#!/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' ) declare -A tgts=( ["amd64"]='x86_64' ["arm64"]='arm64' ) 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/ go mod tidy go get -u ./... go mod tidy export CGO_ENABLED=0 _origdir="$(pwd)" _pfx='vault_totp_' for cmd_dir in cmd/*; do cmd_dir="${_origdir}/${cmd_dir}" cmd="$(basename "${cmd_dir}")" _bin="${_pfx}${cmd}" #echo "${cmd_dir} => ${_bin}..." echo "${_bin}..." if [ ! -f "${cmd_dir}/main.go" ]; then continue fi cd "${cmd_dir}" for ga in "${!tgts[@]}"; do echo -e "\t${ga}..." for osnm in "${!os_sfx[@]}"; do echo -e "\t\t${osnm}: " _sfx="${os_sfx[$osnm]}" _a="${tgts[$ga]}" bin="${_origdir}/bin/${_bin}-${_a}-${CURRENT_VER:-dev}.${_sfx}" export GOOS="${osnm}" export GOARCH="${ga}" echo -e "\t\t\tBuilding '${bin}'..." go build \ -o "${bin}" \ -ldflags \ "${LDFLAGS_STR}" # "${LDFLAGS_STR}" \ # *.go echo -e "\t\t\tDone." done echo -e "\tDone." done echo "Done." done echo -e "\nBuild complete."