comparison cutils/treesum.py @ 142:71747e45b52c

Prepare for using subcommands in "treesum.py". This is to prepare for verification and filtering/parsing digest files.
author Franz Glasner <fzglas.hg@dom66.de>
date Fri, 03 Jan 2025 15:49:57 +0100
parents 69f8a3db8fbd
children 492975912cad
comparison
equal deleted inserted replaced
141:fdc456832ba6 142:71747e45b52c
27 from .util import digest 27 from .util import digest
28 from .util import walk 28 from .util import walk
29 29
30 30
31 def main(argv=None): 31 def main(argv=None):
32 aparser = argparse.ArgumentParser( 32
33 description="Generate checksums for directory trees", 33 def _populate_generate_arguments(gp):
34 """Use to populate command aliases.
35
36 This is because :class:`argparse.ArgumentParser` does not
37 support them for all supported Python versions.
38
39 """
40 gp.add_argument(
41 "--algorithm", "-a", action="store", type=util.argv2algo,
42 help="1 (aka sha1), 224, 256, 384, 512, "
43 "3 (alias for sha3-512), 3-224, 3-256, 3-384, 3-512, "
44 "blake2b, blake2b-256 (default), blake2s, "
45 "blake2 (alias for blake2b), "
46 "blake2-256 (alias for blake2b-256), "
47 "md5")
48 gp.add_argument(
49 "--append-output", action="store_true", dest="append_output",
50 help="Append to the output file instead of overwriting it.")
51 gp.add_argument(
52 "--base64", action="store_true",
53 help="Output checksums in base64 notation, not hexadecimal "
54 "(OpenBSD).")
55 gp.add_argument(
56 "--comment", action="append", default=[],
57 help="Put given comment COMMENT into the output as \"COMMENT\". "
58 "Can be given more than once.")
59 gp.add_argument(
60 "--follow-directory-symlinks", "-l", action="store_true",
61 dest="follow_directory_symlinks",
62 help="Follow symbolic links to directories when walking a "
63 "directory tree. Note that this is different from using "
64 "\"--logical\" or \"--physical\" for arguments given "
65 "directly on the command line")
66 gp.add_argument(
67 "--logical", "-L", dest="logical", action="store_true",
68 default=None,
69 help="Follow symbolic links given on command line arguments."
70 " Note that this is a different setting as to follow symbolic"
71 " links to directories when traversing a directory tree.")
72 gp.add_argument(
73 "--mmap", action="store_true", dest="mmap", default=None,
74 help="Use mmap if available. Default is to determine "
75 "automatically from the filesize.")
76 gp.add_argument(
77 "--no-mmap", action="store_false", dest="mmap", default=None,
78 help="Dont use mmap.")
79 gp.add_argument(
80 "--output", "-o", action="store", metavar="OUTPUT",
81 help="Put the checksum into given file. "
82 "If not given or if it is given as `-' then stdout is used.")
83 gp.add_argument(
84 "--physical", "-P", dest="logical", action="store_false",
85 default=None,
86 help="Do not follow symbolic links given on comment line "
87 "arguments. This is the default.")
88 gp.add_argument(
89 "directories", nargs="*", metavar="DIRECTORY")
90
91 parser = argparse.ArgumentParser(
92 description="Generate and verify checksums for directory trees.",
34 fromfile_prefix_chars='@') 93 fromfile_prefix_chars='@')
35 aparser.add_argument( 94
36 "--algorithm", "-a", action="store", type=util.argv2algo, 95 # Global options for all sub-commands
37 help="1 (aka sha1), 224, 256, 384, 512, " 96 parser.add_argument(
38 "3 (alias for sha3-512), 3-224, 3-256, 3-384, 3-512, " 97 "-v", "--version", action="version",
39 "blake2b, blake2b-256 (default), blake2s, "
40 "blake2 (alias for blake2b), blake2-256 (alias for blake2b-256), "
41 "md5")
42 aparser.add_argument(
43 "--append-output", action="store_true", dest="append_output",
44 help="Append to the output file instead of overwriting it.")
45 aparser.add_argument(
46 "--base64", action="store_true",
47 help="Output checksums in base64 notation, not hexadecimal (OpenBSD).")
48 aparser.add_argument(
49 "--comment", action="append", default=[],
50 help="Put given comment COMMENT into the output as \"COMMENT\"."
51 " Can be given more than once.")
52 aparser.add_argument(
53 "--follow-directory-symlinks", "-l", action="store_true",
54 dest="follow_directory_symlinks",
55 help="Follow symbolic links to directories when walking a directory"
56 " tree. Note that this is different from using \"--logical\" or"
57 " \"--physical\" for arguments given directly on the command"
58 " line")
59 aparser.add_argument(
60 "--logical", "-L", dest="logical", action="store_true", default=None,
61 help="Follow symbolic links given on command line arguments."
62 " Note that this is a different setting as to follow symbolic"
63 " links to directories when traversing a directory tree.")
64 aparser.add_argument(
65 "--mmap", action="store_true", dest="mmap", default=None,
66 help="Use mmap if available. Default is to determine automatically "
67 "from the filesize.")
68 aparser.add_argument(
69 "--no-mmap", action="store_false", dest="mmap", default=None,
70 help="Dont use mmap.")
71 aparser.add_argument(
72 "--output", "-o", action="store", metavar="OUTPUT",
73 help="Put the checksum into given file. If not given of if it is given"
74 " as `-' then stdout is used.")
75 aparser.add_argument(
76 "--physical", "-P", dest="logical", action="store_false", default=None,
77 help="Do not follow symbolic links given on comment line arguments."
78 " This is the default.")
79 aparser.add_argument(
80 "--version", "-v", action="version",
81 version="%s (rv:%s)" % (__version__, __revision__)) 98 version="%s (rv:%s)" % (__version__, __revision__))
82 aparser.add_argument( 99
83 "directories", nargs="*", metavar="DIRECTORY") 100 subparsers = parser.add_subparsers(
84 101 dest="subcommand",
85 opts = aparser.parse_args(args=argv) 102 description="This tool uses subcommands. "
103 "To see detailed help for a specific subcommand use "
104 "the -h/--help option after the subcommand name. "
105 "A short list of valid commands are listed below:")
106
107 genparser = subparsers.add_parser(
108 "generate",
109 help="Generate checksums for directory trees",
110 description="Generate checksums for directory trees")
111 _populate_generate_arguments(genparser)
112 # And an alias for "generate"
113 genparser2 = subparsers.add_parser(
114 "gen",
115 help="Alias for \"generate\"",
116 description="Generate checksums for directory trees. "
117 "This is an alias to \"generate\".")
118 _populate_generate_arguments(genparser2)
119
120 opts = parser.parse_args(args=argv)
86 121
87 if not opts.algorithm: 122 if not opts.algorithm:
88 opts.algorithm = util.argv2algo("blake2b-256") 123 opts.algorithm = util.argv2algo("blake2b-256")
89 124
90 return treesum(opts) 125 return treesum(opts)
91 126
92 127
93 def gen_opts(directories=[], 128 def gen_generate_opts(directories=[],
94 algorithm="BLAKE2b-256", 129 algorithm="BLAKE2b-256",
95 append_output=False, 130 append_output=False,
96 base64=False, 131 base64=False,
97 comment=[], 132 comment=[],
98 follow_directory_symlinks=False, 133 follow_directory_symlinks=False,
99 logical=None, 134 logical=None,
100 mmap=None, 135 mmap=None,
101 output=None): 136 output=None):
102 opts = argparse.Namespace( 137 opts = argparse.Namespace(
103 directories=directories, 138 directories=directories,
104 algorithm=(util.algotag2algotype(algorithm), 139 algorithm=(util.algotag2algotype(algorithm),
105 algorithm), 140 algorithm),
106 append_output=append_output, 141 append_output=append_output,
113 return opts 148 return opts
114 149
115 150
116 def treesum(opts): 151 def treesum(opts):
117 # XXX TBD: opts.check and opts.checklist (as in shasum.py) 152 # XXX TBD: opts.check and opts.checklist (as in shasum.py)
118 return generate_treesum(opts) 153 if opts.subcommand in ("generate", "gen"):
154 return generate_treesum(opts)
155 else:
156 raise RuntimeError(
157 "command `{}' not yet handled".format(opts.subcommand))
119 158
120 159
121 def generate_treesum(opts): 160 def generate_treesum(opts):
122 if not opts.directories: 161 if not opts.directories:
123 opts.directories.append(".") 162 opts.directories.append(".")