diff --git a/swh/model/cli.py b/swh/model/cli.py index 6df219e67a6189d068ebda14f8e496b36e336f98..7b52ce919618ad857714f56f2793a64bfdce8c59 100644 --- a/swh/model/cli.py +++ b/swh/model/cli.py @@ -8,6 +8,8 @@ import locale import os import sys +from functools import partial + from swh.model import identifiers as pids from swh.model.exceptions import ValidationError from swh.model.from_disk import Content, Directory @@ -34,20 +36,40 @@ def pid_of_dir(path): return pids.persistent_identifier(pids.DIRECTORY, object) +def identify_object(obj_type, obj): + if obj_type == 'auto': + if os.path.isfile(obj): + obj_type = 'content' + elif os.path.isdir(obj): + obj_type = 'directory' + else: # shouldn't happen, due to path validation + raise click.BadParameter('%s is neither a file nor a directory' % + obj) + pid = None + if obj_type == 'content': + pid = pid_of_file(obj) + elif obj_type == 'directory': + pid = pid_of_dir(obj) + else: # shouldn't happen, due to option validation + raise click.BadParameter('invalid object type: ' + obj_type) + + return (obj, pid) + + @click.command() -@click.option('--type', '-t', default='auto', +@click.option('--type', '-t', 'obj_type', default='auto', type=click.Choice(['auto', 'content', 'directory']), help='type of object to identify (default: auto)') @click.option('--verify', '-v', metavar='PID', type=PidParamType(), help='reference identifier to be compared with computed one') @click.option('--filename/--no-filename', 'show_filename', default=True, help='show/hide file name (default: show)') -@click.argument('object', +@click.argument('objects', nargs=-1, type=click.Path(exists=True, readable=True, allow_dash=True, path_type=bytes)) -def identify(type, verify, show_filename, object): - """Compute the Software Heritage persistent identifier (PID) for a given - source code object. +def identify(obj_type, verify, show_filename, objects): + """Compute the Software Heritage persistent identifier (PID) for the given + source code object(s). For more details about Software Heritage PIDs see: @@ -58,32 +80,23 @@ def identify(type, verify, show_filename, object): Examples: \b - $ swh-identify /usr/src/linux/kernel/ - swh:1:dir:f9f858a48d663b3809c9e2f336412717496202ab + $ swh-identify fork.c kmod.c sched/deadline.c + swh:1:cnt:2e391c754ae730bd2d8520c2ab497c403220c6e3 fork.c + swh:1:cnt:0277d1216f80ae1adeed84a686ed34c9b2931fc2 kmod.c + swh:1:cnt:57b939c81bce5d06fa587df8915f05affbe22b82 sched/deadline.c \b - $ swh-identify /usr/src/linux/kernel/sched/deadline.c - swh:1:cnt:57b939c81bce5d06fa587df8915f05affbe22b82 + $ swh-identify --no-filename /usr/src/linux/kernel/ + swh:1:dir:f9f858a48d663b3809c9e2f336412717496202ab """ - if type == 'auto': - if os.path.isfile(object): - type = 'content' - elif os.path.isdir(object): - type = 'directory' - else: # shouldn't happen, due to path validation - raise click.BadParameter('%s is neither a file nor a directory' % - object) + if verify and len(objects) != 1: + raise click.BadParameter('verification requires a single object') - pid = None - if type == 'content': - pid = pid_of_file(object) - elif type == 'directory': - pid = pid_of_dir(object) - else: # shouldn't happen, due to option validation - raise click.BadParameter('invalid object type: ' + type) + results = map(partial(identify_object, obj_type), objects) if verify: + pid = next(results)[1] if verify == pid: click.echo('PID match: %s' % pid) sys.exit(0) @@ -91,11 +104,12 @@ def identify(type, verify, show_filename, object): click.echo('PID mismatch: %s != %s' % (verify, pid)) sys.exit(1) else: - msg = pid - if show_filename: - encoding = locale.getpreferredencoding(do_setlocale=False) - msg = '%s\t%s' % (pid, object.decode(encoding)) - click.echo(msg) + for (obj, pid) in results: + msg = pid + if show_filename: + encoding = locale.getpreferredencoding(do_setlocale=False) + msg = '%s\t%s' % (pid, obj.decode(encoding)) + click.echo(msg) if __name__ == '__main__':