diff --git a/CONTRIBUTORS b/CONTRIBUTORS --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1,3 +1,4 @@ +Antoine Cezar Daniele Serafini Ishan Bhanuka -Antoine Cezar +Kumar Shivendu diff --git a/swh/model/cli.py b/swh/model/cli.py --- a/swh/model/cli.py +++ b/swh/model/cli.py @@ -3,7 +3,10 @@ # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information +from enum import Enum import os +from pathlib import Path +from stat import S_ISFIFO import sys from typing import Dict, List, Optional @@ -26,6 +29,14 @@ } +class TerminalColor(Enum): + BLUE = "\033[94m" + GREEN = "\033[92m" + + def colorize(self, text): + return self.value + text + "\033[0m" + + class CoreSWHIDParamType(click.ParamType): """Click argument that accepts a core SWHID and returns them as :class:`swh.model.identifiers.CoreSWHID` instances """ @@ -184,6 +195,12 @@ default=True, help="show/hide file name (default: show)", ) +@click.option( + "--recursive", "-r", is_flag=True, help="Show computed SWHIDs recursively", +) +@click.option( + "--color/--no-color", "color", default=None, help="Colorize the output", +) @click.option( "--type", "-t", @@ -210,7 +227,14 @@ ) @click.argument("objects", nargs=-1, required=True) def identify( - obj_type, verify, show_filename, follow_symlinks, objects, exclude_patterns, + obj_type, + verify, + show_filename, + recursive, + color, + follow_symlinks, + objects, + exclude_patterns, ): """Compute the Software Heritage persistent identifier (SWHID) for the given source code object(s). @@ -246,14 +270,50 @@ if verify and len(objects) != 1: raise click.BadParameter("verification requires a single object") - results = zip( - objects, - map( - partial(identify_object, obj_type, follow_symlinks, exclude_patterns), - objects, - ), + partial_identify_obj = partial( + identify_object, obj_type, follow_symlinks, exclude_patterns ) + is_piped = S_ISFIFO(os.fstat(0).st_mode) + + if recursive: + + def out(path: Path): + is_dir = path.is_dir() + swhid = partial_identify_obj(str(path)) + path_out = path.name + if is_piped: + if color is True: + path_out = ( + TerminalColor.BLUE.colorize(path_out) + if is_dir + else TerminalColor.GREEN.colorize(path_out) + ) + else: + if color is None or color is True: + path_out = ( + TerminalColor.BLUE.colorize(path_out) + if is_dir + else TerminalColor.GREEN.colorize(path_out) + ) + return f"{path_out} {swhid}" + + for obj in list(objects): + obj = Path(obj) + for root, _, files in os.walk(str(obj)): + root = Path(root) + rel_depth = str(root.relative_to(obj)).count(os.sep) + 1 + if root == obj: + rel_depth = 0 + click.echo(f"{(rel_depth) * ' │ '} {out(root)}") + for filename in files: + filepath = Path(os.path.join(root, filename)) + click.echo(f"{(rel_depth + 1) * ' │ '} {out(filepath)}") + click.echo("") + sys.exit(0) + + results = zip(objects, map(partial_identify_obj, objects)) + if verify: swhid = next(results)[1] if str(verify) == swhid: