diff --git a/borgmatic/actions/compact.py b/borgmatic/actions/compact.py index 00585b0b..7a25b829 100644 --- a/borgmatic/actions/compact.py +++ b/borgmatic/actions/compact.py @@ -2,6 +2,7 @@ import logging import borgmatic.borg.compact import borgmatic.borg.feature +import borgmatic.config.validate import borgmatic.hooks.command logger = logging.getLogger(__name__) @@ -24,6 +25,11 @@ def run_compact( ''' Run the "compact" action for the given repository. ''' + if compact_arguments.repository and not borgmatic.config.validate.repositories_match( + repository, compact_arguments.repository + ): + return + borgmatic.hooks.command.execute_hook( hooks.get('before_compact'), hooks.get('umask'), diff --git a/borgmatic/commands/arguments.py b/borgmatic/commands/arguments.py index fbf71685..6991db58 100644 --- a/borgmatic/commands/arguments.py +++ b/borgmatic/commands/arguments.py @@ -357,6 +357,10 @@ def make_parsers(): add_help=False, ) compact_group = compact_parser.add_argument_group('compact arguments') + compact_group.add_argument( + '--repository', + help='Path of specific existing repository to compact (must be already specified in a borgmatic configuration file)', + ) compact_group.add_argument( '--progress', dest='progress', diff --git a/tests/unit/actions/test_compact.py b/tests/unit/actions/test_compact.py index bc2b9406..fab21f32 100644 --- a/tests/unit/actions/test_compact.py +++ b/tests/unit/actions/test_compact.py @@ -3,13 +3,67 @@ from flexmock import flexmock from borgmatic.actions import compact as module -def test_compact_actions_calls_hooks(): +def test_compact_actions_calls_hooks_for_configured_repository(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.compact).should_receive('compact_segments') flexmock(module.borgmatic.hooks.command).should_receive('execute_hook').times(2) compact_arguments = flexmock( - progress=flexmock(), cleanup_commits=flexmock(), threshold=flexmock() + repository=None, progress=flexmock(), cleanup_commits=flexmock(), threshold=flexmock() + ) + global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) + + module.run_compact( + config_filename='test.yaml', + repository='repo', + storage={}, + retention={}, + hooks={}, + hook_context={}, + local_borg_version=None, + compact_arguments=compact_arguments, + global_arguments=global_arguments, + dry_run_label='', + local_path=None, + remote_path=None, + ) + + +def test_compact_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.feature).should_receive('available').and_return(True) + flexmock(module.borgmatic.borg.compact).should_receive('compact_segments') + compact_arguments = flexmock( + repository='repo', progress=flexmock(), cleanup_commits=flexmock(), threshold=flexmock() + ) + global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) + + module.run_compact( + config_filename='test.yaml', + repository='repo', + storage={}, + retention={}, + hooks={}, + hook_context={}, + local_borg_version=None, + compact_arguments=compact_arguments, + global_arguments=global_arguments, + dry_run_label='', + local_path=None, + remote_path=None, + ) + + +def test_compact_bails_if_repository_does_not_match(): + flexmock(module.logger).answer = lambda message: None + flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) + flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return( + False + ) + flexmock(module.borgmatic.borg.compact).should_receive('compact_segments').never() + compact_arguments = flexmock( + repository='repo2', progress=flexmock(), cleanup_commits=flexmock(), threshold=flexmock() ) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False)