X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=bup.git;a=blobdiff_plain;f=lib%2Fbup%2Fls.py;h=bff04010f40382402c0b6cbbba1723e968f34a3f;hp=78717ac1dc2d4072f6f830537350b12e1f004ddf;hb=bf67f94dd4f4096de4eee07a7dc377d6c889a016;hpb=f76c37383ddb82343e85632e9154547412e7b1ad diff --git a/lib/bup/ls.py b/lib/bup/ls.py index 78717ac..bff0401 100644 --- a/lib/bup/ls.py +++ b/lib/bup/ls.py @@ -1,14 +1,17 @@ """Common code for listing files from a bup repository.""" -from __future__ import print_function +from __future__ import absolute_import +from binascii import hexlify from itertools import chain from stat import S_ISDIR, S_ISLNK -import copy, locale, os.path, stat, sys, xstat +import copy, locale, os.path, stat, sys -from bup import metadata, options, vfs +from bup import metadata, options, vfs, xstat +from bup.compat import argv_bytes +from bup.io import path_msg from bup.options import Options from bup.repo import LocalRepo, RemoteRepo -from helpers import columnate, istty1, last, log +from bup.helpers import columnate, istty1, last, log def item_hash(item, tree_for_commit): """If the item is a Commit, return its commit oid, otherwise return @@ -26,28 +29,29 @@ def item_info(item, name, classification = None, numeric_ids = False, human_readable = False): - """Return a string containing the information to display for the VFS + """Return bytes containing the information to display for the VFS item. Classification may be "all", "type", or None. """ - result = '' + result = b'' if show_hash: oid = item_hash(item, commit_hash) - result += '%s ' % (oid.encode('hex') if oid - else '0000000000000000000000000000000000000000') + result += b'%s ' % (hexlify(oid) if oid + else b'0000000000000000000000000000000000000000') if long_fmt: meta = item.meta.copy() meta.path = name # FIXME: need some way to track fake vs real meta items? - result += metadata.summary_str(meta, - numeric_ids=numeric_ids, - classification=classification, - human_readable=human_readable) + result += metadata.summary_bytes(meta, + numeric_ids=numeric_ids, + classification=classification, + human_readable=human_readable) else: result += name if classification: - result += xstat.classification_str(vfs.item_mode(item), - classification == 'all') + cls = xstat.classification_str(vfs.item_mode(item), + classification == 'all') + result += cls.encode('iso-8859-1') return result @@ -78,7 +82,7 @@ def opts_from_cmdline(args, onabort=None): else: opt, flags, extra = Options(optspec).parse(args) - opt.paths = extra or ('/',) + opt.paths = [argv_bytes(x) for x in extra] or (b'/',) opt.long_listing = opt.l opt.classification = None opt.show_hidden = None @@ -94,7 +98,7 @@ def opts_from_cmdline(args, onabort=None): opt.show_hidden = 'almost' return opt -def within_repo(repo, opt): +def within_repo(repo, opt, out): if opt.commit_hash: opt.hash = True @@ -113,15 +117,15 @@ def within_repo(repo, opt): for path in opt.paths: try: if opt.directory: - resolved = vfs.lresolve(repo, path) + resolved = vfs.resolve(repo, path, follow=False) else: resolved = vfs.try_resolve(repo, path) leaf_name, leaf_item = resolved[-1] if not leaf_item: log('error: cannot access %r in %r\n' - % ('/'.join(name for name, item in resolved), - path)) + % ('/'.join(path_msg(name) for name, item in resolved), + path_msg(path))) ret = 1 continue if not opt.directory and S_ISDIR(vfs.item_mode(leaf_item)): @@ -129,11 +133,11 @@ def within_repo(repo, opt): if opt.show_hidden == 'all': # Match non-bup "ls -a ... /". parent = resolved[-2] if len(resolved) > 1 else resolved[0] - items = chain(items, (('..', parent[1]),)) + items = chain(items, ((b'..', parent[1]),)) for sub_name, sub_item in sorted(items, key=lambda x: x[0]): - if opt.show_hidden != 'all' and sub_name == '.': + if opt.show_hidden != 'all' and sub_name == b'.': continue - if sub_name.startswith('.') and \ + if sub_name.startswith(b'.') and \ opt.show_hidden not in ('almost', 'all'): continue if opt.l: @@ -146,7 +150,8 @@ def within_repo(repo, opt): if not opt.long_listing and istty1: pending.append(line) else: - print(line) + out.write(line) + out.write(b'\n') else: leaf_item = vfs.augment_item_meta(repo, leaf_item, include_size=True) @@ -154,18 +159,19 @@ def within_repo(repo, opt): if not opt.long_listing and istty1: pending.append(line) else: - print(line) + out.write(line) + out.write(b'\n') except vfs.IOError as ex: log('bup: %s\n' % ex) ret = 1 if pending: - sys.stdout.write(columnate(pending, '')) + out.write(columnate(pending, b'')) return ret -def via_cmdline(args, onabort=None): - """Output a listing of a file or directory in the bup repository. +def via_cmdline(args, out=None, onabort=None): + """Write a listing of a file or directory in the bup repository to out. When a long listing is not requested and stdout is attached to a tty, the output is formatted in columns. When not attached to tty @@ -173,6 +179,7 @@ def via_cmdline(args, onabort=None): file is listed per line. """ + assert out opt = opts_from_cmdline(args, onabort=onabort) - return within_repo(RemoteRepo(opt.remote) if opt.remote else LocalRepo(), - opt) + repo = RemoteRepo(argv_bytes(opt.remote)) if opt.remote else LocalRepo() + return within_repo(repo, opt, out)