summaryrefslogtreecommitdiffstats
path: root/openstack
diff options
context:
space:
mode:
Diffstat (limited to 'openstack')
-rw-r--r--openstack/common/cfg.py87
1 files changed, 48 insertions, 39 deletions
diff --git a/openstack/common/cfg.py b/openstack/common/cfg.py
index 7939d02..2430077 100644
--- a/openstack/common/cfg.py
+++ b/openstack/common/cfg.py
@@ -475,6 +475,8 @@ class Opt(object):
a single character CLI option name
default:
the default value of the option
+ positional:
+ True if the option is a positional CLI argument
metavar:
the name shown as the argument to a CLI option in --help output
help:
@@ -483,8 +485,8 @@ class Opt(object):
multi = False
def __init__(self, name, dest=None, short=None, default=None,
- metavar=None, help=None, secret=False, required=False,
- deprecated_name=None):
+ positional=False, metavar=None, help=None,
+ secret=False, required=False, deprecated_name=None):
"""Construct an Opt object.
The only required parameter is the option's name. However, it is
@@ -494,6 +496,7 @@ class Opt(object):
:param dest: the name of the corresponding ConfigOpts property
:param short: a single character CLI option name
:param default: the default value of the option
+ :param positional: True if the option is a positional CLI argument
:param metavar: the option argument to show in --help
:param help: an explanation of how the option is used
:param secret: true iff the value should be obfuscated in log output
@@ -507,6 +510,7 @@ class Opt(object):
self.dest = dest
self.short = short
self.default = default
+ self.positional = positional
self.metavar = metavar
self.help = help
self.secret = secret
@@ -551,10 +555,10 @@ class Opt(object):
kwargs = self._get_argparse_kwargs(group)
prefix = self._get_argparse_prefix('', group)
self._add_to_argparse(container, self.name, self.short, kwargs, prefix,
- self.deprecated_name)
+ self.positional, self.deprecated_name)
def _add_to_argparse(self, container, name, short, kwargs, prefix='',
- deprecated_name=None):
+ positional=False, deprecated_name=None):
"""Add an option to an argparse parser or group.
:param container: an argparse._ArgumentGroup object
@@ -562,14 +566,17 @@ class Opt(object):
:param short: the short opt name
:param kwargs: the keyword arguments for add_argument()
:param prefix: an optional prefix to prepend to the opt name
+ :param position: whether the optional is a positional CLI argument
:raises: DuplicateOptError if a naming confict is detected
"""
- args = ['--' + prefix + name]
- if short:
- args += ['-' + short]
+ def hyphen(arg):
+ return arg if not positional else ''
+ args = [hyphen('--') + prefix + name]
+ if short:
+ args.append(hyphen('-') + short)
if deprecated_name:
- args += ['--' + prefix + deprecated_name]
+ args.append(hyphen('--') + prefix + deprecated_name)
try:
container.add_argument(*args, **kwargs)
@@ -598,11 +605,14 @@ class Opt(object):
:param kwargs: optional keyword arguments to add to
:returns: a dict of keyword arguments
"""
- dest = self.dest
- if group is not None:
- dest = group.name + '_' + dest
- kwargs.update({'dest': dest,
- 'metavar': self.metavar,
+ if not self.positional:
+ dest = self.dest
+ if group is not None:
+ dest = group.name + '_' + dest
+ kwargs['dest'] = dest
+ else:
+ kwargs['nargs'] = '?'
+ kwargs.update({'metavar': self.metavar,
'help': self.help, })
return kwargs
@@ -644,6 +654,11 @@ class BoolOpt(Opt):
_boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
'0': False, 'no': False, 'false': False, 'off': False}
+ def __init__(self, *args, **kwargs):
+ if 'positional' in kwargs:
+ raise ValueError('positional boolean args not supported')
+ super(BoolOpt, self).__init__(*args, **kwargs)
+
def _get_from_config_parser(self, cparser, section):
"""Retrieve the opt value as a boolean from ConfigParser."""
def convert_bool(v):
@@ -668,7 +683,7 @@ class BoolOpt(Opt):
prefix = self._get_argparse_prefix('no', group)
kwargs["help"] = "The inverse of --" + self.name
self._add_to_argparse(container, self.name, None, kwargs, prefix,
- self.deprecated_name)
+ self.positional, self.deprecated_name)
def _get_argparse_kwargs(self, group, action='store_true', **kwargs):
"""Extends the base argparse keyword dict for boolean options."""
@@ -733,16 +748,20 @@ class ListOpt(Opt):
default=None,
required=False,
help=None,
- metavar=None):
+ metavar=None,
+ nargs=None):
argparse._StoreAction.__init__(self,
option_strings=option_strings,
dest=dest,
default=default,
required=required,
- help=help)
+ help=help,
+ nargs=nargs)
def __call__(self, parser, namespace, values, option_string=None):
- setattr(namespace, self.dest, values.split(','))
+ if values is not None:
+ values = values.split(',')
+ setattr(namespace, self.dest, values)
def _get_from_config_parser(self, cparser, section):
"""Retrieve the opt value as a list from ConfigParser."""
@@ -767,8 +786,12 @@ class MultiStrOpt(Opt):
def _get_argparse_kwargs(self, group, **kwargs):
"""Extends the base argparse keyword dict for multi str options."""
- return super(MultiStrOpt,
- self)._get_argparse_kwargs(group, action='append')
+ kwargs = super(MultiStrOpt, self)._get_argparse_kwargs(group)
+ if not self.positional:
+ kwargs['action'] = 'append'
+ else:
+ kwargs['nargs'] = '*'
+ return kwargs
def _cparser_get_with_deprecated(self, cparser, section):
"""If cannot find option as dest try deprecated_name alias."""
@@ -942,20 +965,6 @@ class ConfigCliParser(argparse.ArgumentParser):
def add_subparsers(self, **kwargs):
return super(ConfigCliParser, self).add_subparsers(**kwargs)
- def parse_args(self, *args, **kwargs):
- opts, args = super(ConfigCliParser, self).parse_known_args(*args,
- **kwargs)
- unknown_args = []
- for arg in args:
- if 0 == arg.find("-"):
- unknown_args.append(arg)
-
- if unknown_args:
- msg = 'unrecognized arguments: %s'
- self.error(msg % ' '.join(unknown_args))
-
- return opts, args
-
class ConfigOpts(collections.Mapping):
@@ -1090,14 +1099,12 @@ class ConfigOpts(collections.Mapping):
self._setup(project, prog, version, usage, default_config_files)
- self._cli_values, leftovers = self._parse_cli_opts(args)
+ self._cli_values = self._parse_cli_opts(args)
self._parse_config_files()
self._check_required_opts()
- return leftovers
-
def __getattr__(self, name):
"""Look up an option value and perform string substitution.
@@ -1452,6 +1459,10 @@ class ConfigOpts(collections.Mapping):
if not opt.multi:
return value
+ # argparse ignores default=None for nargs='*'
+ if opt.positional and not value:
+ value = opt.default
+
return value + values
if values:
@@ -1577,9 +1588,7 @@ class ConfigOpts(collections.Mapping):
for opt, group in self._all_opts():
opt._add_to_cli(self._oparser, group)
- values, leftovers = self._oparser.parse_args(args)
-
- return vars(values), leftovers
+ return vars(self._oparser.parse_args(args))
class GroupAttr(collections.Mapping):