osapi_compute_extension_opt = cfg.MultiStrOpt('osapi_compute_extension',
default=DEFAULT_EXTENSIONS)
-Option schemas are registered with with the config manager at runtime, but
-before the option is referenced::
+Option schemas are registered with the config manager at runtime, but before
+the option is referenced::
class ExtensionManager(object):
fix_path('~'),
os.path.join('/etc', project) if project else None,
'/etc'
- ]
+ ]
return filter(bool, cfg_dirs)
multi = False
def __init__(self, name, dest=None, short=None, default=None,
- metavar=None, help=None, secret=False, required=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
:param help: an explanation of how the option is used
:param secret: true iff the value should be obfuscated in log output
:param required: true iff a value must be supplied for this option
+ :param deprecated_name: deprecated name option. Acts like an alias
"""
self.name = name
if dest is None:
self.help = help
self.secret = secret
self.required = required
+ if deprecated_name is not None:
+ self.deprecated_name = deprecated_name.replace('-', '_')
+ else:
+ self.deprecated_name = None
def _get_from_config_parser(self, cparser, section):
"""Retrieves the option value from a MultiConfigParser object.
:param cparser: a ConfigParser object
:param section: a section name
"""
- return cparser.get(section, self.dest)
+ return self._cparser_get_with_deprecated(cparser, section)
+
+ def _cparser_get_with_deprecated(self, cparser, section):
+ """If cannot find option as dest try deprecated_name alias."""
+ if self.deprecated_name is not None:
+ return cparser.get(section, [self.dest, self.deprecated_name])
+ return cparser.get(section, [self.dest])
def _add_to_cli(self, parser, group=None):
"""Makes the option available in the command line interface.
container = self._get_optparse_container(parser, group)
kwargs = self._get_optparse_kwargs(group)
prefix = self._get_optparse_prefix('', group)
- self._add_to_optparse(container, self.name, self.short, kwargs, prefix)
+ self._add_to_optparse(container, self.name, self.short, kwargs, prefix,
+ self.deprecated_name)
- def _add_to_optparse(self, container, name, short, kwargs, prefix=''):
+ def _add_to_optparse(self, container, name, short, kwargs, prefix='',
+ deprecated_name=None):
"""Add an option to an optparse parser or group.
:param container: an optparse.OptionContainer object
args = ['--' + prefix + name]
if short:
args += ['-' + short]
+ if deprecated_name:
+ args += ['--' + prefix + deprecated_name]
for a in args:
if container.has_option(a):
raise DuplicateOptError(a)
dest = self.dest
if group is not None:
dest = group.name + '_' + dest
- kwargs.update({
- 'dest': dest,
- 'metavar': self.metavar,
- 'help': self.help,
- })
+ kwargs.update({'dest': dest,
+ 'metavar': self.metavar,
+ 'help': self.help, })
return kwargs
def _get_optparse_prefix(self, prefix, group):
return value
- return [convert_bool(v) for v in cparser.get(section, self.dest)]
+ return [convert_bool(v) for v in
+ self._cparser_get_with_deprecated(cparser, section)]
def _add_to_cli(self, parser, group=None):
"""Extends the base class method to add the --nooptname option."""
kwargs = self._get_optparse_kwargs(group, action='store_false')
prefix = self._get_optparse_prefix('no', group)
kwargs["help"] = "The inverse of --" + self.name
- self._add_to_optparse(container, self.name, None, kwargs, prefix)
+ self._add_to_optparse(container, self.name, None, kwargs, prefix,
+ self.deprecated_name)
def _get_optparse_kwargs(self, group, action='store_true', **kwargs):
"""Extends the base optparse keyword dict for boolean options."""
def _get_from_config_parser(self, cparser, section):
"""Retrieve the opt value as a integer from ConfigParser."""
- return [int(v) for v in cparser.get(section, self.dest)]
+ return [int(v) for v in self._cparser_get_with_deprecated(cparser,
+ section)]
def _get_optparse_kwargs(self, group, **kwargs):
"""Extends the base optparse keyword dict for integer options."""
def _get_from_config_parser(self, cparser, section):
"""Retrieve the opt value as a float from ConfigParser."""
- return [float(v) for v in cparser.get(section, self.dest)]
+ return [float(v) for v in
+ self._cparser_get_with_deprecated(cparser, section)]
def _get_optparse_kwargs(self, group, **kwargs):
"""Extends the base optparse keyword dict for float options."""
def _get_from_config_parser(self, cparser, section):
"""Retrieve the opt value as a list from ConfigParser."""
- return [v.split(',') for v in cparser.get(section, self.dest)]
+ return [v.split(',') for v in
+ self._cparser_get_with_deprecated(cparser, section)]
def _get_optparse_kwargs(self, group, **kwargs):
"""Extends the base optparse keyword dict for list options."""
return super(MultiStrOpt,
self)._get_optparse_kwargs(group, action='append')
+ def _cparser_get_with_deprecated(self, cparser, section):
+ """If cannot find option as dest try deprecated_name alias."""
+ if self.deprecated_name is not None:
+ return cparser.get(section, [self.dest, self.deprecated_name],
+ multi=True)
+ return cparser.get(section, [self.dest], multi=True)
+
class OptGroup(object):
class MultiConfigParser(object):
def __init__(self):
- self.sections = {}
+ self.parsed = []
def read(self, config_files):
read_ok = []
for filename in config_files:
- parser = ConfigParser(filename, self.sections)
+ sections = {}
+ parser = ConfigParser(filename, sections)
try:
parser.parse()
except IOError:
continue
-
+ self.parsed.insert(0, sections)
read_ok.append(filename)
return read_ok
- def get(self, section, name):
- return self.sections[section][name]
+ def get(self, section, names, multi=False):
+ rvalue = []
+ for sections in self.parsed:
+ if section not in sections:
+ continue
+ for name in names:
+ if name in sections[section]:
+ if multi:
+ rvalue = sections[section][name] + rvalue
+ else:
+ return sections[section][name]
+ if multi and rvalue != []:
+ return rvalue
+ raise KeyError
class ConfigOpts(collections.Mapping):
self._oparser.disable_interspersed_args()
self._config_opts = [
- MultiStrOpt('config-file',
- default=default_config_files,
- metavar='PATH',
- help='Path to a config file to use. Multiple config '
- 'files can be specified, with values in later '
- 'files taking precedence. The default files '
- ' used are: %s' % (default_config_files, )),
+ MultiStrOpt('config-file',
+ default=default_config_files,
+ metavar='PATH',
+ help='Path to a config file to use. Multiple config '
+ 'files can be specified, with values in later '
+ 'files taking precedence. The default files '
+ ' used are: %s' % (default_config_files, )),
StrOpt('config-dir',
metavar='DIR',
help='Path to a config directory to pull *.conf '
'the file(s), if any, specified via --config-file, '
'hence over-ridden options in the directory take '
'precedence.'),
- ]
+ ]
self.register_cli_opts(self._config_opts)
self.project = project
def _substitute(self, value):
"""Perform string template substitution.
- Substititue any template variables (e.g. $foo, ${bar}) in the supplied
+ Substitute any template variables (e.g. $foo, ${bar}) in the supplied
string value(s) with opt values.
:param value: the string value, or list of string values
default, opt, override = [info[k] for k in sorted(info.keys())]
if opt.required:
- if (default is not None or
- override is not None):
+ if (default is not None or override is not None):
continue
if self._get(opt.name, group) is None:
short='v',
default=False,
help='Print more verbose output'),
- ]
+ ]
logging_cli_opts = [
StrOpt('log-config',
StrOpt('syslog-log-facility',
default='LOG_USER',
help='syslog facility to receive log lines')
- ]
+ ]
def __init__(self):
super(CommonConfigOpts, self).__init__()