# HG changeset patch # User Franz Glasner # Date 1735915797 -3600 # Node ID 71747e45b52c71e5dcf180e79f15d268f8ea7cec # Parent fdc456832ba654ce4a040ba4f8331772ae2ac500 Prepare for using subcommands in "treesum.py". This is to prepare for verification and filtering/parsing digest files. diff -r fdc456832ba6 -r 71747e45b52c cutils/treesum.py --- a/cutils/treesum.py Fri Jan 03 01:33:01 2025 +0100 +++ b/cutils/treesum.py Fri Jan 03 15:49:57 2025 +0100 @@ -29,60 +29,95 @@ def main(argv=None): - aparser = argparse.ArgumentParser( - description="Generate checksums for directory trees", + + def _populate_generate_arguments(gp): + """Use to populate command aliases. + + This is because :class:`argparse.ArgumentParser` does not + support them for all supported Python versions. + + """ + gp.add_argument( + "--algorithm", "-a", action="store", type=util.argv2algo, + help="1 (aka sha1), 224, 256, 384, 512, " + "3 (alias for sha3-512), 3-224, 3-256, 3-384, 3-512, " + "blake2b, blake2b-256 (default), blake2s, " + "blake2 (alias for blake2b), " + "blake2-256 (alias for blake2b-256), " + "md5") + gp.add_argument( + "--append-output", action="store_true", dest="append_output", + help="Append to the output file instead of overwriting it.") + gp.add_argument( + "--base64", action="store_true", + help="Output checksums in base64 notation, not hexadecimal " + "(OpenBSD).") + gp.add_argument( + "--comment", action="append", default=[], + help="Put given comment COMMENT into the output as \"COMMENT\". " + "Can be given more than once.") + gp.add_argument( + "--follow-directory-symlinks", "-l", action="store_true", + dest="follow_directory_symlinks", + help="Follow symbolic links to directories when walking a " + "directory tree. Note that this is different from using " + "\"--logical\" or \"--physical\" for arguments given " + "directly on the command line") + gp.add_argument( + "--logical", "-L", dest="logical", action="store_true", + default=None, + help="Follow symbolic links given on command line arguments." + " Note that this is a different setting as to follow symbolic" + " links to directories when traversing a directory tree.") + gp.add_argument( + "--mmap", action="store_true", dest="mmap", default=None, + help="Use mmap if available. Default is to determine " + "automatically from the filesize.") + gp.add_argument( + "--no-mmap", action="store_false", dest="mmap", default=None, + help="Dont use mmap.") + gp.add_argument( + "--output", "-o", action="store", metavar="OUTPUT", + help="Put the checksum into given file. " + "If not given or if it is given as `-' then stdout is used.") + gp.add_argument( + "--physical", "-P", dest="logical", action="store_false", + default=None, + help="Do not follow symbolic links given on comment line " + "arguments. This is the default.") + gp.add_argument( + "directories", nargs="*", metavar="DIRECTORY") + + parser = argparse.ArgumentParser( + description="Generate and verify checksums for directory trees.", fromfile_prefix_chars='@') - aparser.add_argument( - "--algorithm", "-a", action="store", type=util.argv2algo, - help="1 (aka sha1), 224, 256, 384, 512, " - "3 (alias for sha3-512), 3-224, 3-256, 3-384, 3-512, " - "blake2b, blake2b-256 (default), blake2s, " - "blake2 (alias for blake2b), blake2-256 (alias for blake2b-256), " - "md5") - aparser.add_argument( - "--append-output", action="store_true", dest="append_output", - help="Append to the output file instead of overwriting it.") - aparser.add_argument( - "--base64", action="store_true", - help="Output checksums in base64 notation, not hexadecimal (OpenBSD).") - aparser.add_argument( - "--comment", action="append", default=[], - help="Put given comment COMMENT into the output as \"COMMENT\"." - " Can be given more than once.") - aparser.add_argument( - "--follow-directory-symlinks", "-l", action="store_true", - dest="follow_directory_symlinks", - help="Follow symbolic links to directories when walking a directory" - " tree. Note that this is different from using \"--logical\" or" - " \"--physical\" for arguments given directly on the command" - " line") - aparser.add_argument( - "--logical", "-L", dest="logical", action="store_true", default=None, - help="Follow symbolic links given on command line arguments." - " Note that this is a different setting as to follow symbolic" - " links to directories when traversing a directory tree.") - aparser.add_argument( - "--mmap", action="store_true", dest="mmap", default=None, - help="Use mmap if available. Default is to determine automatically " - "from the filesize.") - aparser.add_argument( - "--no-mmap", action="store_false", dest="mmap", default=None, - help="Dont use mmap.") - aparser.add_argument( - "--output", "-o", action="store", metavar="OUTPUT", - help="Put the checksum into given file. If not given of if it is given" - " as `-' then stdout is used.") - aparser.add_argument( - "--physical", "-P", dest="logical", action="store_false", default=None, - help="Do not follow symbolic links given on comment line arguments." - " This is the default.") - aparser.add_argument( - "--version", "-v", action="version", + + # Global options for all sub-commands + parser.add_argument( + "-v", "--version", action="version", version="%s (rv:%s)" % (__version__, __revision__)) - aparser.add_argument( - "directories", nargs="*", metavar="DIRECTORY") + + subparsers = parser.add_subparsers( + dest="subcommand", + description="This tool uses subcommands. " + "To see detailed help for a specific subcommand use " + "the -h/--help option after the subcommand name. " + "A short list of valid commands are listed below:") - opts = aparser.parse_args(args=argv) + genparser = subparsers.add_parser( + "generate", + help="Generate checksums for directory trees", + description="Generate checksums for directory trees") + _populate_generate_arguments(genparser) + # And an alias for "generate" + genparser2 = subparsers.add_parser( + "gen", + help="Alias for \"generate\"", + description="Generate checksums for directory trees. " + "This is an alias to \"generate\".") + _populate_generate_arguments(genparser2) + + opts = parser.parse_args(args=argv) if not opts.algorithm: opts.algorithm = util.argv2algo("blake2b-256") @@ -90,15 +125,15 @@ return treesum(opts) -def gen_opts(directories=[], - algorithm="BLAKE2b-256", - append_output=False, - base64=False, - comment=[], - follow_directory_symlinks=False, - logical=None, - mmap=None, - output=None): +def gen_generate_opts(directories=[], + algorithm="BLAKE2b-256", + append_output=False, + base64=False, + comment=[], + follow_directory_symlinks=False, + logical=None, + mmap=None, + output=None): opts = argparse.Namespace( directories=directories, algorithm=(util.algotag2algotype(algorithm), @@ -115,7 +150,11 @@ def treesum(opts): # XXX TBD: opts.check and opts.checklist (as in shasum.py) - return generate_treesum(opts) + if opts.subcommand in ("generate", "gen"): + return generate_treesum(opts) + else: + raise RuntimeError( + "command `{}' not yet handled".format(opts.subcommand)) def generate_treesum(opts):