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 <rlb@defaultvalue.org>
Tested-by: Rob Browning <rlb@defaultvalue.org>
$(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)
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
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
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]
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():
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:
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
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
-_version.py.pre export-subst
+_release.py export-subst
--- /dev/null
+
+# This will be automatically populated by git via export-subst.
+# cf. ./.gitattributes
+
+COMMIT='$Format:%H$'
+NAMES='$Format:%d$'
+DATE='$Format:%ci$'
--- /dev/null
+
+from bup import _release
+
+if _release.COMMIT != '$Format:%H$':
+ from bup._release import COMMIT, DATE, NAMES
+else:
+ from bup._checkout import COMMIT, DATE, NAMES
--- /dev/null
+#!/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"
if (/^\s*Testing "(.*)" in (.*):\s*$/)
{
- alarm(120);
+ alarm(300);
my ($sect, $file) = ($1, $2);
endsect();
}
elsif (/^!\s*(.*?)\s+(\S+)\s*$/)
{
- alarm(120);
+ alarm(300);
my ($name, $result) = ($1, $2);
my $pass = ($result eq "ok");