浏览代码

merge subparsers and refactor

Divyansh Singh 2 年之前
父节点
当前提交
bb60b25399
共有 3 个文件被更改,包括 39 次插入24 次删除
  1. 1 1
      borgmatic/actions/bootstrap.py
  2. 27 15
      borgmatic/commands/arguments.py
  3. 11 8
      borgmatic/commands/borgmatic.py

+ 1 - 1
borgmatic/actions/bootstrap.py

@@ -70,7 +70,7 @@ def run_bootstrap(bootstrap_arguments, global_arguments, local_borg_version):
             local_borg_version,
             global_arguments,
             extract_to_stdout=False,
-            destination_path=bootstrap_arguments.destination,
+            destination_path=bootstrap_arguments.destination or '/',
             strip_components=bootstrap_arguments.strip_components,
             progress=bootstrap_arguments.progress,
         )

+ 27 - 15
borgmatic/commands/arguments.py

@@ -1,3 +1,4 @@
+import argparse
 import collections
 from argparse import Action, ArgumentParser
 
@@ -73,18 +74,15 @@ def parse_subparser_arguments(unparsed_arguments, subparsers):
                     if item in subparsers:
                         remaining_arguments.remove(item)
 
-        if canonical_name not in subcommand_parsers_mapping:
-            arguments[canonical_name] = parsed
-        else:
-            arguments[canonical_name] = None
+    arguments[canonical_name] = None if canonical_name in subcommand_parsers_mapping else parsed
 
     for argument in arguments:
-        if arguments[argument] == None:
-            for subcommand in subcommand_parsers_mapping[argument]:
-                if subcommand not in arguments:
-                    raise ValueError("Missing subcommand for {}. Expected one of {}".format(
-                        argument, subcommand_parsers_mapping[argument]
-                    ))
+        if not arguments[argument]:
+            if not any(subcommand in arguments for subcommand in subcommand_parsers_mapping[argument]):
+                raise ValueError("Missing subcommand for {}. Expected one of {}".format(
+                    argument, subcommand_parsers_mapping[argument]
+                ))
+            
 
     # If no actions are explicitly requested, assume defaults.
     if not arguments and '--help' not in unparsed_arguments and '-h' not in unparsed_arguments:
@@ -948,7 +946,17 @@ def make_parsers():
     )
     borg_group.add_argument('-h', '--help', action='help', help='Show this help message and exit')
 
-    return top_level_parser, subparsers, config_subparsers
+    merged_subparsers = argparse._SubParsersAction(None, None, metavar=None, dest='merged', parser_class=None)
+
+    for name, subparser in subparsers.choices.items():
+        merged_subparsers._name_parser_map[name] = subparser
+        subparser._name_parser_map = merged_subparsers._name_parser_map
+
+    for name, subparser in config_subparsers.choices.items():
+        merged_subparsers._name_parser_map[name] = subparser
+        subparser._name_parser_map = merged_subparsers._name_parser_map
+
+    return top_level_parser, merged_subparsers        
 
 
 def parse_arguments(*unparsed_arguments):
@@ -956,14 +964,18 @@ def parse_arguments(*unparsed_arguments):
     Given command-line arguments with which this script was invoked, parse the arguments and return
     them as a dict mapping from subparser name (or "global") to an argparse.Namespace instance.
     '''
-    top_level_parser, subparsers, config_subparsers = make_parsers()
+    top_level_parser, subparsers = make_parsers()
 
-    subparser_choices = subparsers.choices.copy()
-    subparser_choices.update(config_subparsers.choices)
 
     arguments, remaining_arguments = parse_subparser_arguments(
-        unparsed_arguments, subparser_choices
+        unparsed_arguments, subparsers.choices
     )
+
+    if 'bootstrap' in arguments.keys() and len(arguments.keys()) > 1:
+        raise ValueError(
+            'The bootstrap action cannot be combined with other actions. Please run it separately.'
+        )
+
     arguments['global'] = top_level_parser.parse_args(remaining_arguments)
 
     if arguments['global'].excludes_filename:

+ 11 - 8
borgmatic/commands/borgmatic.py

@@ -617,7 +617,7 @@ def collect_configuration_run_summary_logs(configs, arguments):
         if 'extract' in arguments or 'mount' in arguments:
             validate.guard_single_repository_selected(repository, configs)
 
-        if 'config' not in arguments:
+        if 'bootstrap' not in arguments:
             validate.guard_configuration_contains_repository(repository, configs)
     except ValueError as error:
         yield from log_error_records(str(error))
@@ -626,14 +626,17 @@ def collect_configuration_run_summary_logs(configs, arguments):
     if 'bootstrap' in arguments:
         # no configuration file is needed for bootstrap
         local_borg_version = borg_version.local_borg_version({}, 'borg')
-        borgmatic.actions.bootstrap.run_bootstrap(arguments['bootstrap'], arguments['global'], local_borg_version)
-        yield logging.makeLogRecord(
-            dict(
-                levelno=logging.INFO,
-                levelname='INFO',
-                msg='Bootstrap successful',
+        try:
+            borgmatic.actions.bootstrap.run_bootstrap(arguments['bootstrap'], arguments['global'], local_borg_version)
+            yield logging.makeLogRecord(
+                dict(
+                    levelno=logging.INFO,
+                    levelname='INFO',
+                    msg='Bootstrap successful',
+                )
             )
-        )
+        except (CalledProcessError, ValueError, OSError) as error:
+            yield from log_error_records('Error running bootstrap', error)
         return
 
     if not configs: