From 826e4352d1ba0d59beb0cb013e149f6d486f8ae9 Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Sun, 8 Dec 2019 14:07:02 -0800 Subject: [PATCH] Filter listed paths via "borgmatic list --path" flag (#269). --- NEWS | 1 + borgmatic/borg/list.py | 3 ++- borgmatic/commands/arguments.py | 7 ++++++ tests/unit/borg/test_list.py | 41 ++++++++++++++++++++++----------- 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/NEWS b/NEWS index 57397842..bd671266 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ * Fix "borgmatic umount" so it only runs Borg once instead of once per repository / configuration file. * #253: Mount whole repositories via "borgmatic mount" without any "--archive" flag. + * #269: Filter listed paths via "borgmatic list --path" flag. 1.4.17 * #235: Pass extra options directly to particular Borg commands, handy for Borg options that diff --git a/borgmatic/borg/list.py b/borgmatic/borg/list.py index bcbe36e2..845f2884 100644 --- a/borgmatic/borg/list.py +++ b/borgmatic/borg/list.py @@ -36,13 +36,14 @@ def list_archives(repository, storage_config, list_arguments, local_path='borg', + make_flags('remote-path', remote_path) + make_flags('lock-wait', lock_wait) + make_flags_from_arguments( - list_arguments, excludes=('repository', 'archive', 'successful') + list_arguments, excludes=('repository', 'archive', 'paths', 'successful') ) + ( '::'.join((repository, list_arguments.archive)) if list_arguments.archive else repository, ) + + (tuple(list_arguments.paths) if list_arguments.paths else ()) ) return execute_command( diff --git a/borgmatic/commands/arguments.py b/borgmatic/commands/arguments.py index b2e9eabf..738981ca 100644 --- a/borgmatic/commands/arguments.py +++ b/borgmatic/commands/arguments.py @@ -419,6 +419,13 @@ def parse_arguments(*unparsed_arguments): help='Path of repository to list, defaults to the configured repository if there is only one', ) list_group.add_argument('--archive', help='Name of archive to list') + list_group.add_argument( + '--path', + metavar='PATH', + nargs='+', + dest='paths', + help='Paths to list from archive, defaults to the entire archive', + ) list_group.add_argument( '--short', default=False, action='store_true', help='Output only archive or path names' ) diff --git a/tests/unit/borg/test_list.py b/tests/unit/borg/test_list.py index 4e3de334..40ad1229 100644 --- a/tests/unit/borg/test_list.py +++ b/tests/unit/borg/test_list.py @@ -16,7 +16,7 @@ def test_list_archives_calls_borg_with_parameters(): module.list_archives( repository='repo', storage_config={}, - list_arguments=flexmock(archive=None, json=False, successful=False), + list_arguments=flexmock(archive=None, paths=None, json=False, successful=False), ) @@ -31,7 +31,7 @@ def test_list_archives_with_log_info_calls_borg_with_info_parameter(): module.list_archives( repository='repo', storage_config={}, - list_arguments=flexmock(archive=None, json=False, successful=False), + list_arguments=flexmock(archive=None, paths=None, json=False, successful=False), ) @@ -44,7 +44,7 @@ def test_list_archives_with_log_info_and_json_suppresses_most_borg_output(): module.list_archives( repository='repo', storage_config={}, - list_arguments=flexmock(archive=None, json=True, successful=False), + list_arguments=flexmock(archive=None, paths=None, json=True, successful=False), ) @@ -59,7 +59,7 @@ def test_list_archives_with_log_debug_calls_borg_with_debug_parameter(): module.list_archives( repository='repo', storage_config={}, - list_arguments=flexmock(archive=None, json=False, successful=False), + list_arguments=flexmock(archive=None, paths=None, json=False, successful=False), ) @@ -72,7 +72,7 @@ def test_list_archives_with_log_debug_and_json_suppresses_most_borg_output(): module.list_archives( repository='repo', storage_config={}, - list_arguments=flexmock(archive=None, json=True, successful=False), + list_arguments=flexmock(archive=None, paths=None, json=True, successful=False), ) @@ -87,7 +87,7 @@ def test_list_archives_with_lock_wait_calls_borg_with_lock_wait_parameters(): module.list_archives( repository='repo', storage_config=storage_config, - list_arguments=flexmock(archive=None, json=False, successful=False), + list_arguments=flexmock(archive=None, paths=None, json=False, successful=False), ) @@ -100,7 +100,22 @@ def test_list_archives_with_archive_calls_borg_with_archive_parameter(): module.list_archives( repository='repo', storage_config=storage_config, - list_arguments=flexmock(archive='archive', json=False, successful=False), + list_arguments=flexmock(archive='archive', paths=None, json=False, successful=False), + ) + + +def test_list_archives_with_path_calls_borg_with_path_parameter(): + storage_config = {} + flexmock(module).should_receive('execute_command').with_args( + ('borg', 'list', 'repo::archive', 'var/lib'), + output_log_level=logging.WARNING, + error_on_warnings=False, + ) + + module.list_archives( + repository='repo', + storage_config=storage_config, + list_arguments=flexmock(archive='archive', paths=['var/lib'], json=False, successful=False), ) @@ -112,7 +127,7 @@ def test_list_archives_with_local_path_calls_borg_via_local_path(): module.list_archives( repository='repo', storage_config={}, - list_arguments=flexmock(archive=None, json=False, successful=False), + list_arguments=flexmock(archive=None, paths=None, json=False, successful=False), local_path='borg1', ) @@ -127,7 +142,7 @@ def test_list_archives_with_remote_path_calls_borg_with_remote_path_parameters() module.list_archives( repository='repo', storage_config={}, - list_arguments=flexmock(archive=None, json=False, successful=False), + list_arguments=flexmock(archive=None, paths=None, json=False, successful=False), remote_path='borg1', ) @@ -142,7 +157,7 @@ def test_list_archives_with_short_calls_borg_with_short_parameter(): module.list_archives( repository='repo', storage_config={}, - list_arguments=flexmock(archive=None, json=False, successful=False, short=True), + list_arguments=flexmock(archive=None, paths=None, json=False, successful=False, short=True), ) @@ -171,7 +186,7 @@ def test_list_archives_passes_through_arguments_to_borg(argument_name): repository='repo', storage_config={}, list_arguments=flexmock( - archive=None, json=False, successful=False, **{argument_name: 'value'} + archive=None, paths=None, json=False, successful=False, **{argument_name: 'value'} ), ) @@ -186,7 +201,7 @@ def test_list_archives_with_successful_calls_borg_to_exclude_checkpoints(): module.list_archives( repository='repo', storage_config={}, - list_arguments=flexmock(archive=None, json=False, successful=True), + list_arguments=flexmock(archive=None, paths=None, json=False, successful=True), ) @@ -198,7 +213,7 @@ def test_list_archives_with_json_calls_borg_with_json_parameter(): json_output = module.list_archives( repository='repo', storage_config={}, - list_arguments=flexmock(archive=None, json=True, successful=False), + list_arguments=flexmock(archive=None, paths=None, json=True, successful=False), ) assert json_output == '[]'