Fixup dedup_files and add some help/usage methods to config.
authorScott Gasch <[email protected]>
Fri, 9 Jun 2023 23:57:35 +0000 (16:57 -0700)
committerScott Gasch <[email protected]>
Fri, 9 Jun 2023 23:57:35 +0000 (16:57 -0700)
examples/dedup_files/dedup_files.py
src/pyutils/config.py

index f01ed8adb2199f998bd0284aa5edd3a14b4275c0..1ad328ea3756d4c3ddfb3d60fbf19e8178591c3d 100755 (executable)
@@ -15,13 +15,13 @@ from pyutils.files import file_utils
 logger = logging.getLogger(__name__)
 parser = config.add_commandline_args(
     f'Dedup Files ({__file__})',
-    'Deduplicate files based on content in a directory or recursively',
+    'Deduplicate files based on their contents below (one or more) directory(ies) [and, optionally, recursively]',
 )
 parser.add_argument(
-    'start_dirs',
+    'root_dir',
     type=str,
-    nargs='*',
-    help='Filespec (glob) of starting directory',
+    nargs='+',
+    help='Filespec (glob) of root directory at which to operate, may include several',
 )
 parser.add_argument(
     '-n',
@@ -33,13 +33,13 @@ parser.add_argument(
     '-R',
     '--recursive',
     action='store_true',
-    help='Traverse recursively',
+    help='Traverse recursively below root directory(ies)',
 )
 parser.add_argument(
     '-l',
     '--link',
     action='store_true',
-    help='Instead of deleting duplicates, create symbolic links',
+    help='Instead of deleting identified duplicates, create symbolic link back to first source',
 )
 
 
@@ -50,7 +50,7 @@ def main() -> int:
     sizes = defaultdict(list)
     dry_size = 0
 
-    for spec in config.config['start_dirs']:
+    for spec in config.config['root_dir']:
         if config.config['recursive']:
             filez = file_utils.get_files_recursive(spec)
         else:
@@ -88,16 +88,21 @@ def main() -> int:
 
                     assert not file_utils.is_symlink(dupe)
                     if config.config['dry_run']:
-                        print(f'{filename} == {dupe}.')
+                        print(f'{filename} == {dupe} (WOULD DELETE {dupe})')
+                        if config.config['link']:
+                            print(
+                                f'{filename} <- {dupe} (WOULD SYMLINK {dupe} to {filename})'
+                            )
                         dry_size += file_utils.get_file_size(dupe)
                     else:
                         assert len(filename) >= len(dupe)
                         saved = filename
                         killed = dupe
-                        print(f'{killed} == {saved} -- DELETED')
+                        print(f'{killed} == {saved} (DELETED {killed})')
                         logger.info('Deleting %s', killed)
                         os.remove(killed)
                         if config.config['link']:
+                            print(f'{saved} <- {killed} (SYMLINK)')
                             logger.info('Creating symlink from %s -> %s', saved, killed)
                             os.symlink(saved, killed)
                         filename = saved
index 456be3e96fbc2e1400ce952f18fcdb67f81d479a..04e1498ac112e3b77a744ffdb188bcde239eaa66 100644 (file)
@@ -341,18 +341,31 @@ class Config:
         return False
 
     @staticmethod
-    def print_usage() -> None:
-        """Prints the normal help usage message out."""
-        ARGS.print_help()
+    def usage() -> str:
+        """
+        Returns:
+            full program usage help text as a string.
+        """
+        return ARGS.format_help()
 
     @staticmethod
-    def usage() -> str:
+    def short_usage() -> str:
         """
         Returns:
-            program usage help text as a string.
+            program short usage text as a string.
         """
         return ARGS.format_usage()
 
+    @staticmethod
+    def print_usage() -> None:
+        """Prints the full help usage message out."""
+        print(config.usage())
+
+    @staticmethod
+    def print_short_usage() -> None:
+        """Prints a short usage/help message."""
+        print(config.short_usage())
+
     @staticmethod
     def _reorder_arg_action_groups_before_help(entry_module: Optional[str]):
         """Internal.  Used to reorder the arguments before dumping out a
@@ -763,9 +776,21 @@ def print_usage() -> None:
     Config.print_usage()
 
 
+def print_short_usage() -> None:
+    Config.print_short_usage()
+
+
 def usage() -> str:
     """
     Returns:
         program usage help text as a string.
     """
     return Config.usage()
+
+
+def short_usage() -> str:
+    """
+    Returns:
+        program short usage help text as a string.
+    """
+    return Config.short_usage()