1 """Common code for listing files from a bup repository."""
2 import copy, os.path, stat, xstat
3 from bup import metadata, options, vfs
10 classification = None,
12 human_readable = False):
13 """Return a string containing the information to display for the node
14 n. Classification may be "all", "type", or None."""
17 result += "%s " % n.hash.encode('hex')
19 meta = copy.copy(n.metadata())
24 # Fake it -- summary_str() is designed to handle a fake.
25 meta = metadata.Metadata()
29 meta.atime, meta.mtime, meta.ctime = n.atime, n.mtime, n.ctime
30 if stat.S_ISLNK(meta.mode):
31 meta.symlink_target = n.readlink()
32 result += metadata.summary_str(meta,
33 numeric_ids = numeric_ids,
34 classification = classification,
35 human_readable = human_readable)
39 mode = n.metadata() and n.metadata().mode or n.mode
40 result += xstat.classification_str(mode, classification == 'all')
47 s,hash show hash for each file
48 a,all show hidden files
49 A,almost-all show hidden files except . and ..
50 l use a detailed, long listing format
51 d,directory show directories, not contents; don't follow symlinks
52 F,classify append type indicator: dir/ sym@ fifo| sock= exec*
53 file-type append type indicator: dir/ sym@ fifo| sock=
54 human-readable print human readable file sizes (i.e. 3.9K, 4.7M)
55 n,numeric-ids list numeric IDs (user, group, etc.) rather than names
58 def do_ls(args, pwd, default='.', onabort=None, spec_prefix=''):
59 """Output a listing of a file or directory in the bup repository.
61 When a long listing is not requested and stdout is attached to a
62 tty, the output is formatted in columns. When not attached to tty
63 (for example when the output is piped to another command), one
64 file is listed per line.
68 o = options.Options(optspec % spec_prefix, onabort=onabort)
70 o = options.Options(optspec % spec_prefix)
71 (opt, flags, extra) = o.parse(args)
73 # Handle order-sensitive options.
77 (option, parameter) = flag
78 if option in ('-F', '--classify'):
79 classification = 'all'
80 elif option == '--file-type':
81 classification = 'type'
82 elif option in ('-a', '--all'):
84 elif option in ('-A', '--almost-all'):
85 show_hidden = 'almost'
88 def output_node_info(node, name):
89 info = node_info(node, name,
92 classification = classification,
93 numeric_ids = opt.numeric_ids,
94 human_readable = opt.human_readable)
95 if not opt.l and istty1:
101 for path in (extra or [default]):
104 n = pwd.lresolve(path)
106 n = pwd.try_resolve(path)
108 if not opt.directory and stat.S_ISDIR(n.mode):
109 if show_hidden == 'all':
110 output_node_info(n, '.')
111 # Match non-bup "ls -a ... /".
113 output_node_info(n.parent, '..')
115 output_node_info(n, '..')
118 if show_hidden in ('almost', 'all') \
119 or not len(name)>1 or not name.startswith('.'):
120 output_node_info(sub, name)
122 output_node_info(n, os.path.normpath(path))
123 except vfs.NodeError as e:
124 log('error: %s\n' % e)
128 sys.stdout.write(columnate(L, ''))