From cdbe6cdf3ab5d26d0d688ddc9b44bf90a383c3fa Mon Sep 17 00:00:00 2001 From: Nain Date: Wed, 15 Mar 2023 12:39:54 -0400 Subject: [PATCH] Add "--repository" flag to the "prune" action part of ticket #564 --- borgmatic/actions/prune.py | 6 +++ borgmatic/commands/arguments.py | 4 ++ tests/unit/actions/test_prune.py | 72 +++++++++++++++++++++++++++++++- 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/borgmatic/actions/prune.py b/borgmatic/actions/prune.py index 2d214a18..ca098ce4 100644 --- a/borgmatic/actions/prune.py +++ b/borgmatic/actions/prune.py @@ -1,6 +1,7 @@ import logging import borgmatic.borg.prune +import borgmatic.config.validate import borgmatic.hooks.command logger = logging.getLogger(__name__) @@ -23,6 +24,11 @@ def run_prune( ''' Run the "prune" action for the given repository. ''' + if prune_arguments.repository and not borgmatic.config.validate.repositories_match( + repository, prune_arguments.repository + ): + return + borgmatic.hooks.command.execute_hook( hooks.get('before_prune'), hooks.get('umask'), diff --git a/borgmatic/commands/arguments.py b/borgmatic/commands/arguments.py index 3f56b7cd..a8e8aac2 100644 --- a/borgmatic/commands/arguments.py +++ b/borgmatic/commands/arguments.py @@ -333,6 +333,10 @@ def make_parsers(): add_help=False, ) prune_group = prune_parser.add_argument_group('prune arguments') + prune_group.add_argument( + '--repository', + help='Path of specific existing repository to prune (must be already specified in a borgmatic configuration file)', + ) prune_group.add_argument( '--stats', dest='stats', diff --git a/tests/unit/actions/test_prune.py b/tests/unit/actions/test_prune.py index d34a9c84..21e82600 100644 --- a/tests/unit/actions/test_prune.py +++ b/tests/unit/actions/test_prune.py @@ -7,7 +7,77 @@ def test_run_prune_calls_hooks(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.borg.prune).should_receive('prune_archives') flexmock(module.borgmatic.hooks.command).should_receive('execute_hook').times(2) - prune_arguments = flexmock(stats=flexmock(), list_archives=flexmock()) + prune_arguments = flexmock(repository=None, stats=flexmock(), list_archives=flexmock()) + global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) + + module.run_prune( + config_filename='test.yaml', + repository='repo', + storage={}, + retention={}, + hooks={}, + hook_context={}, + local_borg_version=None, + prune_arguments=prune_arguments, + global_arguments=global_arguments, + dry_run_label='', + local_path=None, + remote_path=None, + ) + + +def test_run_prune_runs_with_no_explicit_repository(): + flexmock(module.logger).answer = lambda message: None + flexmock(module.borgmatic.borg.prune).should_receive('prune_archives') + prune_arguments = flexmock(repository=None, stats=flexmock(), list_archives=flexmock()) + global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) + + module.run_prune( + config_filename='test.yaml', + repository='repo', + storage={}, + retention={}, + hooks={}, + hook_context={}, + local_borg_version=None, + prune_arguments=prune_arguments, + global_arguments=global_arguments, + dry_run_label='', + local_path=None, + remote_path=None, + ) + + +def test_run_prune_runs_with_select_repository(): + flexmock(module.logger).answer = lambda message: None + flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) + flexmock(module.borgmatic.borg.prune).should_receive('prune_archives') + prune_arguments = flexmock(repository=flexmock(), stats=flexmock(), list_archives=flexmock()) + global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) + + module.run_prune( + config_filename='test.yaml', + repository='repo', + storage={}, + retention={}, + hooks={}, + hook_context={}, + local_borg_version=None, + prune_arguments=prune_arguments, + global_arguments=global_arguments, + dry_run_label='', + local_path=None, + remote_path=None, + ) + + +def test_run_prune_bails_if_repository_does_not_match(): + flexmock(module.logger).answer = lambda message: None + flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return( + False + ) + flexmock(module.borgmatic.borg.prune).should_receive('prune_archives').never() + prune_arguments = flexmock(repository=flexmock(), stats=flexmock(), list_archives=flexmock()) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) module.run_prune(