Repository: borgbackup/borg

Issue:
don't have multiple debug subcommands by default
the "borg help" is cluttered with debug subcommands.  Maybe hide them by default?  Or merge them into a single sub command? 



Discussion:
@hpk42 yes, carefully introducing subcommands is currently being considered.

Mostly fixed in #1636

Todo left: remove debug-XXX from master - maybe just them showing up, but still accept them (for easier from-the-top-off-the-head debugging advice etc - don't have to distinguish versions and so on).

I'ld say either just remove them in 1.1 (they are not automatically used and not even frequently used) or deprecate them for removal in 1.2.

Another point in this direction would be that when debugging on this level you already know the version and it's unlikely to have "commercial off the shelf" instructions involving these anyway.

I'll remove the debug-xxx form. See above + archiver.py is too big anyway.


Resolving patch:
diff --git a/src/borg/archive.py b/src/borg/archive.py
--- a/src/borg/archive.py
+++ b/src/borg/archive.py
@@ -1256,7 +1256,7 @@ def missing_chunk_detector(chunk_id):
 
             def report(msg, chunk_id, chunk_no):
                 cid = bin_to_hex(chunk_id)
-                msg += ' [chunk: %06d_%s]' % (chunk_no, cid)  # see debug-dump-archive-items
+                msg += ' [chunk: %06d_%s]' % (chunk_no, cid)  # see "debug dump-archive-items"
                 self.error_found = True
                 logger.error(msg)
 
diff --git a/src/borg/archiver.py b/src/borg/archiver.py
--- a/src/borg/archiver.py
+++ b/src/borg/archiver.py
@@ -2467,13 +2467,6 @@ def build_parser(self, prog=None):
         reports and debugging problems. If a traceback happens, this information is
         already appended at the end of the traceback.
         """)
-        subparser = subparsers.add_parser('debug-info', parents=[common_parser], add_help=False,
-                                          description=self.do_debug_info.__doc__,
-                                          epilog=debug_info_epilog,
-                                          formatter_class=argparse.RawDescriptionHelpFormatter,
-                                          help='show system infos for debugging / bug reports (debug)')
-        subparser.set_defaults(func=self.do_debug_info)
-
         subparser = debug_parsers.add_parser('info', parents=[common_parser], add_help=False,
                                           description=self.do_debug_info.__doc__,
                                           epilog=debug_info_epilog,
@@ -2484,16 +2477,6 @@ def build_parser(self, prog=None):
         debug_dump_archive_items_epilog = textwrap.dedent("""
         This command dumps raw (but decrypted and decompressed) archive items (only metadata) to files.
         """)
-        subparser = subparsers.add_parser('debug-dump-archive-items', parents=[common_parser], add_help=False,
-                                          description=self.do_debug_dump_archive_items.__doc__,
-                                          epilog=debug_dump_archive_items_epilog,
-                                          formatter_class=argparse.RawDescriptionHelpFormatter,
-                                          help='dump archive items (metadata) (debug)')
-        subparser.set_defaults(func=self.do_debug_dump_archive_items)
-        subparser.add_argument('location', metavar='ARCHIVE',
-                               type=location_validator(archive=True),
-                               help='archive to dump')
-
         subparser = debug_parsers.add_parser('dump-archive-items', parents=[common_parser], add_help=False,
                                           description=self.do_debug_dump_archive_items.__doc__,
                                           epilog=debug_dump_archive_items_epilog,
@@ -2507,16 +2490,6 @@ def build_parser(self, prog=None):
         debug_dump_repo_objs_epilog = textwrap.dedent("""
         This command dumps raw (but decrypted and decompressed) repo objects to files.
         """)
-        subparser = subparsers.add_parser('debug-dump-repo-objs', parents=[common_parser], add_help=False,
-                                          description=self.do_debug_dump_repo_objs.__doc__,
-                                          epilog=debug_dump_repo_objs_epilog,
-                                          formatter_class=argparse.RawDescriptionHelpFormatter,
-                                          help='dump repo objects (debug)')
-        subparser.set_defaults(func=self.do_debug_dump_repo_objs)
-        subparser.add_argument('location', metavar='REPOSITORY',
-                               type=location_validator(archive=False),
-                               help='repo to dump')
-
         subparser = debug_parsers.add_parser('dump-repo-objs', parents=[common_parser], add_help=False,
                                           description=self.do_debug_dump_repo_objs.__doc__,
                                           epilog=debug_dump_repo_objs_epilog,
@@ -2530,20 +2503,6 @@ def build_parser(self, prog=None):
         debug_get_obj_epilog = textwrap.dedent("""
         This command gets an object from the repository.
         """)
-        subparser = subparsers.add_parser('debug-get-obj', parents=[common_parser], add_help=False,
-                                          description=self.do_debug_get_obj.__doc__,
-                                          epilog=debug_get_obj_epilog,
-                                          formatter_class=argparse.RawDescriptionHelpFormatter,
-                                          help='get object from repository (debug)')
-        subparser.set_defaults(func=self.do_debug_get_obj)
-        subparser.add_argument('location', metavar='REPOSITORY', nargs='?', default='',
-                               type=location_validator(archive=False),
-                               help='repository to use')
-        subparser.add_argument('id', metavar='ID', type=str,
-                               help='hex object ID to get from the repo')
-        subparser.add_argument('path', metavar='PATH', type=str,
-                               help='file to write object data into')
-
         subparser = debug_parsers.add_parser('get-obj', parents=[common_parser], add_help=False,
                                           description=self.do_debug_get_obj.__doc__,
                                           epilog=debug_get_obj_epilog,
@@ -2561,18 +2520,6 @@ def build_parser(self, prog=None):
         debug_put_obj_epilog = textwrap.dedent("""
         This command puts objects into the repository.
         """)
-        subparser = subparsers.add_parser('debug-put-obj', parents=[common_parser], add_help=False,
-                                          description=self.do_debug_put_obj.__doc__,
-                                          epilog=debug_put_obj_epilog,
-                                          formatter_class=argparse.RawDescriptionHelpFormatter,
-                                          help='put object to repository (debug)')
-        subparser.set_defaults(func=self.do_debug_put_obj)
-        subparser.add_argument('location', metavar='REPOSITORY', nargs='?', default='',
-                               type=location_validator(archive=False),
-                               help='repository to use')
-        subparser.add_argument('paths', metavar='PATH', nargs='+', type=str,
-                               help='file(s) to read and create object(s) from')
-
         subparser = debug_parsers.add_parser('put-obj', parents=[common_parser], add_help=False,
                                           description=self.do_debug_put_obj.__doc__,
                                           epilog=debug_put_obj_epilog,
@@ -2588,18 +2535,6 @@ def build_parser(self, prog=None):
         debug_delete_obj_epilog = textwrap.dedent("""
         This command deletes objects from the repository.
         """)
-        subparser = subparsers.add_parser('debug-delete-obj', parents=[common_parser], add_help=False,
-                                          description=self.do_debug_delete_obj.__doc__,
-                                          epilog=debug_delete_obj_epilog,
-                                          formatter_class=argparse.RawDescriptionHelpFormatter,
-                                          help='delete object from repository (debug)')
-        subparser.set_defaults(func=self.do_debug_delete_obj)
-        subparser.add_argument('location', metavar='REPOSITORY', nargs='?', default='',
-                               type=location_validator(archive=False),
-                               help='repository to use')
-        subparser.add_argument('ids', metavar='IDs', nargs='+', type=str,
-                               help='hex object ID(s) to delete from the repo')
-
         subparser = debug_parsers.add_parser('delete-obj', parents=[common_parser], add_help=False,
                                           description=self.do_debug_delete_obj.__doc__,
                                           epilog=debug_delete_obj_epilog,
diff --git a/src/borg/testsuite/archiver.py b/src/borg/testsuite/archiver.py
--- a/src/borg/testsuite/archiver.py
+++ b/src/borg/testsuite/archiver.py
@@ -1547,7 +1547,7 @@ def test_debug_dump_archive_items(self):
         self.cmd('init', self.repository_location)
         self.cmd('create', self.repository_location + '::test', 'input')
         with changedir('output'):
-            output = self.cmd('debug-dump-archive-items', self.repository_location + '::test')
+            output = self.cmd('debug', 'dump-archive-items', self.repository_location + '::test')
         output_dir = sorted(os.listdir('output'))
         assert len(output_dir) > 0 and output_dir[0].startswith('000000_')
         assert 'Done.' in output
@@ -1557,7 +1557,7 @@ def test_debug_dump_repo_objs(self):
         self.cmd('init', self.repository_location)
         self.cmd('create', self.repository_location + '::test', 'input')
         with changedir('output'):
-            output = self.cmd('debug-dump-repo-objs', self.repository_location)
+            output = self.cmd('debug', 'dump-repo-objs', self.repository_location)
         output_dir = sorted(os.listdir('output'))
         assert len(output_dir) > 0 and output_dir[0].startswith('000000_')
         assert 'Done.' in output
@@ -1567,18 +1567,18 @@ def test_debug_put_get_delete_obj(self):
         data = b'some data'
         hexkey = sha256(data).hexdigest()
         self.create_regular_file('file', contents=data)
-        output = self.cmd('debug-put-obj', self.repository_location, 'input/file')
+        output = self.cmd('debug', 'put-obj', self.repository_location, 'input/file')
         assert hexkey in output
-        output = self.cmd('debug-get-obj', self.repository_location, hexkey, 'output/file')
+        output = self.cmd('debug', 'get-obj', self.repository_location, hexkey, 'output/file')
         assert hexkey in output
         with open('output/file', 'rb') as f:
             data_read = f.read()
         assert data == data_read
-        output = self.cmd('debug-delete-obj', self.repository_location, hexkey)
+        output = self.cmd('debug', 'delete-obj', self.repository_location, hexkey)
         assert "deleted" in output
-        output = self.cmd('debug-delete-obj', self.repository_location, hexkey)
+        output = self.cmd('debug', 'delete-obj', self.repository_location, hexkey)
         assert "not found" in output
-        output = self.cmd('debug-delete-obj', self.repository_location, 'invalid')
+        output = self.cmd('debug', 'delete-obj', self.repository_location, 'invalid')
         assert "is invalid" in output
 
     def test_init_interrupt(self):


Test patch: