From d93fdbc5ad79eb9ebb6bcba38ca484603dcbe70f Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Wed, 22 Jan 2020 13:28:24 -0800 Subject: [PATCH] Support "--files" and "--stats" flags at verbosity level 0. --- NEWS | 5 +- borgmatic/borg/create.py | 2 + borgmatic/borg/prune.py | 7 ++- borgmatic/commands/arguments.py | 12 +---- tests/unit/borg/test_create.py | 84 ++++++++++++++++++++++++++++++++- tests/unit/borg/test_prune.py | 54 ++++++++++++++++++++- 6 files changed, 146 insertions(+), 18 deletions(-) diff --git a/NEWS b/NEWS index 25df1b7..dca9bd7 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,7 @@ 1.4.23.dev0 * #274: Add ~/.config/borgmatic.d as another configuration directory default. - * Removed `borg --list --stats` option from `create`and `prune` actions at verbosity 1 - * The `--stats` now always requires to use the `borgmatic --stats` option to be enabled. - * New option `--files` to (re-)add the `borg` `--list` at verbosity 1 + * For "create" and "prune" actions, no longer list files or show detailed stats at verbosity 1. You + can opt back in with "--files" or "--stats" flags. 1.4.22 * #276, #285: Disable colored output when "--json" flag is used, so as to produce valid JSON ouput. diff --git a/borgmatic/borg/create.py b/borgmatic/borg/create.py index dd383ca..5258e9d 100644 --- a/borgmatic/borg/create.py +++ b/borgmatic/borg/create.py @@ -208,6 +208,8 @@ def create_archive( if json: output_log_level = None + elif (stats or files) and logger.getEffectiveLevel() == logging.WARNING: + output_log_level = logging.WARNING else: output_log_level = logging.INFO diff --git a/borgmatic/borg/prune.py b/borgmatic/borg/prune.py index d68a12d..492ff9b 100644 --- a/borgmatic/borg/prune.py +++ b/borgmatic/borg/prune.py @@ -67,4 +67,9 @@ def prune_archives( + (repository,) ) - execute_command(full_command, output_log_level=logging.INFO, error_on_warnings=False) + if (stats or files) and logger.getEffectiveLevel() == logging.WARNING: + output_log_level = logging.WARNING + else: + output_log_level = logging.INFO + + execute_command(full_command, output_log_level=output_log_level, error_on_warnings=False) diff --git a/borgmatic/commands/arguments.py b/borgmatic/commands/arguments.py index 76f25a6..61b9cfc 100644 --- a/borgmatic/commands/arguments.py +++ b/borgmatic/commands/arguments.py @@ -238,11 +238,7 @@ def parse_arguments(*unparsed_arguments): help='Display statistics of archive', ) prune_group.add_argument( - '--files', - dest='files', - default=False, - action='store_true', - help='Show file details and stats at verbosity 1', + '--files', dest='files', default=False, action='store_true', help='Show per-file details' ) prune_group.add_argument('-h', '--help', action='help', help='Show this help message and exit') @@ -269,11 +265,7 @@ def parse_arguments(*unparsed_arguments): help='Display statistics of archive', ) create_group.add_argument( - '--files', - dest='files', - default=False, - action='store_true', - help='Show file details and stats at verbosity 1', + '--files', dest='files', default=False, 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' diff --git a/tests/unit/borg/test_create.py b/tests/unit/borg/test_create.py index 4b74df7..79cdfca 100644 --- a/tests/unit/borg/test_create.py +++ b/tests/unit/borg/test_create.py @@ -840,7 +840,7 @@ def test_create_archive_with_lock_wait_calls_borg_with_lock_wait_parameters(): ) -def test_create_archive_with_stats_calls_borg_with_stats_parameter(): +def test_create_archive_with_stats_calls_borg_with_stats_parameter_and_warning_output_log_level(): flexmock(module).should_receive('borgmatic_source_directories').and_return([]) flexmock(module).should_receive('_expand_directories').and_return(('foo', 'bar')) flexmock(module).should_receive('_expand_home_directories').and_return(()) @@ -849,7 +849,7 @@ def test_create_archive_with_stats_calls_borg_with_stats_parameter(): flexmock(module).should_receive('_make_exclude_flags').and_return(()) flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--stats') + ARCHIVE_WITH_PATHS, - output_log_level=logging.INFO, + output_log_level=logging.WARNING, error_on_warnings=False, ) @@ -866,6 +866,86 @@ def test_create_archive_with_stats_calls_borg_with_stats_parameter(): ) +def test_create_archive_with_stats_and_log_info_calls_borg_with_stats_parameter_and_info_output_log_level(): + flexmock(module).should_receive('borgmatic_source_directories').and_return([]) + flexmock(module).should_receive('_expand_directories').and_return(('foo', 'bar')) + flexmock(module).should_receive('_expand_home_directories').and_return(()) + flexmock(module).should_receive('_write_pattern_file').and_return(None) + flexmock(module).should_receive('_make_pattern_flags').and_return(()) + flexmock(module).should_receive('_make_exclude_flags').and_return(()) + flexmock(module).should_receive('execute_command').with_args( + ('borg', 'create', '--info', '--stats') + ARCHIVE_WITH_PATHS, + output_log_level=logging.INFO, + error_on_warnings=False, + ) + insert_logging_mock(logging.INFO) + + module.create_archive( + dry_run=False, + repository='repo', + location_config={ + 'source_directories': ['foo', 'bar'], + 'repositories': ['repo'], + 'exclude_patterns': None, + }, + storage_config={}, + stats=True, + ) + + +def test_create_archive_with_files_calls_borg_with_list_parameter_and_warning_output_log_level(): + flexmock(module).should_receive('borgmatic_source_directories').and_return([]) + flexmock(module).should_receive('_expand_directories').and_return(('foo', 'bar')) + flexmock(module).should_receive('_expand_home_directories').and_return(()) + flexmock(module).should_receive('_write_pattern_file').and_return(None) + flexmock(module).should_receive('_make_pattern_flags').and_return(()) + flexmock(module).should_receive('_make_exclude_flags').and_return(()) + flexmock(module).should_receive('execute_command').with_args( + ('borg', 'create', '--list', '--filter', 'AME-') + ARCHIVE_WITH_PATHS, + output_log_level=logging.WARNING, + error_on_warnings=False, + ) + + module.create_archive( + dry_run=False, + repository='repo', + location_config={ + 'source_directories': ['foo', 'bar'], + 'repositories': ['repo'], + 'exclude_patterns': None, + }, + storage_config={}, + files=True, + ) + + +def test_create_archive_with_files_and_log_info_calls_borg_with_list_parameter_and_info_output_log_level(): + flexmock(module).should_receive('borgmatic_source_directories').and_return([]) + flexmock(module).should_receive('_expand_directories').and_return(('foo', 'bar')) + flexmock(module).should_receive('_expand_home_directories').and_return(()) + flexmock(module).should_receive('_write_pattern_file').and_return(None) + flexmock(module).should_receive('_make_pattern_flags').and_return(()) + flexmock(module).should_receive('_make_exclude_flags').and_return(()) + flexmock(module).should_receive('execute_command').with_args( + ('borg', 'create', '--list', '--filter', 'AME-', '--info') + ARCHIVE_WITH_PATHS, + output_log_level=logging.INFO, + error_on_warnings=False, + ) + insert_logging_mock(logging.INFO) + + module.create_archive( + dry_run=False, + repository='repo', + location_config={ + 'source_directories': ['foo', 'bar'], + 'repositories': ['repo'], + 'exclude_patterns': None, + }, + storage_config={}, + files=True, + ) + + def test_create_archive_with_progress_and_log_info_calls_borg_with_progress_parameter_and_no_list(): flexmock(module).should_receive('borgmatic_source_directories').and_return([]) flexmock(module).should_receive('_expand_directories').and_return(('foo', 'bar')) diff --git a/tests/unit/borg/test_prune.py b/tests/unit/borg/test_prune.py index 1694e4e..a61c490 100644 --- a/tests/unit/borg/test_prune.py +++ b/tests/unit/borg/test_prune.py @@ -142,12 +142,12 @@ def test_prune_archives_with_remote_path_calls_borg_with_remote_path_parameters( ) -def test_prune_archives_with_stats_calls_borg_with_stats_parameter(): +def test_prune_archives_with_stats_calls_borg_with_stats_parameter_and_warning_output_log_level(): retention_config = flexmock() flexmock(module).should_receive('_make_prune_flags').with_args(retention_config).and_return( BASE_PRUNE_FLAGS ) - insert_execute_command_mock(PRUNE_COMMAND + ('--stats', 'repo'), logging.INFO) + insert_execute_command_mock(PRUNE_COMMAND + ('--stats', 'repo'), logging.WARNING) module.prune_archives( dry_run=False, @@ -158,6 +158,56 @@ def test_prune_archives_with_stats_calls_borg_with_stats_parameter(): ) +def test_prune_archives_with_stats_and_log_info_calls_borg_with_stats_parameter_and_info_output_log_level(): + retention_config = flexmock() + flexmock(module).should_receive('_make_prune_flags').with_args(retention_config).and_return( + BASE_PRUNE_FLAGS + ) + insert_logging_mock(logging.INFO) + insert_execute_command_mock(PRUNE_COMMAND + ('--stats', '--info', 'repo'), logging.INFO) + + module.prune_archives( + dry_run=False, + repository='repo', + storage_config={}, + retention_config=retention_config, + stats=True, + ) + + +def test_prune_archives_with_files_calls_borg_with_list_parameter_and_warning_output_log_level(): + retention_config = flexmock() + flexmock(module).should_receive('_make_prune_flags').with_args(retention_config).and_return( + BASE_PRUNE_FLAGS + ) + insert_execute_command_mock(PRUNE_COMMAND + ('--list', 'repo'), logging.WARNING) + + module.prune_archives( + dry_run=False, + repository='repo', + storage_config={}, + retention_config=retention_config, + files=True, + ) + + +def test_prune_archives_with_files_and_log_info_calls_borg_with_list_parameter_and_info_output_log_level(): + retention_config = flexmock() + flexmock(module).should_receive('_make_prune_flags').with_args(retention_config).and_return( + BASE_PRUNE_FLAGS + ) + insert_logging_mock(logging.INFO) + insert_execute_command_mock(PRUNE_COMMAND + ('--info', '--list', 'repo'), logging.INFO) + + module.prune_archives( + dry_run=False, + repository='repo', + storage_config={}, + retention_config=retention_config, + files=True, + ) + + def test_prune_archives_with_umask_calls_borg_with_umask_parameters(): storage_config = {'umask': '077'} retention_config = flexmock()