From aa144498576624ad2d4bb966e7284f540e5cb52f Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Sat, 6 Jun 2020 14:57:14 -0700 Subject: [PATCH] Add "borgmatic extract --strip-components" flag to remove leading path components when extracting an archive (#324). --- NEWS | 2 ++ borgmatic/borg/extract.py | 2 ++ borgmatic/commands/arguments.py | 7 +++++++ borgmatic/commands/borgmatic.py | 1 + tests/unit/borg/test_environment.py | 2 +- tests/unit/borg/test_extract.py | 15 +++++++++++++++ 6 files changed, 28 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 129c978..ff2863b 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ disk. * #323: Fix for certain configuration options like ssh_command impacting Borg invocations for separate configuration files. + * #324: Add "borgmatic extract --strip-components" flag to remove leading path components when + extracting an archive. * Tweak comment indentation in generated configuration file for clarity. * Link to Borgmacator GNOME AppIndicator from monitoring documentation. diff --git a/borgmatic/borg/extract.py b/borgmatic/borg/extract.py index b43652c..d558715 100644 --- a/borgmatic/borg/extract.py +++ b/borgmatic/borg/extract.py @@ -64,6 +64,7 @@ def extract_archive( local_path='borg', remote_path=None, destination_path=None, + strip_components=None, progress=False, extract_to_stdout=False, ): @@ -91,6 +92,7 @@ def extract_archive( + (('--info',) if logger.getEffectiveLevel() == logging.INFO else ()) + (('--debug', '--list', '--show-rc') if logger.isEnabledFor(logging.DEBUG) else ()) + (('--dry-run',) if dry_run else ()) + + (('--strip-components', str(strip_components)) if strip_components else ()) + (('--progress',) if progress else ()) + (('--stdout',) if extract_to_stdout else ()) + ('::'.join((repository if ':' in repository else os.path.abspath(repository), archive)),) diff --git a/borgmatic/commands/arguments.py b/borgmatic/commands/arguments.py index 2bf6e8e..31a5ba6 100644 --- a/borgmatic/commands/arguments.py +++ b/borgmatic/commands/arguments.py @@ -340,6 +340,13 @@ def parse_arguments(*unparsed_arguments): dest='destination', help='Directory to extract files into, defaults to the current directory', ) + extract_group.add_argument( + '--strip-components', + type=int, + metavar='NUMBER', + dest='strip_components', + help='Number of leading path components to remove from each extracted path. Skip paths with fewer elements', + ) extract_group.add_argument( '--progress', dest='progress', diff --git a/borgmatic/commands/borgmatic.py b/borgmatic/commands/borgmatic.py index 6d21d4d..dc52cbe 100644 --- a/borgmatic/commands/borgmatic.py +++ b/borgmatic/commands/borgmatic.py @@ -328,6 +328,7 @@ def run_actions( local_path=local_path, remote_path=remote_path, destination_path=arguments['extract'].destination, + strip_components=arguments['extract'].strip_components, progress=arguments['extract'].progress, ) if 'mount' in arguments: diff --git a/tests/unit/borg/test_environment.py b/tests/unit/borg/test_environment.py index 9c49e4a..c70d061 100644 --- a/tests/unit/borg/test_environment.py +++ b/tests/unit/borg/test_environment.py @@ -62,7 +62,7 @@ def test_initialize_with_relocated_repo_access_should_override_default(): os.environ = orig_environ -def test_initialize_is_not_effected_by_existing_environment(): +def test_initialize_is_not_affected_by_existing_environment(): orig_environ = os.environ try: diff --git a/tests/unit/borg/test_extract.py b/tests/unit/borg/test_extract.py index 5a95fc3..6ebd458 100644 --- a/tests/unit/borg/test_extract.py +++ b/tests/unit/borg/test_extract.py @@ -220,6 +220,21 @@ def test_extract_archive_calls_borg_with_destination_path(): ) +def test_extract_archive_calls_borg_with_strip_components(): + flexmock(module.os.path).should_receive('abspath').and_return('repo') + insert_execute_command_mock(('borg', 'extract', '--strip-components', '5', 'repo::archive')) + + module.extract_archive( + dry_run=False, + repository='repo', + archive='archive', + paths=None, + location_config={}, + storage_config={}, + strip_components=5, + ) + + def test_extract_archive_calls_borg_with_progress_parameter(): flexmock(module.os.path).should_receive('abspath').and_return('repo') flexmock(module).should_receive('execute_command').with_args(