changeset 104:08fd0609fdd4

Implement "--recurse" for shasum: recurse into directories
author Franz Glasner <fzglas.hg@dom66.de>
date Thu, 26 May 2022 23:14:38 +0200
parents af8318191ed3
children b0631f320efd
files cutils/shasum.py
diffstat 1 files changed, 43 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/cutils/shasum.py	Fri Apr 29 10:31:18 2022 +0200
+++ b/cutils/shasum.py	Thu May 26 23:14:38 2022 +0200
@@ -94,6 +94,10 @@
         help="Dont use mmap.")
 
     aparser.add_argument(
+        "--recurse", action="store_true",
+        help="Recurse into sub-directories while interpreting every FILE as a directory")
+
+    aparser.add_argument(
         "--reverse", "-r", action="store_false", dest="bsd", default=False,
         help="Explicitely select normal coreutils style output (to be option compatible with BSD style commands and :command:`openssl dgst -r`)")
     aparser.add_argument(
@@ -161,29 +165,49 @@
         out = out_bsd
     else:
         out = out_std
-    if not opts.files or (len(opts.files) == 1 and opts.files[0] == '-'):
-        if PY2:
-            if sys.platform == "win32":
-                import os, msvcrt   # noqa: E401
-                msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
-            source = sys.stdin
-        else:
-            source = sys.stdin.buffer
-        out(sys.stdout,
-            compute_digest_stream(opts.algorithm[0], source),
-            None,
-            opts.algorithm[1],
-            True,
-            opts.base64)
+    if opts.recurse:
+        if not opts.files:
+            opts.files.append(".")
+        for dn in opts.files:
+            if not os.path.isdir(dn):
+                if os.path.exists(dn):
+                    raise OSError(errno.ENOTDIR, "not a directory", dn)
+                else:
+                    raise OSError(errno.ENOENT, "directory does not exist", dn)
+            for dirpath, dirnames, dirfiles in os.walk(dn, followlinks=True):
+                for fn in dirfiles:
+                    path = os.path.join(dirpath, fn)
+                    out(opts.dest or sys.stdout,
+                        compute_digest_file(opts.algorithm[0], path,
+                                            use_mmap=opts.mmap),
+                        path,
+                        opts.algorithm[1],
+                        True,
+                        opts.base64)
     else:
-        for fn in opts.files:
-            out(opts.dest or sys.stdout,
-                compute_digest_file(opts.algorithm[0], fn,
-                                    use_mmap=opts.mmap),
-                fn,
+        if not opts.files or (len(opts.files) == 1 and opts.files[0] == '-'):
+            if PY2:
+                if sys.platform == "win32":
+                    import msvcrt   # noqa: E401
+                    msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
+                source = sys.stdin
+            else:
+                source = sys.stdin.buffer
+            out(sys.stdout,
+                compute_digest_stream(opts.algorithm[0], source),
+                None,
                 opts.algorithm[1],
                 True,
                 opts.base64)
+        else:
+            for fn in opts.files:
+                out(opts.dest or sys.stdout,
+                    compute_digest_file(opts.algorithm[0], fn,
+                                        use_mmap=opts.mmap),
+                    fn,
+                    opts.algorithm[1],
+                    True,
+                    opts.base64)
     return 0