1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: Apache-2.0
12 import arvados.commands._util as arv_cmd
14 from arvados._version import __version__
16 FileInfo = collections.namedtuple('FileInfo', ['stream_name', 'name', 'size'])
19 parser = argparse.ArgumentParser(
20 description='List contents of a manifest',
21 parents=[arv_cmd.retry_opt])
23 parser.add_argument('locator', type=str,
24 help="""Collection UUID or locator, optionally with a subdir path.""")
25 parser.add_argument('-s', action='store_true',
26 help="""List file sizes, in KiB.""")
27 parser.add_argument('--version', action='version',
28 version="%s %s" % (sys.argv[0], __version__),
29 help='Print version and exit.')
31 return parser.parse_args(args)
33 def size_formatter(coll_file):
34 return "{:>10}".format((coll_file.size + 1023) // 1024)
36 def name_formatter(coll_file):
37 return "{}/{}".format(coll_file.stream_name, coll_file.name)
39 def main(args, stdout, stderr, api_client=None, logger=None):
40 args = parse_args(args)
42 if api_client is None:
43 api_client = arvados.api('v1', num_retries=args.retries)
46 logger = logging.getLogger('arvados.arv-ls')
49 r = re.search(r'^(.*?)(/.*)?$', args.locator)
50 collection = r.group(1)
51 get_prefix = r.group(2)
53 cr = arvados.CollectionReader(collection, api_client=api_client,
54 num_retries=args.retries)
56 if get_prefix[-1] == '/':
57 get_prefix = get_prefix[:-1]
58 stream_name = '.' + get_prefix
59 reader = cr.find(stream_name)
60 if not (isinstance(reader, arvados.CollectionReader) or
61 isinstance(reader, arvados.collection.Subcollection)):
62 logger.error("'{}' is not a subdirectory".format(get_prefix))
67 except (arvados.errors.ApiError,
68 arvados.errors.ArgumentError,
69 arvados.errors.NotFoundError) as error:
70 logger.error("error fetching collection: {}".format(error))
75 formatters.append(size_formatter)
76 formatters.append(name_formatter)
78 for f in files_in_collection(reader, stream_name):
79 print(*(info_func(f) for info_func in formatters), file=stdout)
83 def files_in_collection(c, stream_name='.'):
84 # Sort first by file type, then alphabetically by file path.
85 for i in sorted(c.keys(),
87 isinstance(c[k], arvados.collection.Subcollection),
89 if isinstance(c[i], arvados.arvfile.ArvadosFile):
90 yield FileInfo(stream_name=stream_name,
93 elif isinstance(c[i], arvados.collection.Subcollection):
94 for f in files_in_collection(c[i], "{}/{}".format(stream_name, i)):