Mercurial > hgrepos > Python > apps > py-cutils
diff cutils/treesum.py @ 131:3a18d71d7c50
Implement --follow-directory-symlinks when walking a directory tree
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Thu, 02 Jan 2025 20:52:49 +0100 |
| parents | d5621028ce39 |
| children | 8b73dca5db97 |
line wrap: on
line diff
--- a/cutils/treesum.py Thu Jan 02 19:50:24 2025 +0100 +++ b/cutils/treesum.py Thu Jan 02 20:52:49 2025 +0100 @@ -46,6 +46,13 @@ "--base64", action="store_true", help="Output checksums in base64 notation, not hexadecimal (OpenBSD).") aparser.add_argument( + "--follow-directory-symlinks", 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" @@ -83,17 +90,20 @@ algorithm="BLAKE2b-256", append_output=False, base64=False, + follow_directory_symlinks=False, logical=None, mmap=None, output=None): - opts = argparse.Namespace(directories=directories, - algorithm=(util.algotag2algotype(algorithm), - algorithm), - append_output=append_output, - base64=base64, - logical=logical, - mmap=mmap, - output=output) + opts = argparse.Namespace( + directories=directories, + algorithm=(util.algotag2algotype(algorithm), + algorithm), + append_output=append_output, + base64=base64, + follow_directory_symlinks=follow_directory_symlinks, + logical=logical, + mmap=mmap, + output=output) return opts @@ -120,11 +130,13 @@ with out_cm as outfp: for d in opts.directories: generate_treesum_for_directory( - outfp, d, opts.algorithm, opts.mmap, opts.base64, opts.logical) + outfp, d, opts.algorithm, opts.mmap, opts.base64, opts.logical, + opts.follow_directory_symlinks) def generate_treesum_for_directory( - outfp, root, algorithm, use_mmap, use_base64, handle_root_logical): + outfp, root, algorithm, use_mmap, use_base64, handle_root_logical, + follow_directory_symlinks): """ :param outfp: a *binary* file with a "write()" and a "flush()" method @@ -137,6 +149,8 @@ flags = [] if handle_root_logical: flags.append("logical") + if follow_directory_symlinks: + flags.append("follow-directory-symlinks") if flags: outfp.write(format_bsd_line("FLAGS", ",".join(flags), None, False)) @@ -163,10 +177,12 @@ outfp.flush() return - for top, dirs, nondirs in walk.walk(root, follow_symlinks=False): + for top, dirs, nondirs in walk.walk( + root, + follow_symlinks=follow_directory_symlinks): dir_dgst = algorithm[0]() for dn in dirs: - if dn.is_symlink: + if dn.is_symlink and not follow_directory_symlinks: linktgt = util.fsencode(os.readlink(dn.path)) linkdgst = algorithm[0]() linkdgst.update(linktgt) @@ -180,11 +196,11 @@ "%s/./@" % (opath,), use_base64)) outfp.flush() - else: - # fetch from dir_digests - dgst = dir_digests[top + (dn.name,)] - dir_dgst.update(b"1:d,%d:%s," % (len(dn.fsname), dn.fsname)) - dir_dgst.update(dgst) + continue + # fetch from dir_digests + dgst = dir_digests[top + (dn.name,)] + dir_dgst.update(b"1:d,%d:%s," % (len(dn.fsname), dn.fsname)) + dir_dgst.update(dgst) for fn in nondirs: dir_dgst.update(b"1:f,%d:%s," % (len(fn.fsname), fn.fsname)) dgst = digest.compute_digest_file(
