瀏覽代碼

Fix broken list_details, progress, and statistics options (#303).

Dan Helfman 2 月之前
父節點
當前提交
cf477bdc1c
共有 47 個文件被更改,包括 336 次插入718 次删除
  1. 1 2
      borgmatic/actions/check.py
  2. 0 10
      borgmatic/actions/compact.py
  3. 0 1
      borgmatic/actions/config/bootstrap.py
  4. 10 15
      borgmatic/actions/create.py
  5. 0 5
      borgmatic/actions/export_tar.py
  6. 0 5
      borgmatic/actions/extract.py
  7. 6 0
      borgmatic/actions/transfer.py
  8. 5 6
      borgmatic/borg/check.py
  9. 2 3
      borgmatic/borg/compact.py
  10. 5 12
      borgmatic/borg/create.py
  11. 11 10
      borgmatic/borg/delete.py
  12. 2 3
      borgmatic/borg/export_tar.py
  13. 4 5
      borgmatic/borg/extract.py
  14. 1 3
      borgmatic/borg/info.py
  15. 5 11
      borgmatic/borg/prune.py
  16. 2 7
      borgmatic/borg/recreate.py
  17. 2 2
      borgmatic/borg/repo_delete.py
  18. 1 1
      borgmatic/borg/repo_list.py
  19. 2 9
      borgmatic/borg/transfer.py
  20. 39 40
      borgmatic/commands/arguments.py
  21. 9 9
      borgmatic/commands/borgmatic.py
  22. 7 6
      borgmatic/config/arguments.py
  23. 6 6
      borgmatic/config/validate.py
  24. 4 34
      tests/integration/commands/test_arguments.py
  25. 13 11
      tests/integration/config/test_validate.py
  26. 0 3
      tests/unit/actions/config/test_bootstrap.py
  27. 1 6
      tests/unit/actions/test_check.py
  28. 11 80
      tests/unit/actions/test_compact.py
  29. 54 100
      tests/unit/actions/test_create.py
  30. 3 5
      tests/unit/actions/test_export_tar.py
  31. 0 2
      tests/unit/actions/test_extract.py
  32. 7 3
      tests/unit/actions/test_prune.py
  33. 20 1
      tests/unit/actions/test_transfer.py
  34. 1 52
      tests/unit/borg/test_check.py
  35. 12 14
      tests/unit/borg/test_compact.py
  36. 13 15
      tests/unit/borg/test_create.py
  37. 14 38
      tests/unit/borg/test_delete.py
  38. 7 8
      tests/unit/borg/test_export_tar.py
  39. 3 5
      tests/unit/borg/test_extract.py
  40. 1 1
      tests/unit/borg/test_info.py
  41. 20 88
      tests/unit/borg/test_prune.py
  42. 1 31
      tests/unit/borg/test_recreate.py
  43. 13 13
      tests/unit/borg/test_repo_delete.py
  44. 1 1
      tests/unit/borg/test_repo_list.py
  45. 2 33
      tests/unit/borg/test_transfer.py
  46. 3 3
      tests/unit/commands/test_borgmatic.py
  47. 12 0
      tests/unit/config/test_arguments.py

+ 1 - 2
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,
         )
     )

+ 0 - 10
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+)')

+ 0 - 1
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,
     )

+ 10 - 15
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,
         )
 

+ 0 - 5
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,
         )

+ 0 - 5
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
-            ),
         )

+ 6 - 0
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'],

+ 5 - 6
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,

+ 2 - 3
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 ())

+ 5 - 12
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')

+ 11 - 10
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,

+ 2 - 3
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

+ 4 - 5
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,

+ 1 - 3
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,
                 )

+ 5 - 11
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

+ 2 - 7
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

+ 2 - 2
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)
     )

+ 1 - 1
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,
                 )

+ 2 - 9
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,

+ 39 - 40
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.'

+ 9 - 9
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,
     )

+ 7 - 6
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)

+ 6 - 6
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 {})
 

+ 4 - 34
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'])
 

+ 13 - 11
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 == {

+ 0 - 3
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()

+ 1 - 6
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(

+ 11 - 80
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)
 
@@ -33,93 +36,18 @@ def test_compact_runs_with_selected_repository():
     ).once().and_return(True)
     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()
-    )
-    global_arguments = flexmock(monitoring_verbosity=1, dry_run=False)
-
-    module.run_compact(
-        config_filename='test.yaml',
-        repository={'path': 'repo'},
-        config={},
-        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_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,
+        progress=flexmock(),
         cleanup_commits=flexmock(),
-        threshold=15,
+        compact_threshold=flexmock(),
     )
     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},
+        config={},
         local_borg_version=None,
         compact_arguments=compact_arguments,
         global_arguments=global_arguments,
@@ -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)
 

+ 54 - 100
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,51 +506,27 @@ def test_run_create_runs_with_selected_repository():
     )
 
 
-def test_run_create_favors_flags_over_config():
+def test_run_create_bails_if_repository_does_not_match():
     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')
+    ).once().and_return(False)
+    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=False,
-        stats=False,
+        progress=flexmock(),
+        statistics=flexmock(),
         json=False,
-        list_files=False,
+        list_details=flexmock(),
     )
     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},
+            repository='repo',
+            config={},
             config_paths=['/tmp/test.yaml'],
             local_borg_version=None,
             create_arguments=create_arguments,
@@ -562,92 +538,70 @@ def test_run_create_favors_flags_over_config():
     )
 
 
-def test_run_create_defaults_to_config():
+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').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')
+    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=True,
-        stats=True,
-        json=False,
-        list_files=True,
+        progress=flexmock(),
+        statistics=flexmock(),
+        json=True,
+        list_details=flexmock(),
     )
     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,
+    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_bails_if_repository_does_not_match():
+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(False)
+    ).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(),
-        stats=flexmock(),
+        statistics=flexmock(),
         json=False,
-        list_files=flexmock(),
+        list_details=flexmock(),
     )
     global_arguments = flexmock(monitoring_verbosity=1, dry_run=False)
 
-    list(
-        module.run_create(
-            config_filename='test.yaml',
-            repository='repo',
-            config={},
-            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,
+    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():
@@ -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)
 

+ 3 - 5
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)

+ 0 - 2
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(),

+ 7 - 3
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(

+ 20 - 1
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,
+        )

+ 1 - 52
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'}, ()

+ 12 - 14
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)

+ 13 - 15
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 == '[]'

+ 14 - 38
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(),
     )

+ 7 - 8
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(

+ 3 - 5
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,
         )
 

+ 1 - 1
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-*'),

+ 20 - 88
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,28 +356,7 @@ def test_prune_archives_defaults_to_stats_config():
     )
 
 
-def test_prune_archives_favors_list_flag_over_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=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():
+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)
@@ -434,7 +366,7 @@ def test_prune_archives_defaults_to_list_config():
     ).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,

+ 1 - 31
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(())

+ 13 - 13
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,

+ 1 - 1
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,

+ 2 - 33
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(())

+ 3 - 3
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 == {}

+ 12 - 0
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()})