From ba2e9d80fd96d2874cca7beb26b43bb24e9a8395 Mon Sep 17 00:00:00 2001 From: W-Mark Kubacki Date: Fri, 18 Mar 2016 23:10:24 +0100 Subject: [PATCH 1/2] Use best practices in build.bash Format of main.buildDate has been locale-dependent, and is now ISO-8601 compliant. Caddy displayed with ```-version``` something like (mind the datetime format): Caddy 0.8.2 (+591b209 Fri Mar 18 21:22:55 UTC 2016) 2 files changed, 9 insertions(+), 4 deletions(-) build.bash main.go which is now: Caddy 0.8.2 (+591b209 2016-03-18 21:22:55Z) 2 files changed, 9 insertions(+), 4 deletions(-) build.bash,main.go See also: * http://wiki.bash-hackers.org/scripting/obsolete * https://google.github.io/styleguide/shell.xml * https://xkcd.com/1179/ --- .gitattributes | 2 ++ build.bash | 54 +++++++++++++++++++++++++------------------------- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/.gitattributes b/.gitattributes index b3384bdce..a850e37cb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,5 @@ +*.bash text eol=lf whitespace=blank-at-eol,space-before-tab,tab-in-indent,trailing-space,tabwidth=2 + # files for systemd *.path text eol=lf whitespace=blank-at-eol,space-before-tab,tab-in-indent,trailing-space,tabwidth=2 *.service text eol=lf whitespace=blank-at-eol,space-before-tab,tab-in-indent,trailing-space,tabwidth=2 diff --git a/build.bash b/build.bash index b7c97d1ec..6f5bf06fe 100755 --- a/build.bash +++ b/build.bash @@ -8,48 +8,48 @@ # # Outputs compiled program in current directory. # Default file name is 'ecaddy'. -# + set -e -output="$1" -if [ -z "$output" ]; then - output="ecaddy" -fi +: ${output_filename:="$1"} +: ${output_filename:="ecaddy"} pkg=main +ldflags=() # Timestamp of build -builddate_id=$pkg.buildDate -builddate=`date -u` +name="${pkg}.buildDate" +value=$(date --utc +"%F %H:%M:%SZ") +ldflags+=("-X" "\"${name}=${value}\"") # Current tag, if HEAD is on a tag -tag_id=$pkg.gitTag +name="${pkg}.gitTag" set +e -tag=`git describe --exact-match HEAD 2> /dev/null` +value="$(git describe --exact-match HEAD 2>/dev/null)" set -e +ldflags+=("-X" "\"${name}=${value}\"") # Nearest tag on branch -lasttag_id=$pkg.gitNearestTag -lasttag=`git describe --abbrev=0 --tags HEAD` +name="${pkg}.gitNearestTag" +value="$(git describe --abbrev=0 --tags HEAD)" +ldflags+=("-X" "\"${name}=${value}\"") # Commit SHA -commit_id=$pkg.gitCommit -commit=`git rev-parse --short HEAD` +name="${pkg}.gitCommit" +value="$(git rev-parse --short HEAD)" +ldflags+=("-X" "\"${name}=${value}\"") -# Summary of uncommited changes -shortstat_id=$pkg.gitShortStat -shortstat=`git diff-index --shortstat HEAD` +# Summary of uncommitted changes +name="${pkg}.gitShortStat" +value="$(git diff-index --shortstat HEAD)" +ldflags+=("-X" "\"${name}=${value}\"") # List of modified files -files_id=$pkg.gitFilesModified -files=`git diff-index --name-only HEAD` +name="${pkg}.gitFilesModified" +value="$(git diff-index --name-only HEAD | tr "\n" "," | sed -e 's:,$::')" +ldflags+=("-X" "\"${name}=${value}\"") - -go build -ldflags " - -X \"$builddate_id=$builddate\" - -X \"$tag_id=$tag\" - -X \"$lasttag_id=$lasttag\" - -X \"$commit_id=$commit\" - -X \"$shortstat_id=$shortstat\" - -X \"$files_id=$files\" -" -o "$output" +set -x +go build \ + -ldflags "${ldflags[*]}" \ + -o "${output_filename}" From 74a5cb2fe3878f1a90f476ed0c84a863969e0934 Mon Sep 17 00:00:00 2001 From: W-Mark Kubacki Date: Fri, 18 Mar 2016 23:45:56 +0100 Subject: [PATCH 2/2] Convert the barbarism in dist/automate.sh to proper BASH structure When thy variables henceforth accept blessed white-space, guided will thy scripture be along righteous path(s). -- 4 BASH 3:42 Caddy's dist files sometimes ended up being owned by matt:staff or other quite arcane and/or frightening names. If someone extracting didn't pay attention a regular user who happened to have same uid by accident could later tamper with the files' contents. It's 0:0 from now on. Use all available threads when packaging distributables Caddy binaries will be added to their archives in-place: This change eliminates them being renamed within dist/builds one after another. As does 'gox', dist/automate.sh will spare one available thread if possible. --- .gitattributes | 1 + build.bash | 4 +- dist/automate.sh | 110 ++++++++++++++++++++++++++++------------------- 3 files changed, 69 insertions(+), 46 deletions(-) diff --git a/.gitattributes b/.gitattributes index a850e37cb..b8001b6bc 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,5 @@ *.bash text eol=lf whitespace=blank-at-eol,space-before-tab,tab-in-indent,trailing-space,tabwidth=2 +*.sh text eol=lf whitespace=blank-at-eol,space-before-tab,tab-in-indent,trailing-space,tabwidth=2 # files for systemd *.path text eol=lf whitespace=blank-at-eol,space-before-tab,tab-in-indent,trailing-space,tabwidth=2 diff --git a/build.bash b/build.bash index 6f5bf06fe..0850fcb40 100755 --- a/build.bash +++ b/build.bash @@ -9,9 +9,9 @@ # Outputs compiled program in current directory. # Default file name is 'ecaddy'. -set -e +set -euo pipefail -: ${output_filename:="$1"} +: ${output_filename:="${1:-}"} : ${output_filename:="ecaddy"} pkg=main diff --git a/dist/automate.sh b/dist/automate.sh index 3cc8d41b2..582882b36 100755 --- a/dist/automate.sh +++ b/dist/automate.sh @@ -1,56 +1,78 @@ #!/usr/bin/env bash -set -e -set -o pipefail -shopt -s nullglob # if no files match glob, assume empty list instead of string literal +set -euo pipefail +# if no files match glob, assume empty list instead of string literal +shopt -s nullglob -## PACKAGE TO BUILD -Package=github.com/mholt/caddy +: ${build_package:="github.com/mholt/caddy"} +: ${dist_dir:="${GOPATH}/src/${build_package}/dist"} +: ${build_dir:="${dist_dir}/builds"} +: ${target_dir:="${dist_dir}/release"} -## PATHS TO USE -DistDir=$GOPATH/src/$Package/dist -BuildDir=$DistDir/builds -ReleaseDir=$DistDir/release +# Bundles a single binary, given as first parameter, into an archive. +package() { + # Binary inside the zip file is simply the project name + binbase="$(basename "${build_package}")" + if [[ "${1}" == *.exe ]]; then + binbase+=".exe" + fi + bin="${build_dir}/${binbase}" + # Name .zip file same as binary, but strip .exe from end + zipname="$(basename "${1%.exe}")" + case "$(printf "${zipname}" | cut -d '_' -f 2 | sed -e 's:[a-z]*bsd:bsd:')" in + linux|bsd) zipname+=".tar.gz" ;; + *) zipname+=".zip" ;; + esac -## BEGIN + # Compress distributable depending on extension + case "${zipname##*.}" in + zip) + zip -j "${target_dir}/${zipname}" \ + "${1}" \ + "${dist_dir}"/{CHANGES.txt,LICENSES.txt,README.txt} + printf "@ $(basename "${1}")\n@=${binbase}\n" \ + | zipnote -w "${target_dir}/${zipname}" + ;; + gz) + tar -caf "${target_dir}/${zipname}" \ + --owner=0 --group=0 \ + --transform="s#$(basename "${1}")#${binbase}#" \ + -C "$(dirname "${1}")" "$(basename "${1}")" \ + -C "${dist_dir}" CHANGES.txt LICENSES.txt README.txt + ;; + esac +} -# Compile binaries -mkdir -p $BuildDir -cd $BuildDir -rm -f caddy* -gox $Package +prepare_directories() { + mkdir -p "${build_dir}" + rm -f "${build_dir}"/caddy* -# Zip them up with release notes and stuff -mkdir -p $ReleaseDir -cd $ReleaseDir -rm -f caddy* -for f in $BuildDir/* -do - # Name .zip file same as binary, but strip .exe from end - zipname=$(basename ${f%".exe"}) - if [[ $f == *"linux"* ]] || [[ $f == *"bsd"* ]]; then - zipname=${zipname}.tar.gz - else - zipname=${zipname}.zip - fi + mkdir -p "${target_dir}" + rm -f "${target_dir}"/caddy* +} - # Binary inside the zip file is simply the project name - binbase=$(basename $Package) - if [[ $f == *.exe ]]; then - binbase=$binbase.exe - fi - bin=$BuildDir/$binbase - mv $f $bin +compile_binaries() { + (cd "${build_dir}"; gox "${build_package}") +} - # Compress distributable - if [[ $zipname == *.zip ]]; then - zip -j $zipname $bin $DistDir/CHANGES.txt $DistDir/LICENSES.txt $DistDir/README.txt - else - tar -cvzf $zipname -C $BuildDir $binbase -C $DistDir CHANGES.txt LICENSES.txt README.txt - fi +if [[ "${1:-}" == "" ]]; then + prepare_directories + compile_binaries - # Put binary filename back to original - mv $bin $f -done + case "${OSTYPE}" in + linux*) + find "${build_dir}" -type f -executable -print0 \ + | xargs --null --max-args=1 --max-procs=$(nproc --ignore=1) -I '{}' \ + "${0}" package '{}' + ;; + *) + while read f; do + package "${f}" + done < <(ls -1 "${build_dir}"/caddy*) + ;; + esac +else + ${1} "${2}" +fi