#!/usr/bin/env bash set -e # This is not portable. It has bashisms. # Like this (bash >= 4.x) declare -A os_sfx=( ["linux"]='bin' ["windows"]='exe' ["darwin"]='app' ) BUILD_TIME="$(date '+%s')" BUILD_USER="$(whoami)" BUILD_SUDO_USER="${SUDO_USER}" BUILD_HOST="$(hostname)" # Check to make sure git is available. if ! command -v git &> /dev/null; then echo "Git is not available; automatic version handling unsupported." echo "You must build by calling 'go build' directly in the respective directories." exit 0 fi # Check git directory/repository. if ! git rev-parse --is-inside-work-tree &> /dev/null; then echo "Not running inside a git work tree; automatic version handling unsupported/build script unsupported." echo "You must build by calling 'go build' directly in the respective directories instead." exit 0 fi # If it has a tag in the path of the current HEAD that matches a version string... # I wish git describe supported regex. It does not; only globs. Gross. # If there's a bug anywhere, it's here. if git describe --tags --abbrev=0 --match "v[0-9]*" HEAD &> /dev/null; then # It has a tag we can use. CURRENT_VER="$(git describe --tags --abbrev=0 --match "v[0-9]*" HEAD)" COMMITS_SINCE="$(git rev-list --count ${CURRENT_VER}..HEAD)" else # No tag available. CURRENT_VER="" COMMITS_SINCE="" fi # If it's dirty (staged but not committed or unstaged files)... if ! git diff-index --quiet HEAD; then # It's dirty. IS_DIRTY="1" else # It's clean. IS_DIRTY="0" fi # Get the commit hash of the *most recent* commit in the path of current HEAD... CURRENT_HASH="$(git rev-parse --verify HEAD)" # The same as above, but abbreviated. CURRENT_SHORT="$(git rev-parse --verify --short HEAD)" # Get the module name. MODPATH="$(sed -n -re 's@^\s*module\s+(.*)(//.*)?$@\1@p' go.mod)" # Build the ldflags string. # BEHOLD! BASH WITCHCRAFT. LDFLAGS_STR="\ -X '${MODPATH}/version.version=${CURRENT_VER}' \ -X '${MODPATH}/version.commitHash=${CURRENT_HASH}' \ -X '${MODPATH}/version.commitShort=${CURRENT_SHORT}' \ -X '${MODPATH}/version.numCommitsAfterTag=${COMMITS_SINCE}' \ -X '${MODPATH}/version.isDirty=${IS_DIRTY}' \ -X '${MODPATH}/version.buildTime=${BUILD_TIME}' \ -X '${MODPATH}/version.buildUser=${BUILD_USER}' \ -X '${MODPATH}/version.buildSudoUser=${BUILD_SUDO_USER}' \ -X '${MODPATH}/version.buildHost=${BUILD_HOST}'" set -u # And finally build. mkdir -p ./bin/ export CGO_ENABLED=0 _origdir="$(pwd)" _pfx='' #for cmd in 'discord' 'irc' 'msteams' 'slack' 'xmpp'; do for cmd_dir in cmd/*; do cmd="$(basename "${cmd_dir}")" echo "${cmd}..." if [ ! -f "${cmd_dir}/main.go" ]; then continue fi cd "${cmd_dir}" _bin="${_pfx}${cmd}" for ga in 'amd64' 'arm64'; do as="${ga}" if [[ "${ga}" == 'amd64' ]]; then as='x86_64' fi echo -e "\t${as}..." for osnm in "${!os_sfx[@]}"; do echo -e "\t\t${osnm}: " _sfx="${os_sfx[$osnm]}" bin="${_origdir}/bin/${_bin}-${as}-${CURRENT_VER:-dev}.${_sfx}" export GOOS="${osnm}" export GOARCH="${ga}" echo -e -n "\t\tBuilding '${bin}'..." go build \ -o "${bin}" \ -ldflags \ "${LDFLAGS_STR}" # "${LDFLAGS_STR}" \ # *.go echo " Done." done echo -e "\tDone." done echo "Done." done echo -e "\nBuild complete."