Fix error with "info --match-archives" and fix "--match-archives" overriding logic (#666).

This commit is contained in:
Dan Helfman 2023-04-04 21:25:10 -07:00
parent 00d1dea94e
commit 616eb6b6da
12 changed files with 292 additions and 69 deletions

5
NEWS
View file

@ -1,3 +1,8 @@
1.7.12.dev0
* #666: Fix error when running the "info" action with the "--match-archives" flag. Also fix the
"--match-archives" flag to correctly override the "match_archives" configuration option for
the "transfer", "list", "rlist", and "info" actions.
1.7.11 1.7.11
* #479, #588: BREAKING: Automatically use the "archive_name_format" option to filter which archives * #479, #588: BREAKING: Automatically use the "archive_name_format" option to filter which archives
get used for borgmatic actions that operate on multiple archives. Override this behavior with the get used for borgmatic actions that operate on multiple archives. Override this behavior with the

View file

@ -46,21 +46,18 @@ def display_archives_info(
if info_arguments.prefix if info_arguments.prefix
else ( else (
flags.make_match_archives_flags( flags.make_match_archives_flags(
storage_config.get('match_archives'), info_arguments.match_archives
or info_arguments.archive
or storage_config.get('match_archives'),
storage_config.get('archive_name_format'), storage_config.get('archive_name_format'),
local_borg_version, local_borg_version,
) )
) )
) )
+ flags.make_flags_from_arguments( + flags.make_flags_from_arguments(
info_arguments, excludes=('repository', 'archive', 'prefix') info_arguments, excludes=('repository', 'archive', 'prefix', 'match_archives')
) )
+ flags.make_repository_flags(repository_path, local_borg_version) + flags.make_repository_flags(repository_path, local_borg_version)
+ (
flags.make_flags('match-archives', info_arguments.archive)
if feature.available(feature.Feature.MATCH_ARCHIVES, local_borg_version)
else flags.make_flags('glob-archives', info_arguments.archive)
)
) )
if info_arguments.json: if info_arguments.json:

View file

@ -52,7 +52,7 @@ def resolve_archive_name(
return latest_archive return latest_archive
MAKE_FLAGS_EXCLUDES = ('repository', 'prefix') MAKE_FLAGS_EXCLUDES = ('repository', 'prefix', 'match_archives')
def make_rlist_command( def make_rlist_command(
@ -96,7 +96,7 @@ def make_rlist_command(
if rlist_arguments.prefix if rlist_arguments.prefix
else ( else (
flags.make_match_archives_flags( flags.make_match_archives_flags(
storage_config.get('match_archives'), rlist_arguments.match_archives or storage_config.get('match_archives'),
storage_config.get('archive_name_format'), storage_config.get('archive_name_format'),
local_borg_version, local_borg_version,
) )

View file

@ -28,12 +28,6 @@ def transfer_archives(
+ (('--debug', '--show-rc') if logger.isEnabledFor(logging.DEBUG) else ()) + (('--debug', '--show-rc') if logger.isEnabledFor(logging.DEBUG) else ())
+ flags.make_flags('remote-path', remote_path) + flags.make_flags('remote-path', remote_path)
+ flags.make_flags('lock-wait', storage_config.get('lock_wait', None)) + flags.make_flags('lock-wait', storage_config.get('lock_wait', None))
+ (('--progress',) if transfer_arguments.progress else ())
+ (
flags.make_flags(
'match-archives', transfer_arguments.match_archives or transfer_arguments.archive
)
)
+ ( + (
flags.make_flags_from_arguments( flags.make_flags_from_arguments(
transfer_arguments, transfer_arguments,
@ -41,7 +35,9 @@ def transfer_archives(
) )
or ( or (
flags.make_match_archives_flags( flags.make_match_archives_flags(
storage_config.get('match_archives'), transfer_arguments.match_archives
or transfer_arguments.archive
or storage_config.get('match_archives'),
storage_config.get('archive_name_format'), storage_config.get('archive_name_format'),
local_borg_version, local_borg_version,
) )

View file

@ -652,7 +652,7 @@ def make_parsers():
'--json', default=False, action='store_true', help='Output results as JSON' '--json', default=False, action='store_true', help='Output results as JSON'
) )
rlist_group.add_argument( rlist_group.add_argument(
'-P', '--prefix', help='Only list archive names starting with this prefix' '-P', '--prefix', help='Deprecated. Only list archive names starting with this prefix'
) )
rlist_group.add_argument( rlist_group.add_argument(
'-a', '-a',
@ -707,7 +707,7 @@ def make_parsers():
'--json', default=False, action='store_true', help='Output results as JSON' '--json', default=False, action='store_true', help='Output results as JSON'
) )
list_group.add_argument( list_group.add_argument(
'-P', '--prefix', help='Only list archive names starting with this prefix' '-P', '--prefix', help='Deprecated. Only list archive names starting with this prefix'
) )
list_group.add_argument( list_group.add_argument(
'-a', '-a',
@ -779,7 +779,9 @@ def make_parsers():
'--json', dest='json', default=False, action='store_true', help='Output results as JSON' '--json', dest='json', default=False, action='store_true', help='Output results as JSON'
) )
info_group.add_argument( info_group.add_argument(
'-P', '--prefix', help='Only show info for archive names starting with this prefix' '-P',
'--prefix',
help='Deprecated. Only show info for archive names starting with this prefix',
) )
info_group.add_argument( info_group.add_argument(
'-a', '-a',
@ -877,7 +879,17 @@ def parse_arguments(*unparsed_arguments):
and arguments['transfer'].match_archives and arguments['transfer'].match_archives
): ):
raise ValueError( raise ValueError(
'With the transfer action, only one of --archive and --glob-archives flags can be used.' 'With the transfer action, only one of --archive and --match-archives flags can be used.'
)
if 'list' in arguments and (arguments['list'].prefix and arguments['list'].match_archives):
raise ValueError(
'With the list action, only one of --prefix or --match-archives flags can be used.'
)
if 'rlist' in arguments and (arguments['rlist'].prefix and arguments['rlist'].match_archives):
raise ValueError(
'With the rlist action, only one of --prefix or --match-archives flags can be used.'
) )
if 'info' in arguments and ( if 'info' in arguments and (

View file

@ -128,13 +128,17 @@ documentation](https://borgbackup.readthedocs.io/en/stable/usage/help.html#borg-
for more information. For Borg 2.x, see the [match archives for more information. For Borg 2.x, see the [match archives
documentation](https://borgbackup.readthedocs.io/en/2.0.0b5/usage/help.html#borg-help-match-archives). documentation](https://borgbackup.readthedocs.io/en/2.0.0b5/usage/help.html#borg-help-match-archives).
Some borgmatic command-line actions also have a `--match-archives` flag that
overrides both the auto-matching behavior and the `match_archives`
configuration option.
<span class="minilink minilink-addedin">Prior to 1.7.11</span> The way to <span class="minilink minilink-addedin">Prior to 1.7.11</span> The way to
limit the archives used for the `prune` action was a `prefix` option in the limit the archives used for the `prune` action was a `prefix` option in the
`retention` section for matching against the start of archive names. And the `retention` section for matching against the start of archive names. And the
option for limiting the archives used for the `check` action was a separate option for limiting the archives used for the `check` action was a separate
`prefix` in the `consistency` section. Both of these options are deprecated in `prefix` in the `consistency` section. Both of these options are deprecated in
favor of the auto-matching behavior (or `match_archives`) in newer versions of favor of the auto-matching behavior (or `match_archives`/`--match-archives`)
borgmatic. in newer versions of borgmatic.
## Configuration includes ## Configuration includes

View file

@ -1,6 +1,6 @@
from setuptools import find_packages, setup from setuptools import find_packages, setup
VERSION = '1.7.11' VERSION = '1.7.12.dev0'
setup( setup(

View file

@ -0,0 +1,104 @@
import copy
import flexmock
import borgmatic.borg.info
import borgmatic.borg.list
import borgmatic.borg.rlist
import borgmatic.borg.transfer
import borgmatic.commands.arguments
def assert_command_does_not_duplicate_flags(command, *args, **kwargs):
'''
Assert that the given Borg command sequence does not contain any duplicated flags, e.g.
"--match-archives" twice anywhere in the command.
'''
flag_counts = {}
for flag_name in command:
if not flag_name.startswith('--'):
continue
if flag_name in flag_counts:
flag_counts[flag_name] += 1
else:
flag_counts[flag_name] = 1
assert flag_counts == {
flag_name: 1 for flag_name in flag_counts
}, f"Duplicate flags found in: {' '.join(command)}"
def fuzz_argument(arguments, argument_name):
'''
Given an argparse.Namespace instance of arguments and an argument name in it, copy the arguments
namespace and set the argument name in the copy with a fake value. Return the copied arguments.
This is useful for "fuzzing" a unit under test by passing it each possible argument in turn,
making sure it doesn't blow up or duplicate Borg arguments.
'''
arguments_copy = copy.copy(arguments)
value = getattr(arguments_copy, argument_name)
setattr(arguments_copy, argument_name, not value if isinstance(value, bool) else 'value')
return arguments_copy
def test_transfer_archives_command_does_not_duplicate_flags_or_raise():
arguments = borgmatic.commands.arguments.parse_arguments(
'transfer', '--source-repository', 'foo'
)['transfer']
flexmock(borgmatic.borg.transfer).should_receive('execute_command').replace_with(
assert_command_does_not_duplicate_flags
)
for argument_name in dir(arguments):
if argument_name.startswith('_'):
continue
borgmatic.borg.transfer.transfer_archives(
False, 'repo', {}, '2.3.4', fuzz_argument(arguments, argument_name)
)
def test_make_list_command_does_not_duplicate_flags_or_raise():
arguments = borgmatic.commands.arguments.parse_arguments('list')['list']
for argument_name in dir(arguments):
if argument_name.startswith('_'):
continue
borgmatic.borg.list.make_list_command(
'repo', {}, '2.3.4', fuzz_argument(arguments, argument_name)
)
def test_make_rlist_command_does_not_duplicate_flags_or_raise():
arguments = borgmatic.commands.arguments.parse_arguments('rlist')['rlist']
for argument_name in dir(arguments):
if argument_name.startswith('_'):
continue
borgmatic.borg.rlist.make_rlist_command(
'repo', {}, '2.3.4', fuzz_argument(arguments, argument_name)
)
def test_display_archives_info_command_does_not_duplicate_flags_or_raise():
arguments = borgmatic.commands.arguments.parse_arguments('info')['info']
flexmock(borgmatic.borg.info).should_receive('execute_command_and_capture_output').replace_with(
assert_command_does_not_duplicate_flags
)
flexmock(borgmatic.borg.info).should_receive('execute_command').replace_with(
assert_command_does_not_duplicate_flags
)
for argument_name in dir(arguments):
if argument_name.startswith('_'):
continue
borgmatic.borg.info.display_archives_info(
'repo', {}, '2.3.4', fuzz_argument(arguments, argument_name)
)

View file

@ -465,6 +465,20 @@ def test_parse_arguments_disallows_transfer_with_both_archive_and_match_archives
) )
def test_parse_arguments_disallows_list_with_both_prefix_and_match_archives():
flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default'])
with pytest.raises(ValueError):
module.parse_arguments('list', '--prefix', 'foo', '--match-archives', 'sh:*bar')
def test_parse_arguments_disallows_rlist_with_both_prefix_and_match_archives():
flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default'])
with pytest.raises(ValueError):
module.parse_arguments('rlist', '--prefix', 'foo', '--match-archives', 'sh:*bar')
def test_parse_arguments_disallows_info_with_both_archive_and_match_archives(): def test_parse_arguments_disallows_info_with_both_archive_and_match_archives():
flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default'])

View file

@ -29,7 +29,7 @@ def test_display_archives_info_calls_borg_with_parameters():
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
info_arguments=flexmock(archive=None, json=False, prefix=None), info_arguments=flexmock(archive=None, json=False, prefix=None, match_archives=None),
) )
@ -54,7 +54,7 @@ def test_display_archives_info_with_log_info_calls_borg_with_info_parameter():
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
info_arguments=flexmock(archive=None, json=False, prefix=None), info_arguments=flexmock(archive=None, json=False, prefix=None, match_archives=None),
) )
@ -77,7 +77,7 @@ def test_display_archives_info_with_log_info_and_json_suppresses_most_borg_outpu
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
info_arguments=flexmock(archive=None, json=True, prefix=None), info_arguments=flexmock(archive=None, json=True, prefix=None, match_archives=None),
) )
assert json_output == '[]' assert json_output == '[]'
@ -105,7 +105,7 @@ def test_display_archives_info_with_log_debug_calls_borg_with_debug_parameter():
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
info_arguments=flexmock(archive=None, json=False, prefix=None), info_arguments=flexmock(archive=None, json=False, prefix=None, match_archives=None),
) )
@ -128,7 +128,7 @@ def test_display_archives_info_with_log_debug_and_json_suppresses_most_borg_outp
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
info_arguments=flexmock(archive=None, json=True, prefix=None), info_arguments=flexmock(archive=None, json=True, prefix=None, match_archives=None),
) )
assert json_output == '[]' assert json_output == '[]'
@ -152,7 +152,7 @@ def test_display_archives_info_with_json_calls_borg_with_json_parameter():
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
info_arguments=flexmock(archive=None, json=True, prefix=None), info_arguments=flexmock(archive=None, json=True, prefix=None, match_archives=None),
) )
assert json_output == '[]' assert json_output == '[]'
@ -162,17 +162,14 @@ def test_display_archives_info_with_archive_calls_borg_with_match_archives_param
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').and_return(())
flexmock(module.flags).should_receive('make_flags').with_args(
'match-archives', 'archive'
).and_return(('--match-archives', 'archive'))
flexmock(module.flags).should_receive('make_match_archives_flags').with_args( flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
None, None, '2.3.4' 'archive', None, '2.3.4'
).and_return(()) ).and_return(('--match-archives', 'archive'))
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
flexmock(module.environment).should_receive('make_environment') flexmock(module.environment).should_receive('make_environment')
flexmock(module).should_receive('execute_command').with_args( flexmock(module).should_receive('execute_command').with_args(
('borg', 'info', '--repo', 'repo', '--match-archives', 'archive'), ('borg', 'info', '--match-archives', 'archive', '--repo', 'repo'),
output_log_level=module.borgmatic.logger.ANSWER, output_log_level=module.borgmatic.logger.ANSWER,
borg_local_path='borg', borg_local_path='borg',
extra_environment=None, extra_environment=None,
@ -182,7 +179,7 @@ def test_display_archives_info_with_archive_calls_borg_with_match_archives_param
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
info_arguments=flexmock(archive='archive', json=False, prefix=None), info_arguments=flexmock(archive='archive', json=False, prefix=None, match_archives=None),
) )
@ -207,7 +204,7 @@ def test_display_archives_info_with_local_path_calls_borg_via_local_path():
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
info_arguments=flexmock(archive=None, json=False, prefix=None), info_arguments=flexmock(archive=None, json=False, prefix=None, match_archives=None),
local_path='borg1', local_path='borg1',
) )
@ -236,7 +233,7 @@ def test_display_archives_info_with_remote_path_calls_borg_with_remote_path_para
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
info_arguments=flexmock(archive=None, json=False, prefix=None), info_arguments=flexmock(archive=None, json=False, prefix=None, match_archives=None),
remote_path='borg1', remote_path='borg1',
) )
@ -266,7 +263,7 @@ def test_display_archives_info_with_lock_wait_calls_borg_with_lock_wait_paramete
repository_path='repo', repository_path='repo',
storage_config=storage_config, storage_config=storage_config,
local_borg_version='2.3.4', local_borg_version='2.3.4',
info_arguments=flexmock(archive=None, json=False, prefix=None), info_arguments=flexmock(archive=None, json=False, prefix=None, match_archives=None),
) )
@ -347,11 +344,64 @@ def test_display_archives_info_transforms_archive_name_format_into_match_archive
repository_path='repo', repository_path='repo',
storage_config={'archive_name_format': 'bar-{now}'}, # noqa: FS003 storage_config={'archive_name_format': 'bar-{now}'}, # noqa: FS003
local_borg_version='2.3.4', local_borg_version='2.3.4',
info_arguments=flexmock(archive=None, json=False, prefix=None), info_arguments=flexmock(archive=None, json=False, prefix=None, match_archives=None),
) )
@pytest.mark.parametrize('argument_name', ('match_archives', 'sort_by', 'first', 'last')) def test_display_archives_with_match_archives_option_calls_borg_with_match_archives_parameter():
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
flexmock(module.flags).should_receive('make_flags').and_return(())
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
'sh:foo-*', 'bar-{now}', '2.3.4' # noqa: FS003
).and_return(('--match-archives', 'sh:foo-*'))
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
flexmock(module.environment).should_receive('make_environment')
flexmock(module).should_receive('execute_command').with_args(
('borg', 'info', '--match-archives', 'sh:foo-*', '--repo', 'repo'),
output_log_level=module.borgmatic.logger.ANSWER,
borg_local_path='borg',
extra_environment=None,
)
module.display_archives_info(
repository_path='repo',
storage_config={
'archive_name_format': 'bar-{now}', # noqa: FS003
'match_archives': 'sh:foo-*',
},
local_borg_version='2.3.4',
info_arguments=flexmock(archive=None, json=False, prefix=None, match_archives=None),
)
def test_display_archives_with_match_archives_flag_calls_borg_with_match_archives_parameter():
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
flexmock(module.flags).should_receive('make_flags').and_return(())
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
'sh:foo-*', 'bar-{now}', '2.3.4' # noqa: FS003
).and_return(('--match-archives', 'sh:foo-*'))
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
flexmock(module.environment).should_receive('make_environment')
flexmock(module).should_receive('execute_command').with_args(
('borg', 'info', '--match-archives', 'sh:foo-*', '--repo', 'repo'),
output_log_level=module.borgmatic.logger.ANSWER,
borg_local_path='borg',
extra_environment=None,
)
module.display_archives_info(
repository_path='repo',
storage_config={'archive_name_format': 'bar-{now}'}, # noqa: FS003
local_borg_version='2.3.4',
info_arguments=flexmock(archive=None, json=False, prefix=None, match_archives='sh:foo-*'),
)
@pytest.mark.parametrize('argument_name', ('sort_by', 'first', 'last'))
def test_display_archives_info_passes_through_arguments_to_borg(argument_name): def test_display_archives_info_passes_through_arguments_to_borg(argument_name):
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
@ -376,5 +426,7 @@ def test_display_archives_info_passes_through_arguments_to_borg(argument_name):
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
info_arguments=flexmock(archive=None, json=False, prefix=None, **{argument_name: 'value'}), info_arguments=flexmock(
archive=None, json=False, prefix=None, match_archives=None, **{argument_name: 'value'}
),
) )

View file

@ -137,7 +137,9 @@ def test_make_rlist_command_includes_log_info():
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='1.2.3', local_borg_version='1.2.3',
rlist_arguments=flexmock(archive=None, paths=None, json=False, prefix=None), rlist_arguments=flexmock(
archive=None, paths=None, json=False, prefix=None, match_archives=None
),
) )
assert command == ('borg', 'list', '--info', 'repo') assert command == ('borg', 'list', '--info', 'repo')
@ -156,7 +158,9 @@ def test_make_rlist_command_includes_json_but_not_info():
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='1.2.3', local_borg_version='1.2.3',
rlist_arguments=flexmock(archive=None, paths=None, json=True, prefix=None), rlist_arguments=flexmock(
archive=None, paths=None, json=True, prefix=None, match_archives=None
),
) )
assert command == ('borg', 'list', '--json', 'repo') assert command == ('borg', 'list', '--json', 'repo')
@ -175,7 +179,9 @@ def test_make_rlist_command_includes_log_debug():
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='1.2.3', local_borg_version='1.2.3',
rlist_arguments=flexmock(archive=None, paths=None, json=False, prefix=None), rlist_arguments=flexmock(
archive=None, paths=None, json=False, prefix=None, match_archives=None
),
) )
assert command == ('borg', 'list', '--debug', '--show-rc', 'repo') assert command == ('borg', 'list', '--debug', '--show-rc', 'repo')
@ -194,7 +200,9 @@ def test_make_rlist_command_includes_json_but_not_debug():
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='1.2.3', local_borg_version='1.2.3',
rlist_arguments=flexmock(archive=None, paths=None, json=True, prefix=None), rlist_arguments=flexmock(
archive=None, paths=None, json=True, prefix=None, match_archives=None
),
) )
assert command == ('borg', 'list', '--json', 'repo') assert command == ('borg', 'list', '--json', 'repo')
@ -212,7 +220,9 @@ def test_make_rlist_command_includes_json():
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='1.2.3', local_borg_version='1.2.3',
rlist_arguments=flexmock(archive=None, paths=None, json=True, prefix=None), rlist_arguments=flexmock(
archive=None, paths=None, json=True, prefix=None, match_archives=None
),
) )
assert command == ('borg', 'list', '--json', 'repo') assert command == ('borg', 'list', '--json', 'repo')
@ -232,7 +242,9 @@ def test_make_rlist_command_includes_lock_wait():
repository_path='repo', repository_path='repo',
storage_config={'lock_wait': 5}, storage_config={'lock_wait': 5},
local_borg_version='1.2.3', local_borg_version='1.2.3',
rlist_arguments=flexmock(archive=None, paths=None, json=False, prefix=None), rlist_arguments=flexmock(
archive=None, paths=None, json=False, prefix=None, match_archives=None
),
) )
assert command == ('borg', 'list', '--lock-wait', '5', 'repo') assert command == ('borg', 'list', '--lock-wait', '5', 'repo')
@ -250,7 +262,9 @@ def test_make_rlist_command_includes_local_path():
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='1.2.3', local_borg_version='1.2.3',
rlist_arguments=flexmock(archive=None, paths=None, json=False, prefix=None), rlist_arguments=flexmock(
archive=None, paths=None, json=False, prefix=None, match_archives=None
),
local_path='borg2', local_path='borg2',
) )
@ -271,7 +285,9 @@ def test_make_rlist_command_includes_remote_path():
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='1.2.3', local_borg_version='1.2.3',
rlist_arguments=flexmock(archive=None, paths=None, json=False, prefix=None), rlist_arguments=flexmock(
archive=None, paths=None, json=False, prefix=None, match_archives=None
),
remote_path='borg2', remote_path='borg2',
) )
@ -328,7 +344,9 @@ def test_make_rlist_command_transforms_archive_name_format_into_match_archives()
repository_path='repo', repository_path='repo',
storage_config={'archive_name_format': 'bar-{now}'}, # noqa: FS003 storage_config={'archive_name_format': 'bar-{now}'}, # noqa: FS003
local_borg_version='1.2.3', local_borg_version='1.2.3',
rlist_arguments=flexmock(archive=None, paths=None, json=False, prefix=None), rlist_arguments=flexmock(
archive=None, paths=None, json=False, prefix=None, match_archives=None
),
) )
assert command == ('borg', 'list', '--match-archives', 'sh:bar-*', 'repo') assert command == ('borg', 'list', '--match-archives', 'sh:bar-*', 'repo')
@ -346,7 +364,9 @@ def test_make_rlist_command_includes_short():
repository_path='repo', repository_path='repo',
storage_config={}, storage_config={},
local_borg_version='1.2.3', local_borg_version='1.2.3',
rlist_arguments=flexmock(archive=None, paths=None, json=False, prefix=None, short=True), rlist_arguments=flexmock(
archive=None, paths=None, json=False, prefix=None, match_archives=None, short=True
),
) )
assert command == ('borg', 'list', '--short', 'repo') assert command == ('borg', 'list', '--short', 'repo')
@ -354,16 +374,7 @@ def test_make_rlist_command_includes_short():
@pytest.mark.parametrize( @pytest.mark.parametrize(
'argument_name', 'argument_name',
( ('sort_by', 'first', 'last', 'exclude', 'exclude_from', 'pattern', 'patterns_from',),
'match_archives',
'sort_by',
'first',
'last',
'exclude',
'exclude_from',
'pattern',
'patterns_from',
),
) )
def test_make_rlist_command_includes_additional_flags(argument_name): def test_make_rlist_command_includes_additional_flags(argument_name):
flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').and_return(())
@ -384,6 +395,7 @@ def test_make_rlist_command_includes_additional_flags(argument_name):
paths=None, paths=None,
json=False, json=False,
prefix=None, prefix=None,
match_archives=None,
find_paths=None, find_paths=None,
format=None, format=None,
**{argument_name: 'value'}, **{argument_name: 'value'},
@ -393,6 +405,35 @@ def test_make_rlist_command_includes_additional_flags(argument_name):
assert command == ('borg', 'list', '--' + argument_name.replace('_', '-'), 'value', 'repo') assert command == ('borg', 'list', '--' + argument_name.replace('_', '-'), 'value', 'repo')
def test_make_rlist_command_with_match_archives_calls_borg_with_match_archives_parameters():
flexmock(module.flags).should_receive('make_flags').and_return(())
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
None, None, '1.2.3'
).and_return(())
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
'foo-*', None, '1.2.3',
).and_return(('--match-archives', 'foo-*'))
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
command = module.make_rlist_command(
repository_path='repo',
storage_config={},
local_borg_version='1.2.3',
rlist_arguments=flexmock(
archive=None,
paths=None,
json=False,
prefix=None,
match_archives='foo-*',
find_paths=None,
format=None,
),
)
assert command == ('borg', 'list', '--match-archives', 'foo-*', 'repo')
def test_list_repository_calls_borg_with_parameters(): def test_list_repository_calls_borg_with_parameters():
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER

View file

@ -124,10 +124,9 @@ def test_transfer_archives_with_archive_calls_borg_with_match_archives_flag():
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').and_return(())
flexmock(module.flags).should_receive('make_flags').with_args( flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
'match-archives', 'archive' 'archive', 'bar-{now}', '2.3.4' # noqa: FS003
).and_return(('--match-archives', 'archive')) ).and_return(('--match-archives', 'archive'))
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
flexmock(module.environment).should_receive('make_environment') flexmock(module.environment).should_receive('make_environment')
@ -154,10 +153,9 @@ def test_transfer_archives_with_match_archives_calls_borg_with_match_archives_fl
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').and_return(())
flexmock(module.flags).should_receive('make_flags').with_args( flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
'match-archives', 'sh:foo*' 'sh:foo*', 'bar-{now}', '2.3.4' # noqa: FS003
).and_return(('--match-archives', 'sh:foo*')) ).and_return(('--match-archives', 'sh:foo*'))
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
flexmock(module.environment).should_receive('make_environment') flexmock(module.environment).should_receive('make_environment')
@ -304,7 +302,7 @@ def test_transfer_archives_with_progress_calls_borg_with_progress_flag():
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').and_return(())
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--progress',))
flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
flexmock(module.environment).should_receive('make_environment') flexmock(module.environment).should_receive('make_environment')
flexmock(module).should_receive('execute_command').with_args( flexmock(module).should_receive('execute_command').with_args(