# HG changeset patch # User Franz Glasner # Date 1736501572 -3600 # Node ID 8945be6b404eb59344737fdb4f5eaea02ebe33b2 # Parent 91b8b2a8aebc0b6e8b4ef96c8c95f90fa72db322 Mode for treesum.py to print only the size of files and the accumulated size of a directory: --size-only. Digests are not computed. diff -r 91b8b2a8aebc -r 8945be6b404e cutils/treesum.py --- a/cutils/treesum.py Thu Jan 09 18:11:38 2025 +0100 +++ b/cutils/treesum.py Fri Jan 10 10:32:52 2025 +0100 @@ -114,6 +114,10 @@ The size is not considered when computing digests. For symbolic links the size is not printed also.""") gp.add_argument( + "--size-only", action="store_true", + help="""Print only the size of files and for each directory its +accumulated directory size. Digests are not computed.""") + gp.add_argument( "directories", nargs="*", metavar="DIRECTORY") parser = argparse.ArgumentParser( @@ -213,7 +217,8 @@ mmap=None, mtime=False, output=None, - print_size=False): + print_size=False, + size_only=False): opts = argparse.Namespace( directories=directories, algorithm=(util.algotag2algotype(algorithm), @@ -229,7 +234,8 @@ metadata_mode=mode, metadata_mtime=mtime, output=output, - print_size=print_size) + print_size=print_size, + size_only=size_only) return opts @@ -268,6 +274,7 @@ opts.metadata_mode, opts.metadata_full_mode, opts.metadata_mtime, + opts.size_only, opts.print_size, minimal=opts.minimal, comment=opts.comment) @@ -276,7 +283,7 @@ def generate_treesum_for_directory( outfp, root, algorithm, use_mmap, use_base64, handle_root_logical, follow_directory_symlinks, with_metadata_mode, with_metadata_full_mode, - with_metadata_mtime, print_size, + with_metadata_mtime, size_only, print_size, minimal=None, comment=None): """ @@ -298,8 +305,11 @@ flags.append("logical") if follow_directory_symlinks: flags.append("follow-directory-symlinks") - if print_size: - flags.append("print-size") + if size_only: + flags.append("size-only") + else: + if print_size: + flags.append("print-size") if flags: flags.sort() outfp.write(format_bsd_line("FLAGS", ",".join(flags), None, False)) @@ -335,12 +345,21 @@ dir_dgst.update(b"1:L,") dir_dgst.update( b"%d:%s," % (len(linkdgst.digest()), linkdgst.digest())) - outfp.write( - format_bsd_line( - algorithm[1], - dir_dgst.digest(), - "./@", - use_base64)) + if size_only: + outfp.write( + format_bsd_line( + "SIZE", + None, + "./@", + False, + 0)) + else: + outfp.write( + format_bsd_line( + algorithm[1], + dir_dgst.digest(), + "./@", + use_base64)) outfp.flush() return @@ -363,20 +382,28 @@ b"%d:%s," % (len(linkdgst.digest()), linkdgst.digest())) opath = "/".join(top) + "/" + fso.name if top else fso.name - outfp.write( - format_bsd_line( - algorithm[1], - linkdgst.digest(), - "%s/./@" % (opath,), - use_base64)) + if size_only: + outfp.write( + format_bsd_line( + "SIZE", + None, + "%s/./@" % (opath,), + False, + 0)) + else: + outfp.write( + format_bsd_line( + algorithm[1], + linkdgst.digest(), + "%s/./@" % (opath,), + use_base64)) outfp.flush() continue # fetch from dir_digests dgst, dsz = dir_digests[top + (fso.name,)] dir_size += dsz dir_dgst.update(b"1:d,%d:%s," % (len(fso.fsname), fso.fsname)) - dir_dgst.update( - b"%d:%s," % (len(dgst), dgst)) + dir_dgst.update(b"%d:%s," % (len(dgst), dgst)) if with_metadata_full_mode: modestr = normalized_mode_str(fso.stat.st_mode) if not isinstance(modestr, bytes): @@ -409,27 +436,38 @@ if not isinstance(modestr, bytes): modestr = modestr.encode("ascii") dir_dgst.update(b"4:mode,%d:%s," % (len(modestr), modestr)) - dgst = digest.compute_digest_file( - algorithm[0], fso.path, use_mmap=use_mmap) - dir_dgst.update(b"%d:%s," % (len(dgst), dgst)) + if not size_only: + dgst = digest.compute_digest_file( + algorithm[0], fso.path, use_mmap=use_mmap) + dir_dgst.update(b"%d:%s," % (len(dgst), dgst)) opath = "/".join(top) + "/" + fso.name if top else fso.name - if print_size: + if size_only: outfp.write( format_bsd_line( - algorithm[1], dgst, opath, use_base64, - fso.stat.st_size)) + "SIZE", None, opath, False, fso.stat.st_size)) else: - outfp.write( - format_bsd_line( - algorithm[1], dgst, opath, use_base64)) + if print_size: + outfp.write( + format_bsd_line( + algorithm[1], dgst, opath, use_base64, + fso.stat.st_size)) + else: + outfp.write( + format_bsd_line( + algorithm[1], dgst, opath, use_base64)) outfp.flush() opath = "/".join(top) + "/" if top else "" - if print_size: + if size_only: outfp.write(format_bsd_line( - algorithm[1], dir_dgst.digest(), opath, use_base64, dir_size)) + "SIZE", None, opath, False, dir_size)) else: - outfp.write(format_bsd_line( - algorithm[1], dir_dgst.digest(), opath, use_base64)) + if print_size: + outfp.write(format_bsd_line( + algorithm[1], dir_dgst.digest(), opath, + use_base64, dir_size)) + else: + outfp.write(format_bsd_line( + algorithm[1], dir_dgst.digest(), opath, use_base64)) outfp.flush() dir_digests[top] = (dir_dgst.digest(), dir_size) @@ -450,28 +488,30 @@ return modestr -def format_bsd_line(digestname, value, filename, use_base64, size=None): +def format_bsd_line(what, value, filename, use_base64, size=None): ls = os.linesep if isinstance(os.linesep, bytes) \ else os.linesep.encode("utf-8") - if not isinstance(digestname, bytes): - digestname = digestname.encode("ascii") - if digestname == b"TIMESTAMP": + if not isinstance(what, bytes): + what = what.encode("ascii") + if what == b"TIMESTAMP": assert filename is None return b"TIMESTAMP = %d%s" % (value, ls) - if digestname in (b"ISOTIMESTAMP", b"FLAGS", b"VERSION"): + if what in (b"ISOTIMESTAMP", b"FLAGS", b"VERSION"): assert filename is None if not isinstance(value, bytes): value = value.encode("ascii") - return b"%s = %s%s" % (digestname, value, ls) + return b"%s = %s%s" % (what, value, ls) assert filename is not None - if digestname == b"COMMENT": + if what == b"COMMENT": if not isinstance(filename, bytes): filename = filename.encode("utf-8") return b"COMMENT (%s)%s" % (filename, ls) if not isinstance(filename, bytes): filename = util.fsencode(filename) + if what == b"SIZE": + return b"SIZE (%s) = %d%s" % (filename, size, ls) if value is None: - return b"%s (%s)%s" % (digestname, filename, ls) + return b"%s (%s)%s" % (what, filename, ls) if use_base64: value = base64.b64encode(value) else: @@ -479,9 +519,9 @@ if filename != b"./@": filename = util.normalize_filename(filename, True) if size is None: - return b"%s (%s) = %s%s" % (digestname, filename, value, ls) + return b"%s (%s) = %s%s" % (what, filename, value, ls) else: - return b"%s (%s) = %s,%d%s" % (digestname, filename, value, size, ls) + return b"%s (%s) = %s,%d%s" % (what, filename, value, size, ls) if __name__ == "__main__":