]> arthur.barton.de Git - bup.git/blob - lib/cmd/drecurse-cmd.py
tests: partially convert to pytest
[bup.git] / lib / cmd / drecurse-cmd.py
1 #!/bin/sh
2 """": # -*-python-*-
3 # https://sourceware.org/bugzilla/show_bug.cgi?id=26034
4 export "BUP_ARGV_0"="$0"
5 arg_i=1
6 for arg in "$@"; do
7     export "BUP_ARGV_${arg_i}"="$arg"
8     shift
9     arg_i=$((arg_i + 1))
10 done
11 # Here to end of preamble replaced during install
12 bup_python="$(dirname "$0")/../../config/bin/python" || exit $?
13 exec "$bup_python" "$0"
14 """
15 # end of bup preamble
16
17 from __future__ import absolute_import, print_function
18 from os.path import relpath
19 import os.path, sys
20
21 sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
22
23 from bup import compat, options, drecurse
24 from bup.compat import argv_bytes
25 from bup.helpers import log, parse_excludes, parse_rx_excludes, saved_errors
26 from bup.io import byte_stream
27
28
29 optspec = """
30 bup drecurse <path>
31 --
32 x,xdev,one-file-system   don't cross filesystem boundaries
33 exclude= a path to exclude from the backup (can be used more than once)
34 exclude-from= a file that contains exclude paths (can be used more than once)
35 exclude-rx= skip paths matching the unanchored regex (may be repeated)
36 exclude-rx-from= skip --exclude-rx patterns in file (may be repeated)
37 q,quiet  don't actually print filenames
38 profile  run under the python profiler
39 """
40 o = options.Options(optspec)
41 opt, flags, extra = o.parse(compat.argv[1:])
42
43 if len(extra) != 1:
44     o.fatal("exactly one filename expected")
45
46 drecurse_top = argv_bytes(extra[0])
47 excluded_paths = parse_excludes(flags, o.fatal)
48 if not drecurse_top.startswith(b'/'):
49     excluded_paths = [relpath(x) for x in excluded_paths]
50 exclude_rxs = parse_rx_excludes(flags, o.fatal)
51 it = drecurse.recursive_dirlist([drecurse_top], opt.xdev,
52                                 excluded_paths=excluded_paths,
53                                 exclude_rxs=exclude_rxs)
54 if opt.profile:
55     import cProfile
56     def do_it():
57         for i in it:
58             pass
59     cProfile.run('do_it()')
60 else:
61     if opt.quiet:
62         for i in it:
63             pass
64     else:
65         sys.stdout.flush()
66         out = byte_stream(sys.stdout)
67         for (name,st) in it:
68             out.write(name + b'\n')
69
70 if saved_errors:
71     log('WARNING: %d errors encountered.\n' % len(saved_errors))
72     sys.exit(1)