[enh] Allow to define global abstract arguments in the cli

This commit is contained in:
Jérôme Lebleu 2015-11-13 11:53:31 +01:00
parent 28db3c5d37
commit 013447bbe7
5 changed files with 45 additions and 18 deletions

View file

@ -94,7 +94,8 @@ def api(namespaces, host='localhost', port=80, routes={},
'use_cache': use_cache }) 'use_cache': use_cache })
moulinette.run(host, port) moulinette.run(host, port)
def cli(namespaces, args, print_json=False, print_plain=False, use_cache=True): def cli(namespaces, args, print_json=False, print_plain=False, use_cache=True,
parser_kwargs={}):
"""Command line interface """Command line interface
Execute an action with the moulinette from the CLI and print its Execute an action with the moulinette from the CLI and print its
@ -107,12 +108,18 @@ def cli(namespaces, args, print_json=False, print_plain=False, use_cache=True):
- print_plain -- True to print result as a script-usable string - print_plain -- True to print result as a script-usable string
- use_cache -- False if it should parse the actions map file - use_cache -- False if it should parse the actions map file
instead of using the cached one instead of using the cached one
- parser_kwargs -- A dict of arguments to pass to the parser
class at construction
""" """
try: try:
moulinette = init_interface('cli', moulinette = init_interface('cli',
actionsmap={'namespaces': namespaces, actionsmap={
'use_cache': use_cache}) 'namespaces': namespaces,
'use_cache': use_cache,
'parser_kwargs': parser_kwargs,
},
)
moulinette.run(args, print_json, print_plain) moulinette.run(args, print_json, print_plain)
except MoulinetteError as e: except MoulinetteError as e:
import logging import logging

View file

@ -342,17 +342,20 @@ class ActionsMap(object):
all available namespaces. all available namespaces.
Keyword arguments: Keyword arguments:
- parser -- The BaseActionsMapParser derived class to use for - parser_class -- The BaseActionsMapParser derived class to use
parsing the actions map for parsing the actions map
- namespaces -- The list of namespaces to use - namespaces -- The list of namespaces to use
- use_cache -- False if it should parse the actions map file - use_cache -- False if it should parse the actions map file
instead of using the cached one. instead of using the cached one
- parser_kwargs -- A dict of arguments to pass to the parser
class at construction
""" """
def __init__(self, parser, namespaces=[], use_cache=True): def __init__(self, parser_class, namespaces=[], use_cache=True,
if not issubclass(parser, BaseActionsMapParser): parser_kwargs={}):
raise ValueError("Invalid parser class '%s'" % parser.__name__) if not issubclass(parser_class, BaseActionsMapParser):
self._parser_class = parser raise ValueError("Invalid parser class '%s'" % parser_class.__name__)
self.parser_class = parser_class
self.use_cache = use_cache self.use_cache = use_cache
if len(namespaces) == 0: if len(namespaces) == 0:
@ -380,8 +383,8 @@ class ActionsMap(object):
m18n.load_namespace(n) m18n.load_namespace(n)
# Generate parsers # Generate parsers
self.extraparser = ExtraArgumentParser(parser.interface) self.extraparser = ExtraArgumentParser(parser_class.interface)
self._parser = self._construct_parser(actionsmaps) self._parser = self._construct_parser(actionsmaps, **parser_kwargs)
@property @property
def parser(self): def parser(self):
@ -515,13 +518,15 @@ class ActionsMap(object):
## Private methods ## Private methods
def _construct_parser(self, actionsmaps): def _construct_parser(self, actionsmaps, **kwargs):
""" """
Construct the parser with the actions map Construct the parser with the actions map
Keyword arguments: Keyword arguments:
- actionsmaps -- A dict of multi-level dictionnary of - actionsmaps -- A dict of multi-level dictionnary of
categories/actions/arguments list for each namespaces categories/actions/arguments list for each namespaces
- **kwargs -- Additionnal arguments to pass at the parser
class instantiation
Returns: Returns:
An interface relevant's parser object An interface relevant's parser object
@ -551,7 +556,7 @@ class ActionsMap(object):
parser.add_argument(*names, **argp) parser.add_argument(*names, **argp)
# Instantiate parser # Instantiate parser
top_parser = self._parser_class() top_parser = self.parser_class(**kwargs)
# Iterate over actions map namespaces # Iterate over actions map namespaces
for n, actionsmap in actionsmaps.items(): for n, actionsmap in actionsmaps.items():

View file

@ -31,7 +31,7 @@ class BaseActionsMapParser(object):
- parent -- A parent BaseActionsMapParser derived object - parent -- A parent BaseActionsMapParser derived object
""" """
def __init__(self, parent=None): def __init__(self, parent=None, **kwargs):
if parent: if parent:
self._o = parent self._o = parent
else: else:

View file

@ -476,7 +476,7 @@ class ActionsMapParser(BaseActionsMapParser):
the arguments is represented by a ExtendedArgumentParser object. the arguments is represented by a ExtendedArgumentParser object.
""" """
def __init__(self, parent=None): def __init__(self, parent=None, **kwargs):
super(ActionsMapParser, self).__init__(parent) super(ActionsMapParser, self).__init__(parent)
self._parsers = {} # dict({(method, path): _HTTPArgumentParser}) self._parsers = {} # dict({(method, path): _HTTPArgumentParser})

View file

@ -5,6 +5,7 @@ import sys
import errno import errno
import getpass import getpass
import locale import locale
from argparse import SUPPRESS
from moulinette.core import MoulinetteError from moulinette.core import MoulinetteError
from moulinette.interfaces import ( from moulinette.interfaces import (
@ -172,9 +173,12 @@ class ActionsMapParser(BaseActionsMapParser):
Keyword arguments: Keyword arguments:
- parser -- The ExtendedArgumentParser object to use - parser -- The ExtendedArgumentParser object to use
- subparser_kwargs -- Arguments to pass to the sub-parser group - subparser_kwargs -- Arguments to pass to the sub-parser group
- top_parser -- An ArgumentParser object whose arguments should
be take into account but not parsed
""" """
def __init__(self, parent=None, parser=None, subparser_kwargs=None): def __init__(self, parent=None, parser=None, subparser_kwargs=None,
top_parser=None, **kwargs):
super(ActionsMapParser, self).__init__(parent) super(ActionsMapParser, self).__init__(parent)
if subparser_kwargs is None: if subparser_kwargs is None:
@ -182,6 +186,14 @@ class ActionsMapParser(BaseActionsMapParser):
self._parser = parser or ExtendedArgumentParser() self._parser = parser or ExtendedArgumentParser()
self._subparsers = self._parser.add_subparsers(**subparser_kwargs) self._subparsers = self._parser.add_subparsers(**subparser_kwargs)
self._global_parser = parent._global_parser if parent else None
if top_parser:
# Append each top parser action to the global group
glob = self.add_global_parser()
for action in top_parser._actions:
action.dest = SUPPRESS
glob._add_action(action)
## Implement virtual properties ## Implement virtual properties
@ -198,7 +210,10 @@ class ActionsMapParser(BaseActionsMapParser):
return [name] return [name]
def add_global_parser(self, **kwargs): def add_global_parser(self, **kwargs):
return self._parser.add_mutually_exclusive_group() if not self._global_parser:
self._global_parser = self._parser.add_argument_group(
"global arguments")
return self._global_parser
def add_category_parser(self, name, category_help=None, **kwargs): def add_category_parser(self, name, category_help=None, **kwargs):
"""Add a parser for a category """Add a parser for a category