comparison cutils/treesum.py @ 135:dbf27681a1f6

Allow to put comments into the output with "--comment"
author Franz Glasner <fzglas.hg@dom66.de>
date Thu, 02 Jan 2025 23:15:10 +0100
parents d2c303695fb8
children db4fd1f64538
comparison
equal deleted inserted replaced
134:d2c303695fb8 135:dbf27681a1f6
44 help="Append to the output file instead of overwriting it.") 44 help="Append to the output file instead of overwriting it.")
45 aparser.add_argument( 45 aparser.add_argument(
46 "--base64", action="store_true", 46 "--base64", action="store_true",
47 help="Output checksums in base64 notation, not hexadecimal (OpenBSD).") 47 help="Output checksums in base64 notation, not hexadecimal (OpenBSD).")
48 aparser.add_argument( 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(
49 "--follow-directory-symlinks", action="store_true", 53 "--follow-directory-symlinks", action="store_true",
50 dest="follow_directory_symlinks", 54 dest="follow_directory_symlinks",
51 help="Follow symbolic links to directories when walking a directory" 55 help="Follow symbolic links to directories when walking a directory"
52 " tree. Note that this is different from using \"--logical\" or" 56 " tree. Note that this is different from using \"--logical\" or"
53 " \"--physical\" for arguments given directly on the command" 57 " \"--physical\" for arguments given directly on the command"
88 92
89 def gen_opts(directories=[], 93 def gen_opts(directories=[],
90 algorithm="BLAKE2b-256", 94 algorithm="BLAKE2b-256",
91 append_output=False, 95 append_output=False,
92 base64=False, 96 base64=False,
97 comment=[],
93 follow_directory_symlinks=False, 98 follow_directory_symlinks=False,
94 logical=None, 99 logical=None,
95 mmap=None, 100 mmap=None,
96 output=None): 101 output=None):
97 opts = argparse.Namespace( 102 opts = argparse.Namespace(
98 directories=directories, 103 directories=directories,
99 algorithm=(util.algotag2algotype(algorithm), 104 algorithm=(util.algotag2algotype(algorithm),
100 algorithm), 105 algorithm),
101 append_output=append_output, 106 append_output=append_output,
102 base64=base64, 107 base64=base64,
108 comment=comment,
103 follow_directory_symlinks=follow_directory_symlinks, 109 follow_directory_symlinks=follow_directory_symlinks,
104 logical=logical, 110 logical=logical,
105 mmap=mmap, 111 mmap=mmap,
106 output=output) 112 output=output)
107 return opts 113 return opts
129 135
130 with out_cm as outfp: 136 with out_cm as outfp:
131 for d in opts.directories: 137 for d in opts.directories:
132 generate_treesum_for_directory( 138 generate_treesum_for_directory(
133 outfp, d, opts.algorithm, opts.mmap, opts.base64, opts.logical, 139 outfp, d, opts.algorithm, opts.mmap, opts.base64, opts.logical,
134 opts.follow_directory_symlinks) 140 opts.follow_directory_symlinks,
141 comment=opts.comment)
135 142
136 143
137 def generate_treesum_for_directory( 144 def generate_treesum_for_directory(
138 outfp, root, algorithm, use_mmap, use_base64, handle_root_logical, 145 outfp, root, algorithm, use_mmap, use_base64, handle_root_logical,
139 follow_directory_symlinks): 146 follow_directory_symlinks, comment=None):
140 """ 147 """
141 148
142 :param outfp: a *binary* file with a "write()" and a "flush()" method 149 :param outfp: a *binary* file with a "write()" and a "flush()" method
143 150
144 """ 151 """
160 outfp.write(format_bsd_line("TIMESTAMP", ts, None, False)) 167 outfp.write(format_bsd_line("TIMESTAMP", ts, None, False))
161 ts = (datetime.datetime.utcfromtimestamp(ts)).isoformat("T") 168 ts = (datetime.datetime.utcfromtimestamp(ts)).isoformat("T")
162 outfp.write(format_bsd_line("ISOTIMESTAMP", ts, None, False)) 169 outfp.write(format_bsd_line("ISOTIMESTAMP", ts, None, False))
163 outfp.flush() 170 outfp.flush()
164 171
172 if comment:
173 for line in comment:
174 outfp.write(format_bsd_line("COMMENT", None, line, False))
165 outfp.write(format_bsd_line("ROOT", None, root, False)) 175 outfp.write(format_bsd_line("ROOT", None, root, False))
166 outfp.flush() 176 outfp.flush()
167 177
168 dir_digests = {} 178 dir_digests = {}
169 179
236 assert filename is None 246 assert filename is None
237 if not isinstance(value, bytes): 247 if not isinstance(value, bytes):
238 value = value.encode("ascii") 248 value = value.encode("ascii")
239 return b"%s = %s%s" % (digestname, value, ls) 249 return b"%s = %s%s" % (digestname, value, ls)
240 assert filename is not None 250 assert filename is not None
251 if digestname == b"COMMENT":
252 if not isinstance(filename, bytes):
253 filename = filename.encode("utf-8")
254 return b"COMMENT (%s)%s" % (filename, ls)
241 if not isinstance(filename, bytes): 255 if not isinstance(filename, bytes):
242 filename = util.fsencode(filename) 256 filename = util.fsencode(filename)
243 if value is None: 257 if value is None:
244 return b"%s (%s)%s" % (digestname, filename, ls) 258 return b"%s (%s)%s" % (digestname, filename, ls)
245 if use_base64: 259 if use_base64: