Explorar o código

tools: add SubParsersHelpAction, which include subcommands details in --help

Marek Marczykowski-Górecki %!s(int64=6) %!d(string=hai) anos
pai
achega
c70e440a6c
Modificáronse 1 ficheiros con 35 adicións e 1 borrados
  1. 35 1
      qubesadmin/tools/__init__.py

+ 35 - 1
qubesadmin/tools/__init__.py

@@ -339,7 +339,7 @@ class QubesArgumentParser(argparse.ArgumentParser):
     def __init__(self, want_app=True, want_app_no_instance=False,
                  vmname_nargs=None, **kwargs):
 
-        super(QubesArgumentParser, self).__init__(**kwargs)
+        super(QubesArgumentParser, self).__init__(add_help=False, **kwargs)
 
         self._want_app = want_app
         self._want_app_no_instance = want_app_no_instance
@@ -360,6 +360,9 @@ class QubesArgumentParser(argparse.ArgumentParser):
         self.add_argument('--force-root', action='store_true',
                           default=False, help=argparse.SUPPRESS)
 
+        self.add_argument('--help', '-h', action=SubParsersHelpAction,
+                          help='show this help message and exit')
+
         if self._vmname_nargs in [argparse.ZERO_OR_MORE, argparse.ONE_OR_MORE]:
             vm_name_group = VmNameGroup(self,
                 required=(self._vmname_nargs
@@ -436,6 +439,37 @@ class QubesArgumentParser(argparse.ArgumentParser):
         print(*args, file=sys.stderr, **kwargs)
 
 
+class SubParsersHelpAction(argparse._HelpAction):
+    ''' Print help for all options _and all subparsers_ '''
+    # source https://stackoverflow.com/a/24122778
+    # pylint: disable=protected-access,too-few-public-methods
+
+    @staticmethod
+    def _indent(indent, text):
+        '''Indent *text* by *indent* spaces'''
+        return '\n'.join((' ' * indent) + l for l in text.splitlines())
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        parser.print_help()
+
+        # retrieve subparsers from parser
+        subparsers_actions = [
+            action for action in parser._actions
+            if isinstance(action, argparse._SubParsersAction)]
+        # there will probably only be one subparser_action,
+        # but better save than sorry
+        for subparsers_action in subparsers_actions:
+            # get all subparsers and print help
+            for pseudo_action in subparsers_action._choices_actions:
+                choice = pseudo_action.dest.split(' ', 1)[0]
+                subparser = subparsers_action.choices[choice]
+                print("\nCommand '{}':".format(choice))
+                choice_help = subparser.format_usage()
+                choice_help = self._indent(2, choice_help)
+                print(choice_help)
+        parser.exit()
+
+
 class AliasedSubParsersAction(argparse._SubParsersAction):
     '''SubParser with support for action aliases'''
     # source https://gist.github.com/sampsyo/471779