From 861984616a20aed9d232a40a6b8055b105c48171 Mon Sep 17 00:00:00 2001 From: Rob Browning Date: Thu, 26 May 2016 19:30:40 -0500 Subject: [PATCH] Fix release archives and add tests Previously, an archive created by "git archive" would fail to build, because the versioning code was broken (in part by 03d35993b87f49753542e705e37949a46964be17) for any build outside a git clone. Although "bup version" may not really have been quite right since the switch from "bup-VERSION" to "VERSION release tags. Fix the problem by reintroducing the content of the older _version.py.pre as a permanent _release.py file, which (as with the previous incarnation) is a template that's expanded during "git archive" via export-subst (cf. gitattributes(5)). Add a version module as the public interface to versioning, and have it sort out whether or not the current tree is an official release. Adjust configure-version to manage _checkout.py instead of _version.py (drop _version.py), so that the version module is effectively just disambiguating between _release.py and _checkout.py. Adjust "bup version" to use the new version module and to handle unprefixed VERSION tags. Finally, add test-release-archive.sh, invoked via "make distcheck", so we (hopefully) don't unknowingly break this again. Signed-off-by: Rob Browning Tested-by: Rob Browning --- Makefile | 16 +++++++++----- cmd/version-cmd.py | 18 +++++++++------- configure-version | 35 ++++++++++++++++++++++--------- lib/bup/.gitattributes | 2 +- lib/bup/_release.py | 7 +++++++ lib/bup/version.py | 7 +++++++ t/test-release-archive.sh | 44 +++++++++++++++++++++++++++++++++++++++ wvtest | 4 ++-- 8 files changed, 107 insertions(+), 26 deletions(-) create mode 100644 lib/bup/_release.py create mode 100644 lib/bup/version.py create mode 100755 t/test-release-archive.sh diff --git a/Makefile b/Makefile index 6aaf886..c3c1155 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ bup_cmds := cmd/bup-python\ $(patsubst cmd/%-cmd.py,cmd/bup-%,$(wildcard cmd/*-cmd.py)) \ $(patsubst cmd/%-cmd.sh,cmd/bup-%,$(wildcard cmd/*-cmd.sh)) -bup_deps := bup lib/bup/_version.py lib/bup/_helpers$(SOEXT) $(bup_cmds) +bup_deps := bup lib/bup/_checkout.py lib/bup/_helpers$(SOEXT) $(bup_cmds) all: $(bup_deps) Documentation/all $(current_sampledata) @@ -126,10 +126,13 @@ lib/bup/_helpers$(SOEXT): \ LDFLAGS="$(LDFLAGS)" CFLAGS="$(CFLAGS)" "$(bup_python)" csetup.py build cp lib/bup/build/*/_helpers$(SOEXT) lib/bup/ -lib/bup/_version.py: - @echo "Something has gone wrong; $@ should already exist." - @echo 'Check "./configure-version --update"' - @false +lib/bup/_checkout.py: + @if grep -F '$Format' lib/bup/_release.py \ + && ! test -e lib/bup/_checkout.py; then \ + echo "Something has gone wrong; $@ should already exist."; \ + echo 'Check "./configure-version --update"'; \ + false; \ + fi t/tmp: mkdir t/tmp @@ -200,6 +203,9 @@ test: all check: test +distcheck: all + ./wvtest run t/test-release-archive.sh + cmd/python-cmd.sh: config/config.vars Makefile printf "#!/bin/sh\nexec %q \"\$$@\"" "$(bup_python)" \ >> cmd/python-cmd.sh.$$PPID.tmp diff --git a/cmd/version-cmd.py b/cmd/version-cmd.py index fbbe24f..cfde72c 100755 --- a/cmd/version-cmd.py +++ b/cmd/version-cmd.py @@ -4,9 +4,11 @@ bup_python="$(dirname "$0")/bup-python" || exit $? exec "$bup_python" "$0" ${1+"$@"} """ # end of bup preamble -import sys +import re, sys from bup import options -from bup import _version +from bup import version + +version_rx = re.compile(r'^[0-9]+\.[0-9]+(\.[0-9]+)?(-[0-9]+-g[0-9abcdef]+)?$') optspec = """ bup version [--date|--commit|--tag] @@ -26,12 +28,12 @@ if total > 1: def version_date(): """Format bup's version date string for output.""" - return _version.DATE.split(' ')[0] + return version.DATE.split(' ')[0] def version_commit(): """Get the commit hash of bup's current version.""" - return _version.COMMIT + return version.COMMIT def version_tag(): @@ -41,15 +43,15 @@ def version_tag(): returned string will be "unknown-" followed by the first seven positions of the commit hash. """ - names = _version.NAMES.strip() + names = version.NAMES.strip() assert(names[0] == '(') assert(names[-1] == ')') names = names[1:-1] l = [n.strip() for n in names.split(',')] for n in l: - if n.startswith('tag: bup-'): - return n[9:] - return 'unknown-%s' % _version.COMMIT[:7] + if n.startswith('tag: ') and version_rx.match(n[5:]): + return n[5:] + return 'unknown-%s' % version.COMMIT[:7] if opt.date: diff --git a/configure-version b/configure-version index fdea6b5..0ce6101 100755 --- a/configure-version +++ b/configure-version @@ -10,23 +10,23 @@ usage() echo 'Usage: ./configure-version [--update | --clean]' } -update-vpy() +update-cpy() { - declare -r vpy=lib/bup/_version.py - rm -f $vpy.tmp-$$ + declare -r cpy=lib/bup/_checkout.py + rm -f $cpy.tmp-$$ local hash date desc hash=$(git log -1 --pretty=format:%H) date=$(git log -1 --pretty=format:%ci) desc=$(git describe --always --match="[0-9]*") - cat > $vpy.tmp-$$ <<-EOF + cat > $cpy.tmp-$$ <<-EOF COMMIT='$hash' - NAMES='(tag: bup-$desc)' + NAMES='(tag: $desc)' DATE='$date' EOF - if ! test -e $vpy || ! cmp -s $vpy $vpy.tmp-$$; then - mv $vpy.tmp-$$ $vpy; + if ! test -e $cpy || ! cmp -s $cpy $cpy.tmp-$$; then + mv $cpy.tmp-$$ $cpy; fi - rm -f $vpy.tmp-$$ + rm -f $cpy.tmp-$$ } if test "$#" -ne 1; then @@ -40,10 +40,25 @@ fi case "$1" in --update) - update-vpy + rc=0 + grep -q -F '$Format' lib/bup/_release.py || rc=$? + case $rc in + 0) update-cpy + ;; + 1) if test -d .git; then + echo 'error: detected release, but found ./.git' 1>&2 + exit 1 + fi + echo "Detected release tree; skipping version configuration" 1>&2 + exit 0 + ;; + *) + echo 'error: grep failed' 1>&2 + exit 1 + esac ;; --clean) - rm -f lib/bup/_version.py lib/bup/_version.pyc lib/bup/_version.py.tmp-* + rm -f lib/bup/_checkout.py lib/bup/_checkout.pyc lib/bup/_checkout.py.tmp-* ;; *) usage 1>&2; exit 1 diff --git a/lib/bup/.gitattributes b/lib/bup/.gitattributes index 7410999..25da3ff 100644 --- a/lib/bup/.gitattributes +++ b/lib/bup/.gitattributes @@ -1 +1 @@ -_version.py.pre export-subst +_release.py export-subst diff --git a/lib/bup/_release.py b/lib/bup/_release.py new file mode 100644 index 0000000..0efa54b --- /dev/null +++ b/lib/bup/_release.py @@ -0,0 +1,7 @@ + +# This will be automatically populated by git via export-subst. +# cf. ./.gitattributes + +COMMIT='$Format:%H$' +NAMES='$Format:%d$' +DATE='$Format:%ci$' diff --git a/lib/bup/version.py b/lib/bup/version.py new file mode 100644 index 0000000..23d3921 --- /dev/null +++ b/lib/bup/version.py @@ -0,0 +1,7 @@ + +from bup import _release + +if _release.COMMIT != '$Format:%H$': + from bup._release import COMMIT, DATE, NAMES +else: + from bup._checkout import COMMIT, DATE, NAMES diff --git a/t/test-release-archive.sh b/t/test-release-archive.sh new file mode 100755 index 0000000..4c5487a --- /dev/null +++ b/t/test-release-archive.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +. ./wvtest-bup.sh || exit $? +. t/lib.sh || exit $? +. config/config.vars.sh + +set -o pipefail + +WVPASS git status > /dev/null + +if ! git diff-index --quiet HEAD; then + WVDIE "uncommitted changes; cannot continue" +fi + +top="$(WVPASS pwd)" || exit $? +tmpdir="$(WVPASS wvmktempdir)" || exit $? + +bup() { "$top/bup" "$@"; } + +WVPASS cd "$tmpdir" + +WVPASS git clone "$top" clone + +for ver in 11.11 11.11.11; do + WVSTART "version $ver" + WVPASS cd clone + WVPASS git tag "$ver" + WVPASS git archive --prefix=bup-"$ver"/ -o "$tmpdir"/bup-"$ver".tgz "$ver" + WVPASS cd "$tmpdir" + WVPASS tar xzf bup-"$ver".tgz + WVPASS cd bup-"$ver" + WVPASS "$bup_make" + WVPASSEQ "$ver" "$(./bup version)" + WVPASS cd "$tmpdir" +done + +WVSTART 'make check in unpacked archive' +WVPASS cd bup-11.11.11 +if ! "$bup_make" -j5 check > archive-tests.log 2>&1; then + cat archive-tests.log 1>&2 + WVPASS false +fi + +WVPASS cd "$top" +WVPASS rm -rf "$tmpdir" diff --git a/wvtest b/wvtest index 6d8445a..2b1633b 100755 --- a/wvtest +++ b/wvtest @@ -131,7 +131,7 @@ sub run if (/^\s*Testing "(.*)" in (.*):\s*$/) { - alarm(120); + alarm(300); my ($sect, $file) = ($1, $2); endsect(); @@ -142,7 +142,7 @@ sub run } elsif (/^!\s*(.*?)\s+(\S+)\s*$/) { - alarm(120); + alarm(300); my ($name, $result) = ($1, $2); my $pass = ($result eq "ok"); -- 2.39.2