From e61643be081b242015dbd315e65fa9c922dde094 Mon Sep 17 00:00:00 2001 From: Rob Browning Date: Thu, 30 Jan 2014 18:49:36 -0600 Subject: [PATCH] Fix drecurse relative --excludes, quash duplicates, and add tests. Previously "bup drecurse --exclude bar foo" wouldn't work because bar would be expanded to an absolute path, but drecurse would traverse (and attempt to match against) relative paths. Have parse_excludes() remove duplicates and sort its result. Add some initial drecurse tests. Signed-off-by: Rob Browning --- Makefile | 1 + cmd/drecurse-cmd.py | 9 +++-- lib/bup/helpers.py | 2 +- t/test-drecurse.sh | 83 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 3 deletions(-) create mode 100755 t/test-drecurse.sh diff --git a/Makefile b/Makefile index 1863e6e..8eaec0b 100644 --- a/Makefile +++ b/Makefile @@ -88,6 +88,7 @@ runtests-python: all runtests-cmdline: all test -e t/tmp || mkdir t/tmp + TMPDIR="$(test_tmp)" t/test-drecurse.sh TMPDIR="$(test_tmp)" t/test-cat-file.sh TMPDIR="$(test_tmp)" t/test-compression.sh TMPDIR="$(test_tmp)" t/test-fsck.sh diff --git a/cmd/drecurse-cmd.py b/cmd/drecurse-cmd.py index 218b2ef..e528055 100755 --- a/cmd/drecurse-cmd.py +++ b/cmd/drecurse-cmd.py @@ -1,4 +1,6 @@ #!/usr/bin/env python + +from os.path import relpath from bup import options, drecurse from bup.helpers import * @@ -17,9 +19,12 @@ o = options.Options(optspec) if len(extra) != 1: o.fatal("exactly one filename expected") +drecurse_top = extra[0] excluded_paths = parse_excludes(flags, o.fatal) - -it = drecurse.recursive_dirlist(extra, opt.xdev, excluded_paths=excluded_paths) +if not drecurse_top.startswith('/'): + excluded_paths = [relpath(x) for x in excluded_paths] +it = drecurse.recursive_dirlist([drecurse_top], opt.xdev, + excluded_paths=excluded_paths) if opt.profile: import cProfile def do_it(): diff --git a/lib/bup/helpers.py b/lib/bup/helpers.py index 45fcbb5..a169196 100644 --- a/lib/bup/helpers.py +++ b/lib/bup/helpers.py @@ -762,7 +762,7 @@ def parse_excludes(options, fatal): raise fatal("couldn't read %s" % parameter) for exclude_path in f.readlines(): excluded_paths.append(realpath(exclude_path.strip())) - return excluded_paths + return sorted(frozenset(excluded_paths)) def parse_rx_excludes(options, fatal): diff --git a/t/test-drecurse.sh b/t/test-drecurse.sh new file mode 100755 index 0000000..5a52f39 --- /dev/null +++ b/t/test-drecurse.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash +. ./wvtest-bup.sh +. t/lib.sh + +set -o pipefail + +top="$(WVPASS pwd)" || exit $? +tmpdir="$(WVPASS wvmktempdir)" || exit $? + +export BUP_DIR="$tmpdir/bup" +export GIT_DIR="$tmpdir/bup" + +bup() { "$top/bup" "$@"; } + +WVPASS cd "$tmpdir" + +# These tests aren't comprehensive, but test-save-restore-excludes.sh +# exercises some of the same code more thoroughly via index, and +# --xdev is handled in test-xdev.sh. + +WVSTART "drecurse" +WVPASS bup init +WVPASS mkdir src src/a src/b +WVPASS touch src/a/1 src/a/2 src/b/1 src/b/2 src/c +(cd src && WVPASS ln -s a a-link) +WVPASSEQ "$(bup drecurse src)" "src/c +src/b/2 +src/b/1 +src/b/ +src/a/2 +src/a/1 +src/a/ +src/a-link +src/" + +WVSTART "drecurse --exclude (file)" +WVPASSEQ "$(bup drecurse --exclude src/b/2 src)" "src/c +src/b/1 +src/b/ +src/a/2 +src/a/1 +src/a/ +src/a-link +src/" + +WVSTART "drecurse --exclude (dir)" +WVPASSEQ "$(bup drecurse --exclude src/b/ src)" "src/c +src/a/2 +src/a/1 +src/a/ +src/a-link +src/" + +WVSTART "drecurse --exclude (symlink)" +WVPASSEQ "$(bup drecurse --exclude src/a-link src)" "src/c +src/b/2 +src/b/1 +src/b/ +src/a/2 +src/a/1 +src/a/ +src/" + +WVSTART "drecurse --exclude (absolute path)" +WVPASSEQ "$(bup drecurse --exclude src/b/2 "$(pwd)/src")" "$(pwd)/src/c +$(pwd)/src/b/1 +$(pwd)/src/b/ +$(pwd)/src/a/2 +$(pwd)/src/a/1 +$(pwd)/src/a/ +$(pwd)/src/a-link +$(pwd)/src/" + +WVSTART "drecurse --exclude-from" +WVPASS echo "src/b" > exclude-list +WVPASSEQ "$(bup drecurse --exclude-from exclude-list src)" "src/c +src/a/2 +src/a/1 +src/a/ +src/a-link +src/" + +WVPASS rm -rf "$tmpdir" -- 2.39.2