summaryrefslogtreecommitdiffstats
path: root/scripts/lib/argparse_oe.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lib/argparse_oe.py')
-rw-r--r--scripts/lib/argparse_oe.py59
1 files changed, 59 insertions, 0 deletions
diff --git a/scripts/lib/argparse_oe.py b/scripts/lib/argparse_oe.py
index fd866922bd..744cfe312f 100644
--- a/scripts/lib/argparse_oe.py
+++ b/scripts/lib/argparse_oe.py
@@ -1,5 +1,6 @@
1import sys 1import sys
2import argparse 2import argparse
3from collections import defaultdict, OrderedDict
3 4
4class ArgumentUsageError(Exception): 5class ArgumentUsageError(Exception):
5 """Exception class you can raise (and catch) in order to show the help""" 6 """Exception class you can raise (and catch) in order to show the help"""
@@ -9,6 +10,10 @@ class ArgumentUsageError(Exception):
9 10
10class ArgumentParser(argparse.ArgumentParser): 11class ArgumentParser(argparse.ArgumentParser):
11 """Our own version of argparse's ArgumentParser""" 12 """Our own version of argparse's ArgumentParser"""
13 def __init__(self, *args, **kwargs):
14 kwargs.setdefault('formatter_class', OeHelpFormatter)
15 self._subparser_groups = OrderedDict()
16 super(ArgumentParser, self).__init__(*args, **kwargs)
12 17
13 def error(self, message): 18 def error(self, message):
14 sys.stderr.write('ERROR: %s\n' % message) 19 sys.stderr.write('ERROR: %s\n' % message)
@@ -27,10 +32,26 @@ class ArgumentParser(argparse.ArgumentParser):
27 32
28 def add_subparsers(self, *args, **kwargs): 33 def add_subparsers(self, *args, **kwargs):
29 ret = super(ArgumentParser, self).add_subparsers(*args, **kwargs) 34 ret = super(ArgumentParser, self).add_subparsers(*args, **kwargs)
35 # Need a way of accessing the parent parser
36 ret._parent_parser = self
37 # Ensure our class gets instantiated
30 ret._parser_class = ArgumentSubParser 38 ret._parser_class = ArgumentSubParser
39 # Hacky way of adding a method to the subparsers object
40 ret.add_subparser_group = self.add_subparser_group
31 return ret 41 return ret
32 42
43 def add_subparser_group(self, groupname, groupdesc, order=0):
44 self._subparser_groups[groupname] = (groupdesc, order)
45
46
33class ArgumentSubParser(ArgumentParser): 47class ArgumentSubParser(ArgumentParser):
48 def __init__(self, *args, **kwargs):
49 if 'group' in kwargs:
50 self._group = kwargs.pop('group')
51 if 'order' in kwargs:
52 self._order = kwargs.pop('order')
53 super(ArgumentSubParser, self).__init__(*args, **kwargs)
54
34 def parse_known_args(self, args=None, namespace=None): 55 def parse_known_args(self, args=None, namespace=None):
35 # This works around argparse not handling optional positional arguments being 56 # This works around argparse not handling optional positional arguments being
36 # intermixed with other options. A pretty horrible hack, but we're not left 57 # intermixed with other options. A pretty horrible hack, but we're not left
@@ -64,3 +85,41 @@ class ArgumentSubParser(ArgumentParser):
64 if hasattr(action, 'save_nargs'): 85 if hasattr(action, 'save_nargs'):
65 action.nargs = action.save_nargs 86 action.nargs = action.save_nargs
66 return super(ArgumentParser, self).format_help() 87 return super(ArgumentParser, self).format_help()
88
89
90class OeHelpFormatter(argparse.HelpFormatter):
91 def _format_action(self, action):
92 if hasattr(action, '_get_subactions'):
93 # subcommands list
94 groupmap = defaultdict(list)
95 ordermap = {}
96 subparser_groups = action._parent_parser._subparser_groups
97 groups = sorted(subparser_groups.keys(), key=lambda item: subparser_groups[item][1], reverse=True)
98 for subaction in self._iter_indented_subactions(action):
99 parser = action._name_parser_map[subaction.dest]
100 group = getattr(parser, '_group', None)
101 groupmap[group].append(subaction)
102 if group not in groups:
103 groups.append(group)
104 order = getattr(parser, '_order', 0)
105 ordermap[subaction.dest] = order
106
107 lines = []
108 if len(groupmap) > 1:
109 groupindent = ' '
110 else:
111 groupindent = ''
112 for group in groups:
113 subactions = groupmap[group]
114 if not subactions:
115 continue
116 if groupindent:
117 if not group:
118 group = 'other'
119 groupdesc = subparser_groups.get(group, (group, 0))[0]
120 lines.append(' %s:' % groupdesc)
121 for subaction in sorted(subactions, key=lambda item: ordermap[item.dest], reverse=True):
122 lines.append('%s%s' % (groupindent, self._format_action(subaction).rstrip()))
123 return '\n'.join(lines)
124 else:
125 return super(OeHelpFormatter, self)._format_action(action)