Bug 951733 - Support passing an existing argparse.ArgumentParser to mach in order to populate the command arguments. r=gps

This commit is contained in:
James Graham 2014-01-03 11:32:53 +00:00
parent 8f9a5a015b
commit a2e48d8056
3 changed files with 41 additions and 10 deletions

View File

@ -80,13 +80,17 @@ class MethodHandler(object):
# in a given context.
'conditions',
# argparse.ArgumentParser instance to use as the basis for command
# arguments.
'parser',
# Arguments added to this command's parser. This is a 2-tuple of
# positional and named arguments, respectively.
'arguments',
)
def __init__(self, cls, method, name, category=None, description=None,
allow_all_arguments=False, conditions=None, arguments=None,
allow_all_arguments=False, conditions=None, parser=None, arguments=None,
pass_context=False):
self.cls = cls
@ -96,6 +100,7 @@ class MethodHandler(object):
self.description = description
self.allow_all_arguments = allow_all_arguments
self.conditions = conditions or []
self.parser = parser
self.arguments = arguments or []
self.pass_context = pass_context

View File

@ -56,8 +56,8 @@ def CommandProvider(cls):
if not isinstance(value, types.FunctionType):
continue
command_name, category, description, allow_all, conditions = getattr(
value, '_mach_command', (None, None, None, None, None))
command_name, category, description, allow_all, conditions, parser = getattr(
value, '_mach_command', (None, None, None, None, None, None))
if command_name is None:
continue
@ -83,7 +83,7 @@ def CommandProvider(cls):
handler = MethodHandler(cls, attr, command_name, category=category,
description=description, allow_all_arguments=allow_all,
conditions=conditions, arguments=arguments,
conditions=conditions, parser=parser, arguments=arguments,
pass_context=pass_context)
Registrar.register_command_handler(handler)
@ -105,6 +105,9 @@ class Command(object):
allow_all_args -- Bool indicating whether to allow unknown arguments
through to the command.
parser -- an optional argparse.ArgumentParser instance to use as
the basis for the command arguments.
For example:
@Command('foo', category='misc', description='Run the foo action')
@ -112,16 +115,17 @@ class Command(object):
pass
"""
def __init__(self, name, category=None, description=None,
allow_all_args=False, conditions=None):
allow_all_args=False, conditions=None, parser=None):
self._name = name
self._category = category
self._description = description
self._allow_all_args = allow_all_args
self._conditions = conditions
self._parser = parser
def __call__(self, func):
func._mach_command = (self._name, self._category, self._description,
self._allow_all_args, self._conditions)
self._allow_all_args, self._conditions, self._parser)
return func

View File

@ -123,6 +123,9 @@ class CommandAction(argparse.Action):
if handler.allow_all_arguments:
parser_args['prefix_chars'] = '+'
if handler.parser:
subparser = handler.parser
else:
subparser = argparse.ArgumentParser(**parser_args)
for arg in handler.arguments:
@ -216,8 +219,24 @@ class CommandAction(argparse.Action):
if handler.allow_all_arguments:
parser_args['prefix_chars'] = '+'
if handler.parser:
c_parser = handler.parser
c_parser.formatter_class = NoUsageFormatter
try:
# By default argparse adds two groups called "positional arguments"
# and "optional arguments". We want to rename these to reflect standard
# mach terminology.
c_parser._action_groups[0].title = 'Command Parameters'
c_parser._action_groups[1].title = 'Command Arguments'
except:
# If argparse changes the internal data structures here continue;
# this will just make the output more ugly
pass
if not handler.description:
handler.description = c_parser.description
c_parser.description = None
else:
c_parser = argparse.ArgumentParser(**parser_args)
group = c_parser.add_argument_group('Command Arguments')
for arg in handler.arguments:
@ -234,3 +253,6 @@ class CommandAction(argparse.Action):
print('')
c_parser.print_help()
class NoUsageFormatter(argparse.HelpFormatter):
def _format_usage(self, *args, **kwargs):
return ""