浏览代码

borgmatic without arguments/parameters should show usage help instead of starting a backup (#262).

Reviewed-on: https://projects.torsion.org/borgmatic-collective/borgmatic/pulls/1046
Dan Helfman 2 月之前
父节点
当前提交
a8362f2618
共有 4 个文件被更改,包括 91 次插入0 次删除
  1. 19 0
      borgmatic/commands/borgmatic.py
  2. 8 0
      borgmatic/config/schema.yaml
  3. 14 0
      docs/how-to/set-up-backups.md
  4. 50 0
      tests/unit/commands/test_borgmatic.py

+ 19 - 0
borgmatic/commands/borgmatic.py

@@ -954,6 +954,21 @@ def exit_with_help_link():  # pragma: no cover
     sys.exit(1)
 
 
+def check_and_show_help_on_no_args(configs):
+    """
+    Check if the 'borgmatic' command is run without any arguments. If the configuration option
+    'default_actions' is set to False, show the help message. Otherwise, trigger the
+    default backup behavior.
+    """
+    if len(sys.argv) == 1:  # No arguments provided
+        default_actions = any(
+            config.get('default_actions', True) for config in configs.values()
+        )
+        if not default_actions:
+            parse_arguments('--help')
+            sys.exit(0)
+
+
 def main(extra_summary_logs=[]):  # pragma: no cover
     configure_signals()
     configure_delayed_logging()
@@ -989,6 +1004,10 @@ def main(extra_summary_logs=[]):  # pragma: no cover
         global_arguments.overrides,
         resolve_env=global_arguments.resolve_env and not validate,
     )
+
+    # Use the helper function to check and show help on no arguments, passing the preloaded configs
+    check_and_show_help_on_no_args(configs)
+
     configuration_parse_errors = (
         (max(log.levelno for log in parse_logs) >= logging.CRITICAL) if parse_logs else False
     )

+ 8 - 0
borgmatic/config/schema.yaml

@@ -2685,3 +2685,11 @@ properties:
                 example: /usr/local/bin/keepassxc-cli
         description: |
             Configuration for integration with the KeePassXC password manager.
+    default_actions:
+        type: boolean
+        description: |
+            Whether to apply default actions (e.g., backup) when no arguments
+            are supplied to the borgmatic command. If set to true, borgmatic
+            will trigger the default actions(create, prune, compact and check).
+            If set to false, borgmatic will display the help message instead.
+        example: true

+ 14 - 0
docs/how-to/set-up-backups.md

@@ -296,6 +296,20 @@ skip_actions:
     - compact
 ```
 
+### Disabling default actions
+
+By default, running `borgmatic` without any arguments will perform the default
+backup actions (create, prune, compact and check). If you want to disable this
+behavior and require explicit actions to be specified, add the following to
+your configuration:
+
+```yaml
+default_actions: false
+```
+
+With this setting, running `borgmatic` without arguments will show the help
+message instead of performing any actions.
+
 
 ## Autopilot
 

+ 50 - 0
tests/unit/commands/test_borgmatic.py

@@ -2120,3 +2120,53 @@ def test_collect_configuration_run_summary_logs_outputs_merged_json_results():
             arguments=arguments,
         )
     )
+def test_check_and_show_help_on_no_args_shows_help_when_no_args_and_default_actions_false():
+    flexmock(module.sys).should_receive('argv').and_return(['borgmatic'])
+    flexmock(module).should_receive('parse_arguments').with_args('--help').once()
+    flexmock(module.sys).should_receive('exit').with_args(0).once()
+    module.check_and_show_help_on_no_args({'test.yaml': {'default_actions': False}})
+
+
+def test_check_and_show_help_on_no_args_does_not_show_help_when_no_args_and_default_actions_true():
+    flexmock(module.sys).should_receive('argv').and_return(['borgmatic'])
+    flexmock(module).should_receive('parse_arguments').never()
+    flexmock(module.sys).should_receive('exit').never()
+    module.check_and_show_help_on_no_args({'test.yaml': {'default_actions': True}})
+
+
+def test_check_and_show_help_on_no_args_does_not_show_help_when_args_provided():
+    flexmock(module.sys).should_receive('argv').and_return(['borgmatic', '--create'])
+    flexmock(module).should_receive('parse_arguments').never()
+    flexmock(module.sys).should_receive('exit').never()
+    module.check_and_show_help_on_no_args({'test.yaml': {'default_actions': False}})
+
+def test_check_and_show_help_on_no_args_with_no_default_actions_in_all_configs():
+    flexmock(module.sys).should_receive('argv').and_return(['borgmatic'])
+    
+    # Both configs have default_actions set to False, so help should be shown
+    configs = {
+        'config1.yaml': {'default_actions': False},
+        'config2.yaml': {'default_actions': False}
+    }
+    
+    # Expect help to be shown
+    flexmock(module).should_receive('parse_arguments').with_args('--help').once()
+    flexmock(module.sys).should_receive('exit').with_args(0).once()
+    
+    module.check_and_show_help_on_no_args(configs)
+
+def test_check_and_show_help_on_no_args_with_conflicting_configs():
+    flexmock(module.sys).should_receive('argv').and_return(['borgmatic'])
+    
+    # Simulate two config files with conflicting 'default_actions' values
+    configs = {
+        'config1.yaml': {'default_actions': True},
+        'config2.yaml': {'default_actions': False}
+    }
+    
+    # Expect help not to be shown because at least one config enables default actions
+    flexmock(module).should_receive('parse_arguments').never()
+    flexmock(module.sys).should_receive('exit').never()
+    
+    module.check_and_show_help_on_no_args(configs)
+