manage help with requires option + add fullpath option

This commit is contained in:
Emmanuel Garette 2019-01-16 09:20:23 +01:00 committed by Emmanuel Garette
parent 285d7316be
commit 195abb4299

View file

@ -15,7 +15,7 @@
from typing import Union, List, Optional from typing import Union, List, Optional
from argparse import ArgumentParser, Namespace, SUPPRESS from argparse import ArgumentParser, Namespace, SUPPRESS, _HelpAction
from tiramisu.error import PropertiesOptionError from tiramisu.error import PropertiesOptionError
try: try:
from tiramisu import Config from tiramisu import Config
@ -60,12 +60,30 @@ class TiramisuNamespace(Namespace):
return super().__getattribute__(key) return super().__getattribute__(key)
class _TiramisuHelpAction(_HelpAction):
needs = False
def __call__(self, *args, **kwargs):
_TiramisuHelpAction.needs = True
def display(self, parser):
_HelpAction.__call__(self, parser, None, None)
class TiramisuCmdlineParser(ArgumentParser): class TiramisuCmdlineParser(ArgumentParser):
def __init__(self, def __init__(self,
*args, *args,
fullpath: bool=True,
**kwargs): **kwargs):
self.fullpath = fullpath
self.config = None self.config = None
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.register('action', 'help', _TiramisuHelpAction)
def _pop_action_class(self, kwargs, default=None):
ret = super()._pop_action_class(kwargs, default)
if kwargs.get('action') != 'help' and kwargs.get('dest') != 'help':
return ret
return _TiramisuHelpAction
def _match_arguments_partial(self, def _match_arguments_partial(self,
actions, actions,
@ -83,6 +101,24 @@ class TiramisuCmdlineParser(ArgumentParser):
actions.pop(0) actions.pop(0)
return super()._match_arguments_partial(actions, arg_string_pattern) return super()._match_arguments_partial(actions, arg_string_pattern)
def _parse_known_args(self, args=None, namespace=None):
namespace_, args_ = super()._parse_known_args(args, namespace)
if args != args_ and args_ and args_[0].startswith(self.prefix_chars):
# option that was disabled are no more disable
# so create a new parser
new_parser = TiramisuCmdlineParser(self.prog, fullpath=self.fullpath)
new_parser._registries = self._registries
new_parser.add_arguments(self.config)
namespace_, args_ = new_parser._parse_known_args(args_, namespace)
else:
if self._registries['action']['help'].needs:
# display help only when all variables assignemnt are done
self._registries['action']['help'].needs = False
helper = self._registries['action']['help'](None)
helper.display(self)
return namespace_, args_
def add_argument(self, *args, **kwargs): def add_argument(self, *args, **kwargs):
if args == ('-h', '--help'): if args == ('-h', '--help'):
super().add_argument(*args, **kwargs) super().add_argument(*args, **kwargs)
@ -118,7 +154,8 @@ class TiramisuCmdlineParser(ArgumentParser):
raise ValueError('name cannot startswith "{}"'.format(self.prefix_chars)) raise ValueError('name cannot startswith "{}"'.format(self.prefix_chars))
properties = obj.property.get() properties = obj.property.get()
kwargs = {'help': option.doc().replace('%', '%%'), kwargs = {'help': option.doc().replace('%', '%%'),
'default': SUPPRESS} 'default': SUPPRESS,
'dest': option.path()}
if 'positional' in properties: if 'positional' in properties:
#if not 'mandatory' in properties: #if not 'mandatory' in properties:
# raise ValueError('"positional" argument must be "mandatory" too') # raise ValueError('"positional" argument must be "mandatory" too')
@ -126,7 +163,7 @@ class TiramisuCmdlineParser(ArgumentParser):
#if option.requires(): #if option.requires():
kwargs['nargs'] = '?' kwargs['nargs'] = '?'
else: else:
if prefix: if self.fullpath and prefix:
name = prefix + '.' + name name = prefix + '.' + name
if len(name) == 1 and 'longargument' not in properties: if len(name) == 1 and 'longargument' not in properties:
args = [self.prefix_chars + name] args = [self.prefix_chars + name]
@ -199,20 +236,15 @@ class TiramisuCmdlineParser(ArgumentParser):
def format_usage(self, def format_usage(self,
*args, *args,
_forhelp=False,
**kwargs): **kwargs):
if _forhelp: help_formatter = TiramisuCmdlineParser(self.prog, fullpath=self.fullpath)
return super().format_usage(*args, **kwargs)
help_formatter = TiramisuCmdlineParser(self.prog)
help_formatter.add_arguments(self.config, _forhelp=True) help_formatter.add_arguments(self.config, _forhelp=True)
return help_formatter.format_usage(*args, **kwargs, _forhelp=True) return super(TiramisuCmdlineParser, help_formatter).format_usage(*args, **kwargs)
def format_help(self, *args, _forhelp=False, **kwargs): def format_help(self, *args, **kwargs):
if _forhelp: help_formatter = TiramisuCmdlineParser(self.prog, fullpath=self.fullpath)
return super().format_help(*args, **kwargs)
help_formatter = TiramisuCmdlineParser(self.prog)
help_formatter.add_arguments(self.config, _forhelp=True) help_formatter.add_arguments(self.config, _forhelp=True)
return help_formatter.format_help(*args, **kwargs, _forhelp=True) return super(TiramisuCmdlineParser, help_formatter).format_help(*args, **kwargs)
def get_config(self): def get_config(self):
return self.config return self.config