Просмотр исходного кода

Add rinfo action for Borg 2 support (#557).

Dan Helfman 2 лет назад
Родитель
Сommit
c7176bd00a

+ 25 - 8
borgmatic/commands/arguments.py

@@ -15,6 +15,7 @@ SUBPARSER_ALIASES = {
     'umount': ['--umount', '-u'],
     'restore': ['--restore', '-r'],
     'list': ['--list', '-l'],
+    'rinfo': [],
     'info': ['--info', '-i'],
     'borg': [],
 }
@@ -613,17 +614,34 @@ def make_parsers():
     )
     list_group.add_argument('-h', '--help', action='help', help='Show this help message and exit')
 
+    rinfo_parser = subparsers.add_parser(
+        'rinfo',
+        aliases=SUBPARSER_ALIASES['rinfo'],
+        help='Show repository summary information such as disk space used',
+        description='Show repository summary information such as disk space used',
+        add_help=False,
+    )
+    rinfo_group = rinfo_parser.add_argument_group('rinfo arguments')
+    rinfo_group.add_argument(
+        '--repository',
+        help='Path of repository to show info for, defaults to the configured repository if there is only one',
+    )
+    rinfo_group.add_argument(
+        '--json', dest='json', default=False, action='store_true', help='Output results as JSON'
+    )
+    rinfo_group.add_argument('-h', '--help', action='help', help='Show this help message and exit')
+
     info_parser = subparsers.add_parser(
         'info',
         aliases=SUBPARSER_ALIASES['info'],
-        help='Display summary information on archives',
-        description='Display summary information on archives',
+        help='Show archive summary information such as disk space used',
+        description='Show archive summary information such as disk space used',
         add_help=False,
     )
     info_group = info_parser.add_argument_group('info arguments')
     info_group.add_argument(
         '--repository',
-        help='Path of repository to show info for, defaults to the configured repository if there is only one',
+        help='Path of repository containing archive to show info for, defaults to the configured repository if there is only one',
     )
     info_group.add_argument('--archive', help='Name of archive to show info for (or "latest")')
     info_group.add_argument(
@@ -697,12 +715,11 @@ def parse_arguments(*unparsed_arguments):
         raise ValueError('The rcreate/init action cannot be used with the --dry-run flag')
 
     if (
-        'list' in arguments
-        and 'info' in arguments
-        and arguments['list'].json
-        and arguments['info'].json
+        ('list' in arguments and 'rinfo' in arguments and arguments['list'].json)
+        or ('list' in arguments and 'info' in arguments and arguments['list'].json)
+        or ('rinfo' in arguments and 'info' in arguments and arguments['rinfo'].json)
     ):
-        raise ValueError('With the --json flag, list and info actions cannot be used together')
+        raise ValueError('With the --json flag, multiple actions cannot be used together')
 
     if 'info' in arguments and arguments['info'].archive and arguments['info'].glob_archives:
         raise ValueError(

+ 19 - 1
borgmatic/commands/borgmatic.py

@@ -24,6 +24,7 @@ from borgmatic.borg import list as borg_list
 from borgmatic.borg import mount as borg_mount
 from borgmatic.borg import prune as borg_prune
 from borgmatic.borg import rcreate as borg_rcreate
+from borgmatic.borg import rinfo as borg_rinfo
 from borgmatic.borg import umount as borg_umount
 from borgmatic.borg import version as borg_version
 from borgmatic.commands.arguments import parse_arguments
@@ -613,13 +614,30 @@ def run_actions(
             )
             if json_output:  # pragma: nocover
                 yield json.loads(json_output)
+    if 'rinfo' in arguments:
+        if arguments['rinfo'].repository is None or validate.repositories_match(
+            repository, arguments['rinfo'].repository
+        ):
+            rinfo_arguments = copy.copy(arguments['rinfo'])
+            if not rinfo_arguments.json:  # pragma: nocover
+                logger.warning('{}: Displaying repository summary information'.format(repository))
+            json_output = borg_rinfo.display_repository_info(
+                repository,
+                storage,
+                local_borg_version,
+                rinfo_arguments=rinfo_arguments,
+                local_path=local_path,
+                remote_path=remote_path,
+            )
+            if json_output:  # pragma: nocover
+                yield json.loads(json_output)
     if 'info' in arguments:
         if arguments['info'].repository is None or validate.repositories_match(
             repository, arguments['info'].repository
         ):
             info_arguments = copy.copy(arguments['info'])
             if not info_arguments.json:  # pragma: nocover
-                logger.warning('{}: Displaying summary info for archives'.format(repository))
+                logger.warning('{}: Displaying archive summary information'.format(repository))
             info_arguments.archive = borg_list.resolve_archive_name(
                 repository, info_arguments.archive, storage, local_path, remote_path
             )

+ 14 - 0
tests/integration/commands/test_arguments.py

@@ -496,6 +496,20 @@ def test_parse_arguments_disallows_json_with_both_list_and_info():
         module.parse_arguments('list', 'info', '--json')
 
 
+def test_parse_arguments_disallows_json_with_both_list_and_rinfo():
+    flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default'])
+
+    with pytest.raises(ValueError):
+        module.parse_arguments('list', 'rinfo', '--json')
+
+
+def test_parse_arguments_disallows_json_with_both_rinfo_and_info():
+    flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default'])
+
+    with pytest.raises(ValueError):
+        module.parse_arguments('rinfo', 'info', '--json')
+
+
 def test_parse_arguments_disallows_info_with_both_archive_and_glob_archives():
     flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default'])
 

+ 25 - 0
tests/unit/commands/test_borgmatic.py

@@ -597,6 +597,31 @@ def test_run_actions_does_not_raise_for_list_action():
     )
 
 
+def test_run_actions_does_not_raise_for_rinfo_action():
+    flexmock(module.validate).should_receive('repositories_match').and_return(True)
+    flexmock(module.borg_rinfo).should_receive('display_repository_info')
+    arguments = {
+        'global': flexmock(monitoring_verbosity=1, dry_run=False),
+        'rinfo': flexmock(repository=flexmock(), json=flexmock()),
+    }
+
+    list(
+        module.run_actions(
+            arguments=arguments,
+            config_filename='test.yaml',
+            location={'repositories': ['repo']},
+            storage={},
+            retention={},
+            consistency={},
+            hooks={},
+            local_path=None,
+            remote_path=None,
+            local_borg_version=None,
+            repository_path='repo',
+        )
+    )
+
+
 def test_run_actions_does_not_raise_for_info_action():
     flexmock(module.validate).should_receive('repositories_match').and_return(True)
     flexmock(module.borg_list).should_receive('resolve_archive_name').and_return(flexmock())