From cf477bdc1c65e6e7210a7ee6049b1752f47f6806 Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Mon, 31 Mar 2025 11:33:56 -0700 Subject: [PATCH] Fix broken list_details, progress, and statistics options (#303). --- borgmatic/actions/check.py | 3 +- borgmatic/actions/compact.py | 10 - borgmatic/actions/config/bootstrap.py | 1 - borgmatic/actions/create.py | 25 +-- borgmatic/actions/export_tar.py | 5 - borgmatic/actions/extract.py | 5 - borgmatic/actions/transfer.py | 6 + borgmatic/borg/check.py | 11 +- borgmatic/borg/compact.py | 5 +- borgmatic/borg/create.py | 17 +- borgmatic/borg/delete.py | 21 +- borgmatic/borg/export_tar.py | 5 +- borgmatic/borg/extract.py | 9 +- borgmatic/borg/info.py | 4 +- borgmatic/borg/prune.py | 16 +- borgmatic/borg/recreate.py | 9 +- borgmatic/borg/repo_delete.py | 4 +- borgmatic/borg/repo_list.py | 2 +- borgmatic/borg/transfer.py | 11 +- borgmatic/commands/arguments.py | 79 ++++---- borgmatic/commands/borgmatic.py | 18 +- borgmatic/config/arguments.py | 13 +- borgmatic/config/validate.py | 12 +- tests/integration/commands/test_arguments.py | 38 +--- tests/integration/config/test_validate.py | 24 +-- tests/unit/actions/config/test_bootstrap.py | 3 - tests/unit/actions/test_check.py | 7 +- tests/unit/actions/test_compact.py | 93 ++------- tests/unit/actions/test_create.py | 194 +++++++------------ tests/unit/actions/test_export_tar.py | 8 +- tests/unit/actions/test_extract.py | 2 - tests/unit/actions/test_prune.py | 10 +- tests/unit/actions/test_transfer.py | 21 +- tests/unit/borg/test_check.py | 53 +---- tests/unit/borg/test_compact.py | 26 ++- tests/unit/borg/test_create.py | 28 ++- tests/unit/borg/test_delete.py | 52 ++--- tests/unit/borg/test_export_tar.py | 15 +- tests/unit/borg/test_extract.py | 8 +- tests/unit/borg/test_info.py | 2 +- tests/unit/borg/test_prune.py | 108 ++--------- tests/unit/borg/test_recreate.py | 32 +-- tests/unit/borg/test_repo_delete.py | 26 +-- tests/unit/borg/test_repo_list.py | 2 +- tests/unit/borg/test_transfer.py | 35 +--- tests/unit/commands/test_borgmatic.py | 6 +- tests/unit/config/test_arguments.py | 12 ++ 47 files changed, 357 insertions(+), 739 deletions(-) diff --git a/borgmatic/actions/check.py b/borgmatic/actions/check.py index b562d760..afcc9262 100644 --- a/borgmatic/actions/check.py +++ b/borgmatic/actions/check.py @@ -372,7 +372,7 @@ def collect_spot_check_source_paths( borgmatic.borg.create.make_base_create_command( dry_run=True, repository_path=repository['path'], - config=config, + config=dict(config, list_details=True), patterns=borgmatic.actions.create.process_patterns( borgmatic.actions.create.collect_patterns(config), working_directory, @@ -382,7 +382,6 @@ def collect_spot_check_source_paths( borgmatic_runtime_directory=borgmatic_runtime_directory, local_path=local_path, remote_path=remote_path, - list_files=True, stream_processes=stream_processes, ) ) diff --git a/borgmatic/actions/compact.py b/borgmatic/actions/compact.py index dbc2e573..551c680d 100644 --- a/borgmatic/actions/compact.py +++ b/borgmatic/actions/compact.py @@ -37,17 +37,7 @@ def run_compact( global_arguments, local_path=local_path, remote_path=remote_path, - progress=( - config.get('progress') - if compact_arguments.progress is None - else compact_arguments.progress - ), cleanup_commits=compact_arguments.cleanup_commits, - threshold=( - config.get('compact_threshold') - if compact_arguments.threshold is None - else compact_arguments.threshold - ), ) else: # pragma: nocover logger.info('Skipping compact (only available/needed in Borg 1.2+)') diff --git a/borgmatic/actions/config/bootstrap.py b/borgmatic/actions/config/bootstrap.py index 4a72b2cd..74714c7e 100644 --- a/borgmatic/actions/config/bootstrap.py +++ b/borgmatic/actions/config/bootstrap.py @@ -127,5 +127,4 @@ def run_bootstrap(bootstrap_arguments, global_arguments, local_borg_version): extract_to_stdout=False, destination_path=bootstrap_arguments.destination, strip_components=bootstrap_arguments.strip_components, - progress=bootstrap_arguments.progress, ) diff --git a/borgmatic/actions/create.py b/borgmatic/actions/create.py index e0ef3b1f..a92af261 100644 --- a/borgmatic/actions/create.py +++ b/borgmatic/actions/create.py @@ -289,6 +289,16 @@ def run_create( ): return + if config.get('list_details') and config.get('progress'): + raise ValueError( + 'With the create action, only one of --list/--files/list_details and --progress/progress can be used.' + ) + + if config.get('list_details') and create_arguments.json: + raise ValueError( + 'With the create action, only one of --list/--files/list_details and --json can be used.' + ) + logger.info(f'Creating archive{dry_run_label}') working_directory = borgmatic.config.paths.get_working_directory(config) @@ -327,22 +337,7 @@ def run_create( borgmatic_runtime_directory, local_path=local_path, remote_path=remote_path, - progress=( - config.get('progress') - if create_arguments.progress is None - else create_arguments.progress - ), - stats=( - config.get('statistics') - if create_arguments.stats is None - else create_arguments.stats - ), json=create_arguments.json, - list_files=( - config.get('list_details') - if create_arguments.list_files is None - else create_arguments.list_files - ), stream_processes=stream_processes, ) diff --git a/borgmatic/actions/export_tar.py b/borgmatic/actions/export_tar.py index cc18aeeb..f04b06ff 100644 --- a/borgmatic/actions/export_tar.py +++ b/borgmatic/actions/export_tar.py @@ -43,10 +43,5 @@ def run_export_tar( local_path=local_path, remote_path=remote_path, tar_filter=export_tar_arguments.tar_filter, - list_files=( - config.get('list_details') - if export_tar_arguments.list_files is None - else export_tar_arguments.list_files - ), strip_components=export_tar_arguments.strip_components, ) diff --git a/borgmatic/actions/extract.py b/borgmatic/actions/extract.py index 3e42b57d..feaaac81 100644 --- a/borgmatic/actions/extract.py +++ b/borgmatic/actions/extract.py @@ -45,9 +45,4 @@ def run_extract( remote_path=remote_path, destination_path=extract_arguments.destination, strip_components=extract_arguments.strip_components, - progress=( - config.get('progress') - if extract_arguments.progress is None - else extract_arguments.progress - ), ) diff --git a/borgmatic/actions/transfer.py b/borgmatic/actions/transfer.py index 8a27d16b..c9601515 100644 --- a/borgmatic/actions/transfer.py +++ b/borgmatic/actions/transfer.py @@ -17,7 +17,13 @@ def run_transfer( ''' Run the "transfer" action for the given repository. ''' + if transfer_arguments.archive and config.get('match_archives'): + raise ValueError( + 'With the transfer action, only one of --archive and --match-archives/match_archives can be used.' + ) + logger.info('Transferring archives to repository') + borgmatic.borg.transfer.transfer_archives( global_arguments.dry_run, repository['path'], diff --git a/borgmatic/borg/check.py b/borgmatic/borg/check.py index c02b6ec4..935c52c8 100644 --- a/borgmatic/borg/check.py +++ b/borgmatic/borg/check.py @@ -32,7 +32,7 @@ def make_archive_filter_flags(local_borg_version, config, checks, check_argument if prefix else ( flags.make_match_archives_flags( - check_arguments.match_archives or config.get('match_archives'), + config.get('match_archives'), config.get('archive_name_format'), local_borg_version, ) @@ -143,9 +143,6 @@ def check_archives( umask = config.get('umask') borg_exit_codes = config.get('borg_exit_codes') working_directory = borgmatic.config.paths.get_working_directory(config) - progress = ( - config.get('progress') if check_arguments.progress is None else check_arguments.progress - ) if 'data' in checks: checks.add('archives') @@ -173,7 +170,7 @@ def check_archives( + (('--log-json',) if global_arguments.log_json else ()) + (('--lock-wait', str(lock_wait)) if lock_wait else ()) + verbosity_flags - + (('--progress',) if progress else ()) + + (('--progress',) if config.get('progress') else ()) + (tuple(extra_borg_options.split(' ')) if extra_borg_options else ()) + flags.make_repository_flags(repository_path, local_borg_version) ) @@ -182,7 +179,9 @@ def check_archives( full_command, # The Borg repair option triggers an interactive prompt, which won't work when output is # captured. And progress messes with the terminal directly. - output_file=(DO_NOT_CAPTURE if check_arguments.repair or progress else None), + output_file=( + DO_NOT_CAPTURE if check_arguments.repair or config.get('progress') else None + ), environment=environment.make_environment(config), working_directory=working_directory, borg_local_path=local_path, diff --git a/borgmatic/borg/compact.py b/borgmatic/borg/compact.py index fd248cbf..b443e8c0 100644 --- a/borgmatic/borg/compact.py +++ b/borgmatic/borg/compact.py @@ -15,9 +15,7 @@ def compact_segments( global_arguments, local_path='borg', remote_path=None, - progress=False, cleanup_commits=False, - threshold=None, ): ''' Given dry-run flag, a local or remote repository path, a configuration dict, and the local Borg @@ -26,6 +24,7 @@ def compact_segments( umask = config.get('umask', None) lock_wait = config.get('lock_wait', None) extra_borg_options = config.get('extra_borg_options', {}).get('compact', '') + threshold = config.get('compact_threshold') full_command = ( (local_path, 'compact') @@ -33,7 +32,7 @@ def compact_segments( + (('--umask', str(umask)) if umask else ()) + (('--log-json',) if global_arguments.log_json else ()) + (('--lock-wait', str(lock_wait)) if lock_wait else ()) - + (('--progress',) if progress else ()) + + (('--progress',) if config.get('progress') else ()) + (('--cleanup-commits',) if cleanup_commits else ()) + (('--threshold', str(threshold)) if threshold else ()) + (('--info',) if logger.getEffectiveLevel() == logging.INFO else ()) diff --git a/borgmatic/borg/create.py b/borgmatic/borg/create.py index ccdb41a9..de5115dc 100644 --- a/borgmatic/borg/create.py +++ b/borgmatic/borg/create.py @@ -213,9 +213,7 @@ def make_base_create_command( borgmatic_runtime_directory, local_path='borg', remote_path=None, - progress=False, json=False, - list_files=False, stream_processes=None, ): ''' @@ -293,7 +291,7 @@ def make_base_create_command( + (('--lock-wait', str(lock_wait)) if lock_wait else ()) + ( ('--list', '--filter', list_filter_flags) - if list_files and not json and not progress + if config.get('list_details') and not json and not config.get('progress') else () ) + (('--dry-run',) if dry_run else ()) @@ -361,10 +359,7 @@ def create_archive( borgmatic_runtime_directory, local_path='borg', remote_path=None, - progress=False, - stats=False, json=False, - list_files=False, stream_processes=None, ): ''' @@ -389,28 +384,26 @@ def create_archive( borgmatic_runtime_directory, local_path, remote_path, - progress, json, - list_files, stream_processes, ) if json: output_log_level = None - elif list_files or (stats and not dry_run): + elif config.get('list_details') or (config.get('statistics') and not dry_run): output_log_level = logging.ANSWER else: output_log_level = logging.INFO # The progress output isn't compatible with captured and logged output, as progress messes with # the terminal directly. - output_file = DO_NOT_CAPTURE if progress else None + output_file = DO_NOT_CAPTURE if config.get('progress') else None create_flags += ( (('--info',) if logger.getEffectiveLevel() == logging.INFO and not json else ()) - + (('--stats',) if stats and not json and not dry_run else ()) + + (('--stats',) if config.get('statistics') and not json and not dry_run else ()) + (('--debug', '--show-rc') if logger.isEnabledFor(logging.DEBUG) and not json else ()) - + (('--progress',) if progress else ()) + + (('--progress',) if config.get('progress') else ()) + (('--json',) if json else ()) ) borg_exit_codes = config.get('borg_exit_codes') diff --git a/borgmatic/borg/delete.py b/borgmatic/borg/delete.py index f31730ce..63ee0ef8 100644 --- a/borgmatic/borg/delete.py +++ b/borgmatic/borg/delete.py @@ -34,14 +34,7 @@ def make_delete_command( + borgmatic.borg.flags.make_flags('umask', config.get('umask')) + borgmatic.borg.flags.make_flags('log-json', global_arguments.log_json) + borgmatic.borg.flags.make_flags('lock-wait', config.get('lock_wait')) - + borgmatic.borg.flags.make_flags( - 'list', - ( - config.get('list_details') - if delete_arguments.list_archives is None - else delete_arguments.list_archives - ), - ) + + borgmatic.borg.flags.make_flags('list', config.get('list_details')) + ( (('--force',) + (('--force',) if delete_arguments.force >= 2 else ())) if delete_arguments.force @@ -55,9 +48,17 @@ def make_delete_command( local_borg_version=local_borg_version, default_archive_name_format='*', ) + + (('--stats',) if config.get('statistics') else ()) + borgmatic.borg.flags.make_flags_from_arguments( delete_arguments, - excludes=('list_archives', 'force', 'match_archives', 'archive', 'repository'), + excludes=( + 'list_details', + 'statistics', + 'force', + 'match_archives', + 'archive', + 'repository', + ), ) + borgmatic.borg.flags.make_repository_flags(repository['path'], local_borg_version) ) @@ -105,7 +106,7 @@ def delete_archives( repo_delete_arguments = argparse.Namespace( repository=repository['path'], - list_archives=delete_arguments.list_archives, + list_details=delete_arguments.list_details, force=delete_arguments.force, cache_only=delete_arguments.cache_only, keep_security_info=delete_arguments.keep_security_info, diff --git a/borgmatic/borg/export_tar.py b/borgmatic/borg/export_tar.py index d8283535..224c07b1 100644 --- a/borgmatic/borg/export_tar.py +++ b/borgmatic/borg/export_tar.py @@ -20,7 +20,6 @@ def export_tar_archive( local_path='borg', remote_path=None, tar_filter=None, - list_files=False, strip_components=None, ): ''' @@ -43,7 +42,7 @@ def export_tar_archive( + (('--log-json',) if global_arguments.log_json else ()) + (('--lock-wait', str(lock_wait)) if lock_wait else ()) + (('--info',) if logger.getEffectiveLevel() == logging.INFO else ()) - + (('--list',) if list_files else ()) + + (('--list',) if config.get('list_details') else ()) + (('--debug', '--show-rc') if logger.isEnabledFor(logging.DEBUG) else ()) + (('--dry-run',) if dry_run else ()) + (('--tar-filter', tar_filter) if tar_filter else ()) @@ -57,7 +56,7 @@ def export_tar_archive( + (tuple(paths) if paths else ()) ) - if list_files: + if config.get('list_details'): output_log_level = logging.ANSWER else: output_log_level = logging.INFO diff --git a/borgmatic/borg/extract.py b/borgmatic/borg/extract.py index 52d7c35f..aa354cbc 100644 --- a/borgmatic/borg/extract.py +++ b/borgmatic/borg/extract.py @@ -77,7 +77,6 @@ def extract_archive( remote_path=None, destination_path=None, strip_components=None, - progress=False, extract_to_stdout=False, ): ''' @@ -92,8 +91,8 @@ def extract_archive( umask = config.get('umask', None) lock_wait = config.get('lock_wait', None) - if progress and extract_to_stdout: - raise ValueError('progress and extract_to_stdout cannot both be set') + if config.get('progress') and extract_to_stdout: + raise ValueError('progress and extract to stdout cannot both be set') if feature.available(feature.Feature.NUMERIC_IDS, local_borg_version): numeric_ids_flags = ('--numeric-ids',) if config.get('numeric_ids') else () @@ -128,7 +127,7 @@ def extract_archive( + (('--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 ()) + + (('--progress',) if config.get('progress') else ()) + (('--stdout',) if extract_to_stdout else ()) + flags.make_repository_archive_flags( # Make the repository path absolute so the destination directory used below via changing @@ -148,7 +147,7 @@ def extract_archive( # The progress output isn't compatible with captured and logged output, as progress messes with # the terminal directly. - if progress: + if config.get('progress'): return execute_command( full_command, output_file=DO_NOT_CAPTURE, diff --git a/borgmatic/borg/info.py b/borgmatic/borg/info.py index bde80a97..2d90ef52 100644 --- a/borgmatic/borg/info.py +++ b/borgmatic/borg/info.py @@ -48,9 +48,7 @@ def make_info_command( if info_arguments.prefix else ( flags.make_match_archives_flags( - info_arguments.match_archives - or info_arguments.archive - or config.get('match_archives'), + info_arguments.archive or config.get('match_archives'), config.get('archive_name_format'), local_borg_version, ) diff --git a/borgmatic/borg/prune.py b/borgmatic/borg/prune.py index b29cbe67..34530eeb 100644 --- a/borgmatic/borg/prune.py +++ b/borgmatic/borg/prune.py @@ -41,7 +41,7 @@ def make_prune_flags(config, prune_arguments, local_borg_version): if prefix else ( flags.make_match_archives_flags( - prune_arguments.match_archives or config.get('match_archives'), + config.get('match_archives'), config.get('archive_name_format'), local_borg_version, ) @@ -66,12 +66,6 @@ def prune_archives( borgmatic.logger.add_custom_log_levels() umask = config.get('umask', None) lock_wait = config.get('lock_wait', None) - stats = config.get('statistics') if prune_arguments.stats is None else prune_arguments.stats - list_archives = ( - config.get('list_details') - if prune_arguments.list_archives is None - else prune_arguments.list_archives - ) extra_borg_options = config.get('extra_borg_options', {}).get('prune', '') full_command = ( @@ -83,7 +77,7 @@ def prune_archives( + (('--lock-wait', str(lock_wait)) if lock_wait else ()) + ( ('--stats',) - if stats + if config.get('statistics') and not dry_run and not feature.available(feature.Feature.NO_PRUNE_STATS, local_borg_version) else () @@ -91,16 +85,16 @@ def prune_archives( + (('--info',) if logger.getEffectiveLevel() == logging.INFO else ()) + flags.make_flags_from_arguments( prune_arguments, - excludes=('repository', 'match_archives', 'stats', 'list_archives'), + excludes=('repository', 'match_archives', 'statistics', 'list_details'), ) - + (('--list',) if list_archives else ()) + + (('--list',) if config.get('list_details') else ()) + (('--debug', '--show-rc') if logger.isEnabledFor(logging.DEBUG) else ()) + (('--dry-run',) if dry_run else ()) + (tuple(extra_borg_options.split(' ')) if extra_borg_options else ()) + flags.make_repository_flags(repository_path, local_borg_version) ) - if stats or list_archives: + if config.get('statistics') or config.get('list_details'): output_log_level = logging.ANSWER else: output_log_level = logging.INFO diff --git a/borgmatic/borg/recreate.py b/borgmatic/borg/recreate.py index 15969f5f..e6f1e04d 100644 --- a/borgmatic/borg/recreate.py +++ b/borgmatic/borg/recreate.py @@ -38,9 +38,6 @@ def recreate_archive( patterns_file = write_patterns_file( patterns, borgmatic.config.paths.get_working_directory(config) ) - list_files = ( - config.get('list_details') if recreate_arguments.list is None else recreate_arguments.list - ) recreate_command = ( (local_path, 'recreate') @@ -56,7 +53,7 @@ def recreate_archive( '--filter', make_list_filter_flags(local_borg_version, global_arguments.dry_run), ) - if list_files + if config.get('list_details') else () ) # Flag --target works only for a single archive. @@ -71,12 +68,10 @@ def recreate_archive( + (('--chunker-params', chunker_params) if chunker_params else ()) + ( flags.make_match_archives_flags( - recreate_arguments.match_archives or archive or config.get('match_archives'), + archive or config.get('match_archives'), config.get('archive_name_format'), local_borg_version, ) - if recreate_arguments.match_archives - else () ) + (('--recompress', recompress) if recompress else ()) + exclude_flags diff --git a/borgmatic/borg/repo_delete.py b/borgmatic/borg/repo_delete.py index fa66d3c0..dee5a1a9 100644 --- a/borgmatic/borg/repo_delete.py +++ b/borgmatic/borg/repo_delete.py @@ -39,14 +39,14 @@ def make_repo_delete_command( + borgmatic.borg.flags.make_flags('umask', config.get('umask')) + borgmatic.borg.flags.make_flags('log-json', global_arguments.log_json) + borgmatic.borg.flags.make_flags('lock-wait', config.get('lock_wait')) - + borgmatic.borg.flags.make_flags('list', repo_delete_arguments.list_archives) + + borgmatic.borg.flags.make_flags('list', config.get('list_details')) + ( (('--force',) + (('--force',) if repo_delete_arguments.force >= 2 else ())) if repo_delete_arguments.force else () ) + borgmatic.borg.flags.make_flags_from_arguments( - repo_delete_arguments, excludes=('list_archives', 'force', 'repository') + repo_delete_arguments, excludes=('list_details', 'force', 'repository') ) + borgmatic.borg.flags.make_repository_flags(repository['path'], local_borg_version) ) diff --git a/borgmatic/borg/repo_list.py b/borgmatic/borg/repo_list.py index 9722758f..9f05adbf 100644 --- a/borgmatic/borg/repo_list.py +++ b/borgmatic/borg/repo_list.py @@ -113,7 +113,7 @@ def make_repo_list_command( if repo_list_arguments.prefix else ( flags.make_match_archives_flags( - repo_list_arguments.match_archives or config.get('match_archives'), + config.get('match_archives'), config.get('archive_name_format'), local_borg_version, ) diff --git a/borgmatic/borg/transfer.py b/borgmatic/borg/transfer.py index 528cd64c..5e16efce 100644 --- a/borgmatic/borg/transfer.py +++ b/borgmatic/borg/transfer.py @@ -40,9 +40,7 @@ def transfer_archives( ) or ( flags.make_match_archives_flags( - transfer_arguments.match_archives - or transfer_arguments.archive - or config.get('match_archives'), + transfer_arguments.archive or config.get('match_archives'), config.get('archive_name_format'), local_borg_version, ) @@ -52,16 +50,11 @@ def transfer_archives( + flags.make_flags('other-repo', transfer_arguments.source_repository) + flags.make_flags('dry-run', dry_run) ) - progress = ( - config.get('progress') - if transfer_arguments.progress is None - else transfer_arguments.progress - ) return execute_command( full_command, output_log_level=logging.ANSWER, - output_file=DO_NOT_CAPTURE if progress else None, + output_file=DO_NOT_CAPTURE if config.get('progress') else None, environment=environment.make_environment(config), working_directory=borgmatic.config.paths.get_working_directory(config), borg_local_path=local_path, diff --git a/borgmatic/commands/arguments.py b/borgmatic/commands/arguments.py index b4623a10..c3b61f42 100644 --- a/borgmatic/commands/arguments.py +++ b/borgmatic/commands/arguments.py @@ -709,7 +709,7 @@ def make_parsers(schema, unparsed_arguments): ) transfer_group.add_argument( '--progress', - default=False, + default=None, action='store_true', help='Display progress as each archive is transferred', ) @@ -776,13 +776,17 @@ def make_parsers(schema, unparsed_arguments): ) prune_group.add_argument( '--stats', - dest='stats', - default=False, + dest='statistics', + default=None, action='store_true', help='Display statistics of the pruned archive [Borg 1 only]', ) prune_group.add_argument( - '--list', dest='list_archives', action='store_true', help='List archives kept/pruned' + '--list', + dest='list_details', + default=None, + action='store_true', + help='List archives kept/pruned', ) prune_group.add_argument( '--oldest', @@ -820,8 +824,7 @@ def make_parsers(schema, unparsed_arguments): ) compact_group.add_argument( '--progress', - dest='progress', - default=False, + default=None, action='store_true', help='Display progress as each segment is compacted', ) @@ -835,7 +838,7 @@ def make_parsers(schema, unparsed_arguments): compact_group.add_argument( '--threshold', type=int, - dest='threshold', + dest='compact_threshold', help='Minimum saved space percentage threshold for compacting a segment, defaults to 10', ) compact_group.add_argument( @@ -856,20 +859,24 @@ def make_parsers(schema, unparsed_arguments): ) create_group.add_argument( '--progress', - dest='progress', - default=False, + default=None, action='store_true', help='Display progress for each file as it is backed up', ) create_group.add_argument( '--stats', - dest='stats', - default=False, + dest='statistics', + default=None, action='store_true', help='Display statistics of archive', ) create_group.add_argument( - '--list', '--files', dest='list_files', action='store_true', help='Show per-file details' + '--list', + '--files', + dest='list_details', + default=None, + action='store_true', + help='Show per-file details', ) create_group.add_argument( '--json', dest='json', default=False, action='store_true', help='Output results as JSON' @@ -890,8 +897,7 @@ def make_parsers(schema, unparsed_arguments): ) check_group.add_argument( '--progress', - dest='progress', - default=False, + default=None, action='store_true', help='Display progress for each file as it is checked', ) @@ -948,12 +954,15 @@ def make_parsers(schema, unparsed_arguments): ) delete_group.add_argument( '--list', - dest='list_archives', + dest='list_details', + default=None, action='store_true', help='Show details for the deleted archives', ) delete_group.add_argument( '--stats', + dest='statistics', + default=None, action='store_true', help='Display statistics for the deleted archives', ) @@ -1058,8 +1067,7 @@ def make_parsers(schema, unparsed_arguments): ) extract_group.add_argument( '--progress', - dest='progress', - default=False, + default=None, action='store_true', help='Display progress for each file as it is extracted', ) @@ -1134,8 +1142,7 @@ def make_parsers(schema, unparsed_arguments): ) config_bootstrap_group.add_argument( '--progress', - dest='progress', - default=False, + default=None, action='store_true', help='Display progress for each file as it is extracted', ) @@ -1228,7 +1235,12 @@ def make_parsers(schema, unparsed_arguments): '--tar-filter', help='Name of filter program to pipe data through' ) export_tar_group.add_argument( - '--list', '--files', dest='list_files', action='store_true', help='Show per-file details' + '--list', + '--files', + dest='list_details', + default=None, + action='store_true', + help='Show per-file details', ) export_tar_group.add_argument( '--strip-components', @@ -1339,7 +1351,8 @@ def make_parsers(schema, unparsed_arguments): ) repo_delete_group.add_argument( '--list', - dest='list_archives', + dest='list_details', + default=None, action='store_true', help='Show details for the archives in the given repository', ) @@ -1770,7 +1783,11 @@ def make_parsers(schema, unparsed_arguments): help='Archive name, hash, or series to recreate', ) recreate_group.add_argument( - '--list', dest='list', action='store_true', help='Show per-file details' + '--list', + dest='list_details', + default=None, + action='store_true', + help='Show per-file details', ) recreate_group.add_argument( '--target', @@ -1865,15 +1882,6 @@ def parse_arguments(schema, *unparsed_arguments): f"Unrecognized argument{'s' if len(unknown_arguments) > 1 else ''}: {' '.join(unknown_arguments)}" ) - if 'create' in arguments and arguments['create'].list_files and arguments['create'].progress: - raise ValueError( - 'With the create action, only one of --list (--files) and --progress flags can be used.' - ) - if 'create' in arguments and arguments['create'].list_files and arguments['create'].json: - raise ValueError( - 'With the create action, only one of --list (--files) and --json flags can be used.' - ) - if ( ('list' in arguments and 'repo-info' in arguments and arguments['list'].json) or ('list' in arguments and 'info' in arguments and arguments['list'].json) @@ -1881,15 +1889,6 @@ def parse_arguments(schema, *unparsed_arguments): ): raise ValueError('With the --json flag, multiple actions cannot be used together.') - if ( - 'transfer' in arguments - and arguments['transfer'].archive - and arguments['transfer'].match_archives - ): - raise ValueError( - '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.' diff --git a/borgmatic/commands/borgmatic.py b/borgmatic/commands/borgmatic.py index c457c8be..28a92b53 100644 --- a/borgmatic/commands/borgmatic.py +++ b/borgmatic/commands/borgmatic.py @@ -600,14 +600,14 @@ def run_actions( ) -def load_configurations(config_filenames, global_arguments, overrides=None, resolve_env=True): +def load_configurations(config_filenames, arguments, overrides=None, resolve_env=True): ''' - Given a sequence of configuration filenames, global arguments as an argparse.Namespace, a - sequence of configuration file override strings in the form of "option.suboption=value", and - whether to resolve environment variables, load and validate each configuration file. Return the - results as a tuple of: dict of configuration filename to corresponding parsed configuration, a - sequence of paths for all loaded configuration files (including includes), and a sequence of - logging.LogRecord instances containing any parse errors. + Given a sequence of configuration filenames, arguments as a dict from action name to + argparse.Namespace, a sequence of configuration file override strings in the form of + "option.suboption=value", and whether to resolve environment variables, load and validate each + configuration file. Return the results as a tuple of: dict of configuration filename to + corresponding parsed configuration, a sequence of paths for all loaded configuration files + (including includes), and a sequence of logging.LogRecord instances containing any parse errors. Log records are returned here instead of being logged directly because logging isn't yet initialized at this point! (Although with the Delayed_logging_handler now in place, maybe this @@ -635,7 +635,7 @@ def load_configurations(config_filenames, global_arguments, overrides=None, reso configs[config_filename], paths, parse_logs = validate.parse_configuration( config_filename, validate.schema_filename(), - global_arguments, + arguments, overrides, resolve_env, ) @@ -1010,7 +1010,7 @@ def main(extra_summary_logs=[]): # pragma: no cover config_filenames = tuple(collect.collect_config_filenames(global_arguments.config_paths)) configs, config_paths, parse_logs = load_configurations( config_filenames, - global_arguments, + arguments, global_arguments.overrides, resolve_env=global_arguments.resolve_env and not validate, ) diff --git a/borgmatic/config/arguments.py b/borgmatic/config/arguments.py index 85c8eef9..3252d779 100644 --- a/borgmatic/config/arguments.py +++ b/borgmatic/config/arguments.py @@ -160,15 +160,16 @@ def prepare_arguments_for_config(global_arguments, schema): return tuple(prepared_values) -def apply_arguments_to_config(config, schema, global_arguments): # pragma: no cover +def apply_arguments_to_config(config, schema, arguments): ''' - Given a configuration dict, a corresponding configuration schema dict, and global arguments as - an argparse.Namespace, set those given argument values into their corresponding configuration - options in the configuration dict. + Given a configuration dict, a corresponding configuration schema dict, and arguments as a dict + from action name to argparse.Namespace, set those given argument values into their corresponding + configuration options in the configuration dict. This supports argument flags of the from "--foo.bar.baz" where each dotted component is a nested configuration object. Additionally, flags like "--foo.bar[0].baz" are supported to update a list element in the configuration. ''' - for keys, value in prepare_arguments_for_config(global_arguments, schema): - set_values(config, keys, value) + for action_arguments in arguments.values(): + for keys, value in prepare_arguments_for_config(action_arguments, schema): + set_values(config, keys, value) diff --git a/borgmatic/config/validate.py b/borgmatic/config/validate.py index 98bf080c..9cb02243 100644 --- a/borgmatic/config/validate.py +++ b/borgmatic/config/validate.py @@ -97,14 +97,14 @@ def apply_logical_validation(config_filename, parsed_configuration): def parse_configuration( - config_filename, schema_filename, global_arguments, overrides=None, resolve_env=True + config_filename, schema_filename, arguments, overrides=None, resolve_env=True ): ''' Given the path to a config filename in YAML format, the path to a schema filename in a YAML - rendition of JSON Schema format, global arguments as an argparse.Namespace, a sequence of - configuration file override strings in the form of "option.suboption=value", and whether to - resolve environment variables, return the parsed configuration as a data structure of nested - dicts and lists corresponding to the schema. Example return value. + rendition of JSON Schema format, arguments as dict from action name to argparse.Namespace, a + sequence of configuration file override strings in the form of "option.suboption=value", and + whether to resolve environment variables, return the parsed configuration as a data structure of + nested dicts and lists corresponding to the schema. Example return value. Example return value: @@ -129,7 +129,7 @@ def parse_configuration( except (ruamel.yaml.error.YAMLError, RecursionError) as error: raise Validation_error(config_filename, (str(error),)) - borgmatic.config.arguments.apply_arguments_to_config(config, schema, global_arguments) + borgmatic.config.arguments.apply_arguments_to_config(config, schema, arguments) override.apply_overrides(config, schema, overrides) constants.apply_constants(config, config.get('constants') if config else {}) diff --git a/tests/integration/commands/test_arguments.py b/tests/integration/commands/test_arguments.py index ed6a9892..a357e1b0 100644 --- a/tests/integration/commands/test_arguments.py +++ b/tests/integration/commands/test_arguments.py @@ -271,11 +271,11 @@ def test_parse_arguments_with_no_actions_passes_argument_to_relevant_actions(): arguments = module.parse_arguments({}, '--stats', '--list') assert 'prune' in arguments - assert arguments['prune'].stats - assert arguments['prune'].list_archives + assert arguments['prune'].statistics + assert arguments['prune'].list_details assert 'create' in arguments - assert arguments['create'].stats - assert arguments['create'].list_files + assert arguments['create'].statistics + assert arguments['create'].list_details assert 'check' in arguments @@ -557,20 +557,6 @@ def test_parse_arguments_with_list_flag_but_no_relevant_action_raises_value_erro module.parse_arguments({}, '--list', 'repo-create') -def test_parse_arguments_disallows_list_with_progress_for_create_action(): - flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) - - with pytest.raises(ValueError): - module.parse_arguments({}, 'create', '--list', '--progress') - - -def test_parse_arguments_disallows_list_with_json_for_create_action(): - flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) - - with pytest.raises(ValueError): - module.parse_arguments({}, 'create', '--list', '--json') - - def test_parse_arguments_allows_json_with_list_or_info(): flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) @@ -599,22 +585,6 @@ def test_parse_arguments_disallows_json_with_both_repo_info_and_info(): module.parse_arguments({}, 'repo-info', 'info', '--json') -def test_parse_arguments_disallows_transfer_with_both_archive_and_match_archives(): - flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) - - with pytest.raises(ValueError): - module.parse_arguments( - {}, - 'transfer', - '--source-repository', - 'source.borg', - '--archive', - 'foo', - '--match-archives', - 'sh:*bar', - ) - - def test_parse_arguments_disallows_list_with_both_prefix_and_match_archives(): flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) diff --git a/tests/integration/config/test_validate.py b/tests/integration/config/test_validate.py index 61d12d7f..e74989c6 100644 --- a/tests/integration/config/test_validate.py +++ b/tests/integration/config/test_validate.py @@ -59,7 +59,7 @@ def test_parse_configuration_transforms_file_into_mapping(): ) config, config_paths, logs = module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', global_arguments=flexmock() + '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} ) assert config == { @@ -89,7 +89,7 @@ def test_parse_configuration_passes_through_quoted_punctuation(): ) config, config_paths, logs = module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', global_arguments=flexmock() + '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} ) assert config == { @@ -123,7 +123,9 @@ def test_parse_configuration_with_schema_lacking_examples_does_not_raise(): ''', ) - module.parse_configuration('/tmp/config.yaml', '/tmp/schema.yaml', global_arguments=flexmock()) + module.parse_configuration( + '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} + ) def test_parse_configuration_inlines_include_inside_deprecated_section(): @@ -150,7 +152,7 @@ def test_parse_configuration_inlines_include_inside_deprecated_section(): builtins.should_receive('open').with_args('/tmp/include.yaml').and_return(include_file) config, config_paths, logs = module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', global_arguments=flexmock() + '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} ) assert config == { @@ -188,7 +190,7 @@ def test_parse_configuration_merges_include(): builtins.should_receive('open').with_args('/tmp/include.yaml').and_return(include_file) config, config_paths, logs = module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', global_arguments=flexmock() + '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} ) assert config == { @@ -205,7 +207,7 @@ def test_parse_configuration_merges_include(): def test_parse_configuration_raises_for_missing_config_file(): with pytest.raises(FileNotFoundError): module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', global_arguments=flexmock() + '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} ) @@ -219,7 +221,7 @@ def test_parse_configuration_raises_for_missing_schema_file(): with pytest.raises(FileNotFoundError): module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', global_arguments=flexmock() + '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} ) @@ -228,7 +230,7 @@ def test_parse_configuration_raises_for_syntax_error(): with pytest.raises(ValueError): module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', global_arguments=flexmock() + '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} ) @@ -243,7 +245,7 @@ def test_parse_configuration_raises_for_validation_error(): with pytest.raises(module.Validation_error): module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', global_arguments=flexmock() + '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} ) @@ -263,7 +265,7 @@ def test_parse_configuration_applies_overrides(): config, config_paths, logs = module.parse_configuration( '/tmp/config.yaml', '/tmp/schema.yaml', - global_arguments=flexmock(), + arguments={'global': flexmock()}, overrides=['local_path=borg2'], ) @@ -293,7 +295,7 @@ def test_parse_configuration_applies_normalization_after_environment_variable_in flexmock(os).should_receive('getenv').replace_with(lambda variable_name, default: default) config, config_paths, logs = module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', global_arguments=flexmock() + '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} ) assert config == { diff --git a/tests/unit/actions/config/test_bootstrap.py b/tests/unit/actions/config/test_bootstrap.py index 7a21e715..554ad05d 100644 --- a/tests/unit/actions/config/test_bootstrap.py +++ b/tests/unit/actions/config/test_bootstrap.py @@ -267,7 +267,6 @@ def test_run_bootstrap_does_not_raise(): archive='archive', destination='dest', strip_components=1, - progress=False, user_runtime_directory='/borgmatic', ssh_command=None, local_path='borg7', @@ -307,7 +306,6 @@ def test_run_bootstrap_translates_ssh_command_argument_to_config(): archive='archive', destination='dest', strip_components=1, - progress=False, user_runtime_directory='/borgmatic', ssh_command='ssh -i key', local_path='borg7', @@ -339,7 +337,6 @@ def test_run_bootstrap_translates_ssh_command_argument_to_config(): extract_to_stdout=False, destination_path='dest', strip_components=1, - progress=False, local_path='borg7', remote_path='borg8', ).and_return(extract_process).once() diff --git a/tests/unit/actions/test_check.py b/tests/unit/actions/test_check.py index 6b16a901..069fae1e 100644 --- a/tests/unit/actions/test_check.py +++ b/tests/unit/actions/test_check.py @@ -577,7 +577,6 @@ def test_collect_spot_check_source_paths_parses_borg_output(): borgmatic_runtime_directory='/run/borgmatic', local_path=object, remote_path=object, - list_files=True, stream_processes=True, ).and_return((('borg', 'create'), ('repo::archive',), flexmock())) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( @@ -625,7 +624,6 @@ def test_collect_spot_check_source_paths_passes_through_stream_processes_false() borgmatic_runtime_directory='/run/borgmatic', local_path=object, remote_path=object, - list_files=True, stream_processes=False, ).and_return((('borg', 'create'), ('repo::archive',), flexmock())) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( @@ -673,7 +671,6 @@ def test_collect_spot_check_source_paths_without_working_directory_parses_borg_o borgmatic_runtime_directory='/run/borgmatic', local_path=object, remote_path=object, - list_files=True, stream_processes=True, ).and_return((('borg', 'create'), ('repo::archive',), flexmock())) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( @@ -721,7 +718,6 @@ def test_collect_spot_check_source_paths_skips_directories(): borgmatic_runtime_directory='/run/borgmatic', local_path=object, remote_path=object, - list_files=True, stream_processes=True, ).and_return((('borg', 'create'), ('repo::archive',), flexmock())) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( @@ -860,14 +856,13 @@ def test_collect_spot_check_source_paths_uses_working_directory(): flexmock(module.borgmatic.borg.create).should_receive('make_base_create_command').with_args( dry_run=True, repository_path='repo', - config=object, + config={'working_directory': '/working/dir', 'list_details': True}, patterns=[Pattern('foo'), Pattern('bar')], local_borg_version=object, global_arguments=object, borgmatic_runtime_directory='/run/borgmatic', local_path=object, remote_path=object, - list_files=True, stream_processes=True, ).and_return((('borg', 'create'), ('repo::archive',), flexmock())) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( diff --git a/tests/unit/actions/test_compact.py b/tests/unit/actions/test_compact.py index 1531fd59..04a3a25e 100644 --- a/tests/unit/actions/test_compact.py +++ b/tests/unit/actions/test_compact.py @@ -9,7 +9,10 @@ def test_compact_actions_calls_hooks_for_configured_repository(): flexmock(module.borgmatic.config.validate).should_receive('repositories_match').never() flexmock(module.borgmatic.borg.compact).should_receive('compact_segments').once() compact_arguments = flexmock( - repository=None, progress=flexmock(), cleanup_commits=flexmock(), threshold=flexmock() + repository=None, + progress=flexmock(), + cleanup_commits=flexmock(), + compact_threshold=flexmock(), ) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) @@ -34,7 +37,10 @@ def test_compact_runs_with_selected_repository(): flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.compact).should_receive('compact_segments').once() compact_arguments = flexmock( - repository=flexmock(), progress=flexmock(), cleanup_commits=flexmock(), threshold=flexmock() + repository=flexmock(), + progress=flexmock(), + cleanup_commits=flexmock(), + compact_threshold=flexmock(), ) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) @@ -51,84 +57,6 @@ def test_compact_runs_with_selected_repository(): ) -def test_compact_favors_flags_over_config(): - flexmock(module.logger).answer = lambda message: None - flexmock(module.borgmatic.config.validate).should_receive( - 'repositories_match' - ).once().and_return(True) - flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) - flexmock(module.borgmatic.borg.compact).should_receive('compact_segments').with_args( - object, - object, - object, - object, - object, - local_path=object, - remote_path=object, - progress=False, - cleanup_commits=object, - threshold=15, - ).once() - compact_arguments = flexmock( - repository=flexmock(), - progress=False, - cleanup_commits=flexmock(), - threshold=15, - ) - global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) - - module.run_compact( - config_filename='test.yaml', - repository={'path': 'repo'}, - config={'progress': True, 'compact_threshold': 20}, - local_borg_version=None, - compact_arguments=compact_arguments, - global_arguments=global_arguments, - dry_run_label='', - local_path=None, - remote_path=None, - ) - - -def test_compact_favors_defaults_to_config(): - flexmock(module.logger).answer = lambda message: None - flexmock(module.borgmatic.config.validate).should_receive( - 'repositories_match' - ).once().and_return(True) - flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) - flexmock(module.borgmatic.borg.compact).should_receive('compact_segments').with_args( - object, - object, - object, - object, - object, - local_path=object, - remote_path=object, - progress=True, - cleanup_commits=object, - threshold=20, - ).once() - compact_arguments = flexmock( - repository=flexmock(), - progress=None, - cleanup_commits=flexmock(), - threshold=None, - ) - global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) - - module.run_compact( - config_filename='test.yaml', - repository={'path': 'repo'}, - config={'progress': True, 'compact_threshold': 20}, - 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) @@ -137,7 +65,10 @@ def test_compact_bails_if_repository_does_not_match(): ).once().and_return(False) flexmock(module.borgmatic.borg.compact).should_receive('compact_segments').never() compact_arguments = flexmock( - repository=flexmock(), progress=flexmock(), cleanup_commits=flexmock(), threshold=flexmock() + repository=flexmock(), + progress=flexmock(), + cleanup_commits=flexmock(), + compact_threshold=flexmock(), ) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) diff --git a/tests/unit/actions/test_create.py b/tests/unit/actions/test_create.py index 6f40fb50..6761f8f4 100644 --- a/tests/unit/actions/test_create.py +++ b/tests/unit/actions/test_create.py @@ -443,9 +443,9 @@ def test_run_create_executes_and_calls_hooks_for_configured_repository(): create_arguments = flexmock( repository=None, progress=flexmock(), - stats=flexmock(), + statistics=flexmock(), json=False, - list_files=flexmock(), + list_details=flexmock(), ) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) @@ -484,9 +484,9 @@ def test_run_create_runs_with_selected_repository(): create_arguments = flexmock( repository=flexmock(), progress=flexmock(), - stats=flexmock(), + statistics=flexmock(), json=False, - list_files=flexmock(), + list_details=flexmock(), ) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) @@ -506,118 +506,6 @@ def test_run_create_runs_with_selected_repository(): ) -def test_run_create_favors_flags_over_config(): - flexmock(module.logger).answer = lambda message: None - flexmock(module.borgmatic.config.validate).should_receive( - 'repositories_match' - ).once().and_return(True) - flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - flexmock() - ) - flexmock(module.borgmatic.borg.create).should_receive('create_archive').with_args( - object, - object, - object, - object, - object, - object, - object, - local_path=object, - remote_path=object, - progress=False, - stats=False, - json=object, - list_files=False, - stream_processes=object, - ).once() - flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').and_return({}) - flexmock(module.borgmatic.hooks.dispatch).should_receive( - 'call_hooks_even_if_unconfigured' - ).and_return({}) - flexmock(module).should_receive('collect_patterns').and_return(()) - flexmock(module).should_receive('process_patterns').and_return([]) - flexmock(module.os.path).should_receive('join').and_return('/run/borgmatic/bootstrap') - create_arguments = flexmock( - repository=flexmock(), - progress=False, - stats=False, - json=False, - list_files=False, - ) - global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) - - list( - module.run_create( - config_filename='test.yaml', - repository={'path': 'repo'}, - config={'progress': True, 'statistics': True, 'list_details': True}, - config_paths=['/tmp/test.yaml'], - local_borg_version=None, - create_arguments=create_arguments, - global_arguments=global_arguments, - dry_run_label='', - local_path=None, - remote_path=None, - ) - ) - - -def test_run_create_defaults_to_config(): - flexmock(module.logger).answer = lambda message: None - flexmock(module.borgmatic.config.validate).should_receive( - 'repositories_match' - ).once().and_return(True) - flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - flexmock() - ) - flexmock(module.borgmatic.borg.create).should_receive('create_archive').with_args( - object, - object, - object, - object, - object, - object, - object, - local_path=object, - remote_path=object, - progress=True, - stats=True, - json=object, - list_files=True, - stream_processes=object, - ).once() - flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').and_return({}) - flexmock(module.borgmatic.hooks.dispatch).should_receive( - 'call_hooks_even_if_unconfigured' - ).and_return({}) - flexmock(module).should_receive('collect_patterns').and_return(()) - flexmock(module).should_receive('process_patterns').and_return([]) - flexmock(module.os.path).should_receive('join').and_return('/run/borgmatic/bootstrap') - create_arguments = flexmock( - repository=flexmock(), - progress=True, - stats=True, - json=False, - list_files=True, - ) - global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) - - list( - module.run_create( - config_filename='test.yaml', - repository={'path': 'repo'}, - config={'progress': True, 'statistics': True, 'list_details': True}, - config_paths=['/tmp/test.yaml'], - local_borg_version=None, - create_arguments=create_arguments, - global_arguments=global_arguments, - dry_run_label='', - local_path=None, - remote_path=None, - ) - ) - - def test_run_create_bails_if_repository_does_not_match(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive( @@ -628,9 +516,9 @@ def test_run_create_bails_if_repository_does_not_match(): create_arguments = flexmock( repository=flexmock(), progress=flexmock(), - stats=flexmock(), + statistics=flexmock(), json=False, - list_files=flexmock(), + list_details=flexmock(), ) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) @@ -650,6 +538,72 @@ def test_run_create_bails_if_repository_does_not_match(): ) +def test_run_create_with_both_list_and_json_errors(): + flexmock(module.logger).answer = lambda message: None + flexmock(module.borgmatic.config.validate).should_receive( + 'repositories_match' + ).once().and_return(True) + flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').never() + flexmock(module.borgmatic.borg.create).should_receive('create_archive').never() + create_arguments = flexmock( + repository=flexmock(), + progress=flexmock(), + statistics=flexmock(), + json=True, + list_details=flexmock(), + ) + global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) + + with pytest.raises(ValueError): + list( + module.run_create( + config_filename='test.yaml', + repository={'path': 'repo'}, + config={'list_details': True}, + config_paths=['/tmp/test.yaml'], + local_borg_version=None, + create_arguments=create_arguments, + global_arguments=global_arguments, + dry_run_label='', + local_path=None, + remote_path=None, + ) + ) + + +def test_run_create_with_both_list_and_progress_errors(): + flexmock(module.logger).answer = lambda message: None + flexmock(module.borgmatic.config.validate).should_receive( + 'repositories_match' + ).once().and_return(True) + flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').never() + flexmock(module.borgmatic.borg.create).should_receive('create_archive').never() + create_arguments = flexmock( + repository=flexmock(), + progress=flexmock(), + statistics=flexmock(), + json=False, + list_details=flexmock(), + ) + global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) + + with pytest.raises(ValueError): + list( + module.run_create( + config_filename='test.yaml', + repository={'path': 'repo'}, + config={'list_details': True, 'progress': True}, + config_paths=['/tmp/test.yaml'], + local_borg_version=None, + create_arguments=create_arguments, + global_arguments=global_arguments, + dry_run_label='', + local_path=None, + remote_path=None, + ) + ) + + def test_run_create_produces_json(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive( @@ -673,9 +627,9 @@ def test_run_create_produces_json(): create_arguments = flexmock( repository=flexmock(), progress=flexmock(), - stats=flexmock(), + statistics=flexmock(), json=True, - list_files=flexmock(), + list_details=flexmock(), ) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) diff --git a/tests/unit/actions/test_export_tar.py b/tests/unit/actions/test_export_tar.py index b2e91c38..d32aa6fe 100644 --- a/tests/unit/actions/test_export_tar.py +++ b/tests/unit/actions/test_export_tar.py @@ -13,7 +13,7 @@ def test_run_export_tar_does_not_raise(): paths=flexmock(), destination=flexmock(), tar_filter=flexmock(), - list_files=flexmock(), + list_details=flexmock(), strip_components=flexmock(), ) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) @@ -44,7 +44,6 @@ def test_run_export_tar_favors_flags_over_config(): local_path=object, remote_path=object, tar_filter=object, - list_files=False, strip_components=object, ).once() export_tar_arguments = flexmock( @@ -53,7 +52,7 @@ def test_run_export_tar_favors_flags_over_config(): paths=flexmock(), destination=flexmock(), tar_filter=flexmock(), - list_files=False, + list_details=False, strip_components=flexmock(), ) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) @@ -84,7 +83,6 @@ def test_run_export_tar_defaults_to_config(): local_path=object, remote_path=object, tar_filter=object, - list_files=True, strip_components=object, ).once() export_tar_arguments = flexmock( @@ -93,7 +91,7 @@ def test_run_export_tar_defaults_to_config(): paths=flexmock(), destination=flexmock(), tar_filter=flexmock(), - list_files=None, + list_details=None, strip_components=flexmock(), ) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) diff --git a/tests/unit/actions/test_extract.py b/tests/unit/actions/test_extract.py index 3707c887..1504d4ce 100644 --- a/tests/unit/actions/test_extract.py +++ b/tests/unit/actions/test_extract.py @@ -44,7 +44,6 @@ def test_run_extract_favors_flags_over_config(): remote_path=object, destination_path=object, strip_components=object, - progress=False, ).once() extract_arguments = flexmock( paths=flexmock(), @@ -83,7 +82,6 @@ def test_run_extract_defaults_to_config(): remote_path=object, destination_path=object, strip_components=object, - progress=True, ).once() extract_arguments = flexmock( paths=flexmock(), diff --git a/tests/unit/actions/test_prune.py b/tests/unit/actions/test_prune.py index 762a83c2..b37e50fb 100644 --- a/tests/unit/actions/test_prune.py +++ b/tests/unit/actions/test_prune.py @@ -7,7 +7,7 @@ def test_run_prune_calls_hooks_for_configured_repository(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').never() flexmock(module.borgmatic.borg.prune).should_receive('prune_archives').once() - prune_arguments = flexmock(repository=None, stats=flexmock(), list_archives=flexmock()) + prune_arguments = flexmock(repository=None, statistics=flexmock(), list_details=flexmock()) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) module.run_prune( @@ -29,7 +29,9 @@ def test_run_prune_runs_with_selected_repository(): 'repositories_match' ).once().and_return(True) flexmock(module.borgmatic.borg.prune).should_receive('prune_archives').once() - prune_arguments = flexmock(repository=flexmock(), stats=flexmock(), list_archives=flexmock()) + prune_arguments = flexmock( + repository=flexmock(), statistics=flexmock(), list_details=flexmock() + ) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) module.run_prune( @@ -51,7 +53,9 @@ def test_run_prune_bails_if_repository_does_not_match(): 'repositories_match' ).once().and_return(False) flexmock(module.borgmatic.borg.prune).should_receive('prune_archives').never() - prune_arguments = flexmock(repository=flexmock(), stats=flexmock(), list_archives=flexmock()) + prune_arguments = flexmock( + repository=flexmock(), statistics=flexmock(), list_details=flexmock() + ) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) module.run_prune( diff --git a/tests/unit/actions/test_transfer.py b/tests/unit/actions/test_transfer.py index 03d259be..be4eda25 100644 --- a/tests/unit/actions/test_transfer.py +++ b/tests/unit/actions/test_transfer.py @@ -1,3 +1,4 @@ +import pytest from flexmock import flexmock from borgmatic.actions import transfer as module @@ -6,7 +7,7 @@ from borgmatic.actions import transfer as module def test_run_transfer_does_not_raise(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.borg.transfer).should_receive('transfer_archives') - transfer_arguments = flexmock() + transfer_arguments = flexmock(archive=None) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) module.run_transfer( @@ -18,3 +19,21 @@ def test_run_transfer_does_not_raise(): local_path=None, remote_path=None, ) + + +def test_run_transfer_with_archive_and_match_archives_raises(): + flexmock(module.logger).answer = lambda message: None + flexmock(module.borgmatic.borg.transfer).should_receive('transfer_archives') + transfer_arguments = flexmock(archive='foo') + global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) + + with pytest.raises(ValueError): + module.run_transfer( + repository={'path': 'repo'}, + config={'match_archives': 'foo*'}, + local_borg_version=None, + transfer_arguments=transfer_arguments, + global_arguments=global_arguments, + local_path=None, + remote_path=None, + ) diff --git a/tests/unit/borg/test_check.py b/tests/unit/borg/test_check.py index 80ce0d94..0a1f5361 100644 --- a/tests/unit/borg/test_check.py +++ b/tests/unit/borg/test_check.py @@ -155,22 +155,6 @@ def test_make_archive_filter_flags_with_data_check_and_prefix_includes_match_arc assert flags == ('--match-archives', 'sh:foo-*') -def test_make_archive_filter_flags_prefers_check_arguments_match_archives_to_config_match_archives(): - flexmock(module.feature).should_receive('available').and_return(True) - flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - 'baz-*', None, '1.2.3' - ).and_return(('--match-archives', 'sh:baz-*')) - - flags = module.make_archive_filter_flags( - '1.2.3', - {'match_archives': 'bar-{now}', 'prefix': ''}, # noqa: FS003 - ('archives',), - check_arguments=flexmock(match_archives='baz-*'), - ) - - assert flags == ('--match-archives', 'sh:baz-*') - - def test_make_archive_filter_flags_with_archives_check_and_empty_prefix_uses_archive_name_format_instead(): flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( @@ -331,42 +315,7 @@ def test_get_repository_id_with_missing_json_keys_raises(): ) -def test_check_archives_favors_progress_flag_over_config(): - config = {'progress': False} - flexmock(module).should_receive('make_check_name_flags').with_args( - {'repository'}, () - ).and_return(()) - flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) - flexmock(module.environment).should_receive('make_environment') - flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) - flexmock(module).should_receive('execute_command').with_args( - ('borg', 'check', '--progress', 'repo'), - output_file=module.DO_NOT_CAPTURE, - environment=None, - working_directory=None, - borg_local_path='borg', - borg_exit_codes=None, - ).once() - - module.check_archives( - repository_path='repo', - config=config, - local_borg_version='1.2.3', - check_arguments=flexmock( - progress=True, - repair=None, - only_checks=None, - force=None, - match_archives=None, - max_duration=None, - ), - global_arguments=flexmock(log_json=False), - checks={'repository'}, - archive_filter_flags=(), - ) - - -def test_check_archives_defaults_to_progress_config(): +def test_check_archives_with_progress_passes_through_to_borg(): config = {'progress': True} flexmock(module).should_receive('make_check_name_flags').with_args( {'repository'}, () diff --git a/tests/unit/borg/test_compact.py b/tests/unit/borg/test_compact.py index 882dac69..7fff7728 100644 --- a/tests/unit/borg/test_compact.py +++ b/tests/unit/borg/test_compact.py @@ -27,7 +27,7 @@ def insert_execute_command_mock( COMPACT_COMMAND = ('borg', 'compact') -def test_compact_segments_calls_borg_with_parameters(): +def test_compact_segments_calls_borg_with_flags(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock(COMPACT_COMMAND + ('repo',), logging.INFO) @@ -40,7 +40,7 @@ def test_compact_segments_calls_borg_with_parameters(): ) -def test_compact_segments_with_log_info_calls_borg_with_info_parameter(): +def test_compact_segments_with_log_info_calls_borg_with_info_flag(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock(COMPACT_COMMAND + ('--info', 'repo'), logging.INFO) insert_logging_mock(logging.INFO) @@ -54,7 +54,7 @@ def test_compact_segments_with_log_info_calls_borg_with_info_parameter(): ) -def test_compact_segments_with_log_debug_calls_borg_with_debug_parameter(): +def test_compact_segments_with_log_debug_calls_borg_with_debug_flag(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock(COMPACT_COMMAND + ('--debug', '--show-rc', 'repo'), logging.INFO) insert_logging_mock(logging.DEBUG) @@ -110,7 +110,7 @@ def test_compact_segments_with_exit_codes_calls_borg_using_them(): ) -def test_compact_segments_with_remote_path_calls_borg_with_remote_path_parameters(): +def test_compact_segments_with_remote_path_calls_borg_with_remote_path_flags(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock(COMPACT_COMMAND + ('--remote-path', 'borg1', 'repo'), logging.INFO) @@ -124,21 +124,20 @@ def test_compact_segments_with_remote_path_calls_borg_with_remote_path_parameter ) -def test_compact_segments_with_progress_calls_borg_with_progress_parameter(): +def test_compact_segments_with_progress_calls_borg_with_progress_flag(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock(COMPACT_COMMAND + ('--progress', 'repo'), logging.INFO) module.compact_segments( dry_run=False, repository_path='repo', - config={}, + config={'progress': True}, local_borg_version='1.2.3', global_arguments=flexmock(log_json=False), - progress=True, ) -def test_compact_segments_with_cleanup_commits_calls_borg_with_cleanup_commits_parameter(): +def test_compact_segments_with_cleanup_commits_calls_borg_with_cleanup_commits_flag(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock(COMPACT_COMMAND + ('--cleanup-commits', 'repo'), logging.INFO) @@ -152,21 +151,20 @@ def test_compact_segments_with_cleanup_commits_calls_borg_with_cleanup_commits_p ) -def test_compact_segments_with_threshold_calls_borg_with_threshold_parameter(): +def test_compact_segments_with_threshold_calls_borg_with_threshold_flag(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock(COMPACT_COMMAND + ('--threshold', '20', 'repo'), logging.INFO) module.compact_segments( dry_run=False, repository_path='repo', - config={}, + config={'compact_threshold': 20}, local_borg_version='1.2.3', global_arguments=flexmock(log_json=False), - threshold=20, ) -def test_compact_segments_with_umask_calls_borg_with_umask_parameters(): +def test_compact_segments_with_umask_calls_borg_with_umask_flags(): config = {'umask': '077'} flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock(COMPACT_COMMAND + ('--umask', '077', 'repo'), logging.INFO) @@ -180,7 +178,7 @@ def test_compact_segments_with_umask_calls_borg_with_umask_parameters(): ) -def test_compact_segments_with_log_json_calls_borg_with_log_json_parameters(): +def test_compact_segments_with_log_json_calls_borg_with_log_json_flags(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock(COMPACT_COMMAND + ('--log-json', 'repo'), logging.INFO) @@ -193,7 +191,7 @@ def test_compact_segments_with_log_json_calls_borg_with_log_json_parameters(): ) -def test_compact_segments_with_lock_wait_calls_borg_with_lock_wait_parameters(): +def test_compact_segments_with_lock_wait_calls_borg_with_lock_wait_flags(): config = {'lock_wait': 5} flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock(COMPACT_COMMAND + ('--lock-wait', '5', 'repo'), logging.INFO) diff --git a/tests/unit/borg/test_create.py b/tests/unit/borg/test_create.py index ad7c044e..80b80ee1 100644 --- a/tests/unit/borg/test_create.py +++ b/tests/unit/borg/test_create.py @@ -631,12 +631,12 @@ def test_make_base_create_command_includes_list_flags_in_borg_command(): config={ 'source_directories': ['foo', 'bar'], 'repositories': ['repo'], + 'list_details': True, }, patterns=[Pattern('foo'), Pattern('bar')], local_borg_version='1.2.3', global_arguments=flexmock(log_json=False), borgmatic_runtime_directory='/run/borgmatic', - list_files=True, ) assert create_flags == ('borg', 'create', '--list', '--filter', 'FOO') @@ -962,7 +962,7 @@ def test_make_base_create_command_with_non_existent_directory_and_source_directo ) -def test_create_archive_calls_borg_with_parameters(): +def test_create_archive_calls_borg_with_flags(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( @@ -1029,7 +1029,7 @@ def test_create_archive_calls_borg_with_environment(): ) -def test_create_archive_with_log_info_calls_borg_with_info_parameter(): +def test_create_archive_with_log_info_calls_borg_with_info_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( @@ -1096,7 +1096,7 @@ def test_create_archive_with_log_info_and_json_suppresses_most_borg_output(): ) -def test_create_archive_with_log_debug_calls_borg_with_debug_parameter(): +def test_create_archive_with_log_debug_calls_borg_with_debug_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( @@ -1196,7 +1196,6 @@ def test_create_archive_with_stats_and_dry_run_calls_borg_without_stats(): local_borg_version='1.2.3', global_arguments=flexmock(log_json=False), borgmatic_runtime_directory='/borgmatic/run', - stats=True, ) @@ -1271,7 +1270,7 @@ def test_create_archive_with_exit_codes_calls_borg_using_them(): ) -def test_create_archive_with_stats_calls_borg_with_stats_parameter_and_answer_output_log_level(): +def test_create_archive_with_stats_calls_borg_with_stats_flag_and_answer_output_log_level(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( @@ -1296,12 +1295,12 @@ def test_create_archive_with_stats_calls_borg_with_stats_parameter_and_answer_ou 'source_directories': ['foo', 'bar'], 'repositories': ['repo'], 'exclude_patterns': None, + 'statistics': True, }, patterns=[Pattern('foo'), Pattern('bar')], local_borg_version='1.2.3', global_arguments=flexmock(log_json=False), borgmatic_runtime_directory='/borgmatic/run', - stats=True, ) @@ -1334,16 +1333,16 @@ def test_create_archive_with_files_calls_borg_with_answer_output_log_level(): 'source_directories': ['foo', 'bar'], 'repositories': ['repo'], 'exclude_patterns': None, + 'list_details': True, }, patterns=[Pattern('foo'), Pattern('bar')], local_borg_version='1.2.3', global_arguments=flexmock(log_json=False), borgmatic_runtime_directory='/borgmatic/run', - list_files=True, ) -def test_create_archive_with_progress_and_log_info_calls_borg_with_progress_parameter_and_no_list(): +def test_create_archive_with_progress_and_log_info_calls_borg_with_progress_flag_and_no_list(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( @@ -1369,16 +1368,16 @@ def test_create_archive_with_progress_and_log_info_calls_borg_with_progress_para 'source_directories': ['foo', 'bar'], 'repositories': ['repo'], 'exclude_patterns': None, + 'progress': True, }, patterns=[Pattern('foo'), Pattern('bar')], local_borg_version='1.2.3', global_arguments=flexmock(log_json=False), borgmatic_runtime_directory='/borgmatic/run', - progress=True, ) -def test_create_archive_with_progress_calls_borg_with_progress_parameter(): +def test_create_archive_with_progress_calls_borg_with_progress_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( @@ -1403,16 +1402,16 @@ def test_create_archive_with_progress_calls_borg_with_progress_parameter(): 'source_directories': ['foo', 'bar'], 'repositories': ['repo'], 'exclude_patterns': None, + 'progress': True, }, patterns=[Pattern('foo'), Pattern('bar')], local_borg_version='1.2.3', global_arguments=flexmock(log_json=False), borgmatic_runtime_directory='/borgmatic/run', - progress=True, ) -def test_create_archive_with_progress_and_stream_processes_calls_borg_with_progress_parameter(): +def test_create_archive_with_progress_and_stream_processes_calls_borg_with_progress_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER processes = flexmock() @@ -1459,12 +1458,12 @@ def test_create_archive_with_progress_and_stream_processes_calls_borg_with_progr 'source_directories': ['foo', 'bar'], 'repositories': ['repo'], 'exclude_patterns': None, + 'progress': True, }, patterns=[Pattern('foo'), Pattern('bar')], local_borg_version='1.2.3', global_arguments=flexmock(log_json=False), borgmatic_runtime_directory='/borgmatic/run', - progress=True, stream_processes=processes, ) @@ -1532,7 +1531,6 @@ def test_create_archive_with_stats_and_json_calls_borg_without_stats_flag(): global_arguments=flexmock(log_json=False), borgmatic_runtime_directory='/borgmatic/run', json=True, - stats=True, ) assert json_output == '[]' diff --git a/tests/unit/borg/test_delete.py b/tests/unit/borg/test_delete.py index f6ace21d..770f411d 100644 --- a/tests/unit/borg/test_delete.py +++ b/tests/unit/borg/test_delete.py @@ -21,7 +21,7 @@ def test_make_delete_command_includes_log_info(): repository={'path': 'repo'}, config={}, local_borg_version='1.2.3', - delete_arguments=flexmock(list_archives=False, force=0, match_archives=None, archive=None), + delete_arguments=flexmock(list_details=False, force=0, match_archives=None, archive=None), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path=None, @@ -43,7 +43,7 @@ def test_make_delete_command_includes_log_debug(): repository={'path': 'repo'}, config={}, local_borg_version='1.2.3', - delete_arguments=flexmock(list_archives=False, force=0, match_archives=None, archive=None), + delete_arguments=flexmock(list_details=False, force=0, match_archives=None, archive=None), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path=None, @@ -67,7 +67,7 @@ def test_make_delete_command_includes_dry_run(): repository={'path': 'repo'}, config={}, local_borg_version='1.2.3', - delete_arguments=flexmock(list_archives=False, force=0, match_archives=None, archive=None), + delete_arguments=flexmock(list_details=False, force=0, match_archives=None, archive=None), global_arguments=flexmock(dry_run=True, log_json=False), local_path='borg', remote_path=None, @@ -91,7 +91,7 @@ def test_make_delete_command_includes_remote_path(): repository={'path': 'repo'}, config={}, local_borg_version='1.2.3', - delete_arguments=flexmock(list_archives=False, force=0, match_archives=None, archive=None), + delete_arguments=flexmock(list_details=False, force=0, match_archives=None, archive=None), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path='borg1', @@ -114,7 +114,7 @@ def test_make_delete_command_includes_umask(): repository={'path': 'repo'}, config={'umask': '077'}, local_borg_version='1.2.3', - delete_arguments=flexmock(list_archives=False, force=0, match_archives=None, archive=None), + delete_arguments=flexmock(list_details=False, force=0, match_archives=None, archive=None), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path=None, @@ -138,7 +138,7 @@ def test_make_delete_command_includes_log_json(): repository={'path': 'repo'}, config={}, local_borg_version='1.2.3', - delete_arguments=flexmock(list_archives=False, force=0, match_archives=None, archive=None), + delete_arguments=flexmock(list_details=False, force=0, match_archives=None, archive=None), global_arguments=flexmock(dry_run=False, log_json=True), local_path='borg', remote_path=None, @@ -162,7 +162,7 @@ def test_make_delete_command_includes_lock_wait(): repository={'path': 'repo'}, config={'lock_wait': 5}, local_borg_version='1.2.3', - delete_arguments=flexmock(list_archives=False, force=0, match_archives=None, archive=None), + delete_arguments=flexmock(list_details=False, force=0, match_archives=None, archive=None), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path=None, @@ -171,31 +171,7 @@ def test_make_delete_command_includes_lock_wait(): assert command == ('borg', 'delete', '--lock-wait', '5', 'repo') -def test_make_delete_command_favors_list_flag_over_config(): - flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) - flexmock(module.borgmatic.borg.flags).should_receive('make_flags').with_args( - 'list', True - ).and_return(('--list',)) - flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) - flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) - flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) - ) - - command = module.make_delete_command( - repository={'path': 'repo'}, - config={'list_details': False}, - local_borg_version='1.2.3', - delete_arguments=flexmock(list_archives=True, force=0, match_archives=None, archive=None), - global_arguments=flexmock(dry_run=False, log_json=False), - local_path='borg', - remote_path=None, - ) - - assert command == ('borg', 'delete', '--list', 'repo') - - -def test_make_delete_command_defaults_to_list_config(): +def test_make_delete_command_with_list_config_calls_borg_with_list_flag(): flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags').with_args( 'list', True @@ -210,7 +186,7 @@ def test_make_delete_command_defaults_to_list_config(): repository={'path': 'repo'}, config={'list_details': True}, local_borg_version='1.2.3', - delete_arguments=flexmock(list_archives=None, force=0, match_archives=None, archive=None), + delete_arguments=flexmock(list_details=None, force=0, match_archives=None, archive=None), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path=None, @@ -231,7 +207,7 @@ def test_make_delete_command_includes_force(): repository={'path': 'repo'}, config={}, local_borg_version='1.2.3', - delete_arguments=flexmock(list_archives=False, force=1, match_archives=None, archive=None), + delete_arguments=flexmock(list_details=False, force=1, match_archives=None, archive=None), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path=None, @@ -252,7 +228,7 @@ def test_make_delete_command_includes_force_twice(): repository={'path': 'repo'}, config={}, local_borg_version='1.2.3', - delete_arguments=flexmock(list_archives=False, force=2, match_archives=None, archive=None), + delete_arguments=flexmock(list_details=False, force=2, match_archives=None, archive=None), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path=None, @@ -276,7 +252,7 @@ def test_make_delete_command_includes_archive(): config={}, local_borg_version='1.2.3', delete_arguments=flexmock( - list_archives=False, force=0, match_archives=None, archive='archive' + list_details=False, force=0, match_archives=None, archive='archive' ), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', @@ -301,7 +277,7 @@ def test_make_delete_command_includes_match_archives(): config={}, local_borg_version='1.2.3', delete_arguments=flexmock( - list_archives=False, force=0, match_archives='sh:foo*', archive='archive' + list_details=False, force=0, match_archives='sh:foo*', archive='archive' ), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', @@ -390,7 +366,7 @@ def test_delete_archives_without_archive_related_argument_calls_borg_repo_delete config={}, local_borg_version=flexmock(), delete_arguments=flexmock( - list_archives=True, force=False, cache_only=False, keep_security_info=False + list_details=True, force=False, cache_only=False, keep_security_info=False ), global_arguments=flexmock(), ) diff --git a/tests/unit/borg/test_export_tar.py b/tests/unit/borg/test_export_tar.py index f45026f3..3fb50129 100644 --- a/tests/unit/borg/test_export_tar.py +++ b/tests/unit/borg/test_export_tar.py @@ -144,7 +144,7 @@ def test_export_tar_archive_calls_borg_with_umask_flags(): ) -def test_export_tar_archive_calls_borg_with_log_json_parameter(): +def test_export_tar_archive_calls_borg_with_log_json_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( @@ -186,7 +186,7 @@ def test_export_tar_archive_calls_borg_with_lock_wait_flags(): ) -def test_export_tar_archive_with_log_info_calls_borg_with_info_parameter(): +def test_export_tar_archive_with_log_info_calls_borg_with_info_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( @@ -230,7 +230,7 @@ def test_export_tar_archive_with_log_debug_calls_borg_with_debug_flags(): ) -def test_export_tar_archive_calls_borg_with_dry_run_parameter(): +def test_export_tar_archive_calls_borg_with_dry_run_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( @@ -273,7 +273,7 @@ def test_export_tar_archive_calls_borg_with_tar_filter_flags(): ) -def test_export_tar_archive_calls_borg_with_list_parameter(): +def test_export_tar_archive_calls_borg_with_list_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( @@ -290,14 +290,13 @@ def test_export_tar_archive_calls_borg_with_list_parameter(): archive='archive', paths=None, destination_path='test.tar', - config={}, + config={'list_details': True}, local_borg_version='1.2.3', global_arguments=flexmock(log_json=False), - list_files=True, ) -def test_export_tar_archive_calls_borg_with_strip_components_parameter(): +def test_export_tar_archive_calls_borg_with_strip_components_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( @@ -320,7 +319,7 @@ def test_export_tar_archive_calls_borg_with_strip_components_parameter(): ) -def test_export_tar_archive_skips_abspath_for_remote_repository_parameter(): +def test_export_tar_archive_skips_abspath_for_remote_repository_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( diff --git a/tests/unit/borg/test_extract.py b/tests/unit/borg/test_extract.py index de392f24..a11155f8 100644 --- a/tests/unit/borg/test_extract.py +++ b/tests/unit/borg/test_extract.py @@ -580,7 +580,7 @@ def test_extract_archive_with_strip_components_all_and_no_paths_raises(): ) -def test_extract_archive_calls_borg_with_progress_parameter(): +def test_extract_archive_calls_borg_with_progress_flag(): flexmock(module.os.path).should_receive('abspath').and_return('repo') flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -606,10 +606,9 @@ def test_extract_archive_calls_borg_with_progress_parameter(): repository='repo', archive='archive', paths=None, - config={}, + config={'progress': True}, local_borg_version='1.2.3', global_arguments=flexmock(log_json=False), - progress=True, ) @@ -622,10 +621,9 @@ def test_extract_archive_with_progress_and_extract_to_stdout_raises(): repository='repo', archive='archive', paths=None, - config={}, + config={'progress': True}, local_borg_version='1.2.3', global_arguments=flexmock(log_json=False), - progress=True, extract_to_stdout=True, ) diff --git a/tests/unit/borg/test_info.py b/tests/unit/borg/test_info.py index 5866b4ab..23f416bb 100644 --- a/tests/unit/borg/test_info.py +++ b/tests/unit/borg/test_info.py @@ -380,7 +380,7 @@ def test_make_info_command_with_match_archives_flag_passes_through_to_command(): command = module.make_info_command( repository_path='repo', - config={'archive_name_format': 'bar-{now}'}, # noqa: FS003 + config={'archive_name_format': 'bar-{now}', 'match_archives': 'sh:foo-*'}, # noqa: FS003 local_borg_version='2.3.4', global_arguments=flexmock(log_json=False), info_arguments=flexmock(archive=None, json=False, prefix=None, match_archives='sh:foo-*'), diff --git a/tests/unit/borg/test_prune.py b/tests/unit/borg/test_prune.py index 1d7888a3..10e8ebf9 100644 --- a/tests/unit/borg/test_prune.py +++ b/tests/unit/borg/test_prune.py @@ -135,32 +135,6 @@ def test_make_prune_flags_without_prefix_uses_archive_name_format_instead(): assert result == expected -def test_make_prune_flags_without_prefix_uses_match_archives_flag_instead_of_option(): - config = { - 'archive_name_format': 'bar-{now}', # noqa: FS003 - 'match_archives': 'foo*', - 'keep_daily': 1, - 'prefix': None, - } - flexmock(module.feature).should_receive('available').and_return(True) - flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - 'baz*', 'bar-{now}', '1.2.3' # noqa: FS003 - ).and_return(('--match-archives', 'sh:bar-*')).once() - - result = module.make_prune_flags( - config, flexmock(match_archives='baz*'), local_borg_version='1.2.3' - ) - - expected = ( - '--keep-daily', - '1', - '--match-archives', - 'sh:bar-*', # noqa: FS003 - ) - - assert result == expected - - def test_make_prune_flags_without_prefix_uses_match_archives_option(): config = { 'archive_name_format': 'bar-{now}', # noqa: FS003 @@ -215,7 +189,7 @@ def test_prune_archives_calls_borg_with_flags(): ).and_return(False) insert_execute_command_mock(PRUNE_COMMAND + ('repo',), logging.INFO) - prune_arguments = flexmock(stats=False, list_archives=False) + prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( dry_run=False, repository_path='repo', @@ -237,7 +211,7 @@ def test_prune_archives_with_log_info_calls_borg_with_info_flag(): insert_execute_command_mock(PRUNE_COMMAND + ('--info', 'repo'), logging.INFO) insert_logging_mock(logging.INFO) - prune_arguments = flexmock(stats=False, list_archives=False) + prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( repository_path='repo', config={}, @@ -259,7 +233,7 @@ def test_prune_archives_with_log_debug_calls_borg_with_debug_flag(): insert_execute_command_mock(PRUNE_COMMAND + ('--debug', '--show-rc', 'repo'), logging.INFO) insert_logging_mock(logging.DEBUG) - prune_arguments = flexmock(stats=False, list_archives=False) + prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( repository_path='repo', config={}, @@ -280,7 +254,7 @@ def test_prune_archives_with_dry_run_calls_borg_with_dry_run_flag(): ).and_return(False) insert_execute_command_mock(PRUNE_COMMAND + ('--dry-run', 'repo'), logging.INFO) - prune_arguments = flexmock(stats=False, list_archives=False) + prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( repository_path='repo', config={}, @@ -301,7 +275,7 @@ def test_prune_archives_with_local_path_calls_borg_via_local_path(): ).and_return(False) insert_execute_command_mock(('borg1',) + PRUNE_COMMAND[1:] + ('repo',), logging.INFO) - prune_arguments = flexmock(stats=False, list_archives=False) + prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( dry_run=False, repository_path='repo', @@ -328,7 +302,7 @@ def test_prune_archives_with_exit_codes_calls_borg_using_them(): borg_exit_codes=borg_exit_codes, ) - prune_arguments = flexmock(stats=False, list_archives=False) + prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( dry_run=False, repository_path='repo', @@ -349,7 +323,7 @@ def test_prune_archives_with_remote_path_calls_borg_with_remote_path_flags(): ).and_return(False) insert_execute_command_mock(PRUNE_COMMAND + ('--remote-path', 'borg1', 'repo'), logging.INFO) - prune_arguments = flexmock(stats=False, list_archives=False) + prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( dry_run=False, repository_path='repo', @@ -361,7 +335,7 @@ def test_prune_archives_with_remote_path_calls_borg_with_remote_path_flags(): ) -def test_prune_archives_favors_stats_flag_over_config(): +def test_prune_archives_with_stats_config_calls_borg_with_stats_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) @@ -371,28 +345,7 @@ def test_prune_archives_favors_stats_flag_over_config(): ).and_return(False) insert_execute_command_mock(PRUNE_COMMAND + ('--stats', 'repo'), module.borgmatic.logger.ANSWER) - prune_arguments = flexmock(stats=True, list_archives=False) - module.prune_archives( - dry_run=False, - repository_path='repo', - config={'statistics': False}, - local_borg_version='1.2.3', - global_arguments=flexmock(log_json=False), - prune_arguments=prune_arguments, - ) - - -def test_prune_archives_defaults_to_stats_config(): - flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') - flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER - flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) - flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) - flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '1.2.3' - ).and_return(False) - insert_execute_command_mock(PRUNE_COMMAND + ('--stats', 'repo'), module.borgmatic.logger.ANSWER) - - prune_arguments = flexmock(stats=None, list_archives=False) + prune_arguments = flexmock(statistics=None, list_details=False) module.prune_archives( dry_run=False, repository_path='repo', @@ -403,7 +356,7 @@ def test_prune_archives_defaults_to_stats_config(): ) -def test_prune_archives_favors_list_flag_over_config(): +def test_prune_archives_with_list_config_calls_borg_with_list_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) @@ -413,28 +366,7 @@ def test_prune_archives_favors_list_flag_over_config(): ).and_return(False) insert_execute_command_mock(PRUNE_COMMAND + ('--list', 'repo'), module.borgmatic.logger.ANSWER) - prune_arguments = flexmock(stats=False, list_archives=True) - module.prune_archives( - dry_run=False, - repository_path='repo', - config={'list_details': False}, - local_borg_version='1.2.3', - global_arguments=flexmock(log_json=False), - prune_arguments=prune_arguments, - ) - - -def test_prune_archives_defaults_to_list_config(): - flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') - flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER - flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) - flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) - flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '1.2.3' - ).and_return(False) - insert_execute_command_mock(PRUNE_COMMAND + ('--list', 'repo'), module.borgmatic.logger.ANSWER) - - prune_arguments = flexmock(stats=False, list_archives=None) + prune_arguments = flexmock(statistics=False, list_details=None) module.prune_archives( dry_run=False, repository_path='repo', @@ -456,7 +388,7 @@ def test_prune_archives_with_umask_calls_borg_with_umask_flags(): ).and_return(False) insert_execute_command_mock(PRUNE_COMMAND + ('--umask', '077', 'repo'), logging.INFO) - prune_arguments = flexmock(stats=False, list_archives=False) + prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( dry_run=False, repository_path='repo', @@ -477,7 +409,7 @@ def test_prune_archives_with_log_json_calls_borg_with_log_json_flag(): ).and_return(False) insert_execute_command_mock(PRUNE_COMMAND + ('--log-json', 'repo'), logging.INFO) - prune_arguments = flexmock(stats=False, list_archives=False) + prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( dry_run=False, repository_path='repo', @@ -499,7 +431,7 @@ def test_prune_archives_with_lock_wait_calls_borg_with_lock_wait_flags(): ).and_return(False) insert_execute_command_mock(PRUNE_COMMAND + ('--lock-wait', '5', 'repo'), logging.INFO) - prune_arguments = flexmock(stats=False, list_archives=False) + prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( dry_run=False, repository_path='repo', @@ -520,7 +452,7 @@ def test_prune_archives_with_extra_borg_options_calls_borg_with_extra_options(): ).and_return(False) insert_execute_command_mock(PRUNE_COMMAND + ('--extra', '--options', 'repo'), logging.INFO) - prune_arguments = flexmock(stats=False, list_archives=False) + prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( dry_run=False, repository_path='repo', @@ -588,7 +520,7 @@ def test_prune_archives_with_date_based_matching_calls_borg_with_date_based_flag ) prune_arguments = flexmock( - stats=False, list_archives=False, newer='1d', newest='1y', older='1m', oldest='1w' + statistics=False, list_details=False, newer='1d', newest='1y', older='1m', oldest='1w' ) module.prune_archives( dry_run=False, @@ -612,7 +544,7 @@ def test_prune_archives_calls_borg_with_working_directory(): PRUNE_COMMAND + ('repo',), logging.INFO, working_directory='/working/dir' ) - prune_arguments = flexmock(stats=False, list_archives=False) + prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( dry_run=False, repository_path='repo', @@ -623,7 +555,7 @@ def test_prune_archives_calls_borg_with_working_directory(): ) -def test_prune_archives_calls_borg_with_flags_and_when_feature_available(): +def test_prune_archives_calls_borg_without_stats_when_feature_is_not_available(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) @@ -633,11 +565,11 @@ def test_prune_archives_calls_borg_with_flags_and_when_feature_available(): ).and_return(True) insert_execute_command_mock(PRUNE_COMMAND + ('repo',), logging.ANSWER) - prune_arguments = flexmock(stats=True, list_archives=False) + prune_arguments = flexmock(statistics=True, list_details=False) module.prune_archives( dry_run=False, repository_path='repo', - config={}, + config={'statistics': True}, local_borg_version='2.0.0b10', global_arguments=flexmock(log_json=False), prune_arguments=prune_arguments, diff --git a/tests/unit/borg/test_recreate.py b/tests/unit/borg/test_recreate.py index dd91218d..c1f135b2 100644 --- a/tests/unit/borg/test_recreate.py +++ b/tests/unit/borg/test_recreate.py @@ -225,37 +225,7 @@ def test_recreate_with_log_json(): ) -def test_recreate_archive_favors_list_flag_over_config(): - flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(()) - flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None) - flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) - flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' - ).and_return(('repo::archive',)) - flexmock(module).should_receive('make_list_filter_flags').and_return('AME+-') - insert_execute_command_mock( - ('borg', 'recreate', '--list', '--filter', 'AME+-', 'repo::archive') - ) - - module.recreate_archive( - repository='repo', - archive='archive', - config={'list_details': False}, - local_borg_version='1.2.3', - recreate_arguments=flexmock( - list=True, - target=None, - comment=None, - timestamp=None, - match_archives=None, - ), - global_arguments=flexmock(dry_run=False, log_json=False), - local_path='borg', - patterns=None, - ) - - -def test_recreate_archive_defaults_to_list_config(): +def test_recreate_with_list_config_calls_borg_with_list_flag(): flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(()) flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) diff --git a/tests/unit/borg/test_repo_delete.py b/tests/unit/borg/test_repo_delete.py index 66e73778..4af66085 100644 --- a/tests/unit/borg/test_repo_delete.py +++ b/tests/unit/borg/test_repo_delete.py @@ -19,7 +19,7 @@ def test_make_repo_delete_command_with_feature_available_runs_borg_repo_delete() repository={'path': 'repo'}, config={}, local_borg_version='1.2.3', - repo_delete_arguments=flexmock(list_archives=False, force=0), + repo_delete_arguments=flexmock(list_details=False, force=0), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path=None, @@ -40,7 +40,7 @@ def test_make_repo_delete_command_without_feature_available_runs_borg_delete(): repository={'path': 'repo'}, config={}, local_borg_version='1.2.3', - repo_delete_arguments=flexmock(list_archives=False, force=0), + repo_delete_arguments=flexmock(list_details=False, force=0), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path=None, @@ -62,7 +62,7 @@ def test_make_repo_delete_command_includes_log_info(): repository={'path': 'repo'}, config={}, local_borg_version='1.2.3', - repo_delete_arguments=flexmock(list_archives=False, force=0), + repo_delete_arguments=flexmock(list_details=False, force=0), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path=None, @@ -84,7 +84,7 @@ def test_make_repo_delete_command_includes_log_debug(): repository={'path': 'repo'}, config={}, local_borg_version='1.2.3', - repo_delete_arguments=flexmock(list_archives=False, force=0), + repo_delete_arguments=flexmock(list_details=False, force=0), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path=None, @@ -108,7 +108,7 @@ def test_make_repo_delete_command_includes_dry_run(): repository={'path': 'repo'}, config={}, local_borg_version='1.2.3', - repo_delete_arguments=flexmock(list_archives=False, force=0), + repo_delete_arguments=flexmock(list_details=False, force=0), global_arguments=flexmock(dry_run=True, log_json=False), local_path='borg', remote_path=None, @@ -132,7 +132,7 @@ def test_make_repo_delete_command_includes_remote_path(): repository={'path': 'repo'}, config={}, local_borg_version='1.2.3', - repo_delete_arguments=flexmock(list_archives=False, force=0), + repo_delete_arguments=flexmock(list_details=False, force=0), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path='borg1', @@ -155,7 +155,7 @@ def test_make_repo_delete_command_includes_umask(): repository={'path': 'repo'}, config={'umask': '077'}, local_borg_version='1.2.3', - repo_delete_arguments=flexmock(list_archives=False, force=0), + repo_delete_arguments=flexmock(list_details=False, force=0), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path=None, @@ -179,7 +179,7 @@ def test_make_repo_delete_command_includes_log_json(): repository={'path': 'repo'}, config={}, local_borg_version='1.2.3', - repo_delete_arguments=flexmock(list_archives=False, force=0), + repo_delete_arguments=flexmock(list_details=False, force=0), global_arguments=flexmock(dry_run=False, log_json=True), local_path='borg', remote_path=None, @@ -203,7 +203,7 @@ def test_make_repo_delete_command_includes_lock_wait(): repository={'path': 'repo'}, config={'lock_wait': 5}, local_borg_version='1.2.3', - repo_delete_arguments=flexmock(list_archives=False, force=0), + repo_delete_arguments=flexmock(list_details=False, force=0), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path=None, @@ -225,9 +225,9 @@ def test_make_repo_delete_command_includes_list(): command = module.make_repo_delete_command( repository={'path': 'repo'}, - config={}, + config={'list_details': True}, local_borg_version='1.2.3', - repo_delete_arguments=flexmock(list_archives=True, force=0), + repo_delete_arguments=flexmock(list_details=True, force=0), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path=None, @@ -248,7 +248,7 @@ def test_make_repo_delete_command_includes_force(): repository={'path': 'repo'}, config={}, local_borg_version='1.2.3', - repo_delete_arguments=flexmock(list_archives=False, force=1), + repo_delete_arguments=flexmock(list_details=False, force=1), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path=None, @@ -269,7 +269,7 @@ def test_make_repo_delete_command_includes_force_twice(): repository={'path': 'repo'}, config={}, local_borg_version='1.2.3', - repo_delete_arguments=flexmock(list_archives=False, force=2), + repo_delete_arguments=flexmock(list_details=False, force=2), global_arguments=flexmock(dry_run=False, log_json=False), local_path='borg', remote_path=None, diff --git a/tests/unit/borg/test_repo_list.py b/tests/unit/borg/test_repo_list.py index da750d7a..73f567f5 100644 --- a/tests/unit/borg/test_repo_list.py +++ b/tests/unit/borg/test_repo_list.py @@ -664,7 +664,7 @@ def test_make_repo_list_command_with_match_archives_calls_borg_with_match_archiv command = module.make_repo_list_command( repository_path='repo', - config={}, + config={'match_archives': 'foo-*'}, local_borg_version='1.2.3', repo_list_arguments=flexmock( archive=None, diff --git a/tests/unit/borg/test_transfer.py b/tests/unit/borg/test_transfer.py index 9e6618e5..ced41f3c 100644 --- a/tests/unit/borg/test_transfer.py +++ b/tests/unit/borg/test_transfer.py @@ -193,7 +193,7 @@ def test_transfer_archives_with_match_archives_calls_borg_with_match_archives_fl module.transfer_archives( dry_run=False, repository_path='repo', - config={'archive_name_format': 'bar-{now}'}, # noqa: FS003 + config={'archive_name_format': 'bar-{now}', 'match_archives': 'sh:foo*'}, # noqa: FS003 local_borg_version='2.3.4', transfer_arguments=flexmock( archive=None, progress=None, match_archives='sh:foo*', source_repository=None @@ -436,38 +436,7 @@ def test_transfer_archives_with_lock_wait_calls_borg_with_lock_wait_flags(): ) -def test_transfer_archives_favors_progress_flag_over_config(): - 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').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.environment).should_receive('make_environment') - flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) - flexmock(module).should_receive('execute_command').with_args( - ('borg', 'transfer', '--progress', '--repo', 'repo'), - output_log_level=module.borgmatic.logger.ANSWER, - output_file=module.DO_NOT_CAPTURE, - environment=None, - working_directory=None, - borg_local_path='borg', - borg_exit_codes=None, - ) - - module.transfer_archives( - dry_run=False, - repository_path='repo', - config={'progress': False}, - local_borg_version='2.3.4', - transfer_arguments=flexmock( - archive=None, progress=True, match_archives=None, source_repository=None - ), - global_arguments=flexmock(log_json=False), - ) - - -def test_transfer_archives_defaults_to_progress_flag(): +def test_transfer_archives_with_progress_calls_borg_with_progress_flags(): 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(()) diff --git a/tests/unit/commands/test_borgmatic.py b/tests/unit/commands/test_borgmatic.py index 18793f19..57f3cf67 100644 --- a/tests/unit/commands/test_borgmatic.py +++ b/tests/unit/commands/test_borgmatic.py @@ -1578,7 +1578,7 @@ def test_load_configurations_collects_parsed_configurations_and_logs(resolve_env configs, config_paths, logs = tuple( module.load_configurations( ('test.yaml', 'other.yaml'), - global_arguments=flexmock(), + arguments=flexmock(), resolve_env=resolve_env, ) ) @@ -1592,7 +1592,7 @@ def test_load_configurations_logs_warning_for_permission_error(): flexmock(module.validate).should_receive('parse_configuration').and_raise(PermissionError) configs, config_paths, logs = tuple( - module.load_configurations(('test.yaml',), global_arguments=flexmock()) + module.load_configurations(('test.yaml',), arguments=flexmock()) ) assert configs == {} @@ -1604,7 +1604,7 @@ def test_load_configurations_logs_critical_for_parse_error(): flexmock(module.validate).should_receive('parse_configuration').and_raise(ValueError) configs, config_paths, logs = tuple( - module.load_configurations(('test.yaml',), global_arguments=flexmock()) + module.load_configurations(('test.yaml',), arguments=flexmock()) ) assert configs == {} diff --git a/tests/unit/config/test_arguments.py b/tests/unit/config/test_arguments.py index 18ad7f56..2c07f815 100644 --- a/tests/unit/config/test_arguments.py +++ b/tests/unit/config/test_arguments.py @@ -189,3 +189,15 @@ def test_prepare_arguments_for_config_skips_option_missing_from_schema(): }, }, ) == ((('other_option',), 'value2'),) + + +def test_apply_arguments_to_config_does_not_raise(): + flexmock(module).should_receive('prepare_arguments_for_config').and_return( + ( + (('foo', 'bar'), 'baz'), + (('one', 'two'), 'three'), + ) + ) + flexmock(module).should_receive('set_values') + + module.apply_arguments_to_config(config={}, schema={}, arguments={'global': flexmock()})