From 6c30a1c8a388f4f0dd4d97de878ff7e605a677eb Mon Sep 17 00:00:00 2001 From: Eric Fried Date: Mon, 16 Jul 2018 16:26:43 -0500 Subject: [PATCH] generator: Pass conf to _OptFormatter In preparation for adding another conf option that would have needed to be kwarg'd all the way down the call stack to the .format method, this patch removes the existing `minimal` and `summarize` kwargs from the methods in that call stack and instead makes them instance attributes of generator._OptFormatter, which is now initialized with the whole ConfigOpts object rather than those individual options. This is just a refactor. There is no functional change (assuming nobody is being naughty and consuming the private _OptFormatter class). Change-Id: Ide0f1c6d79d506b979b54e6446786ea9ff51c8d5 --- oslo_config/generator.py | 31 +++++++++++++--------------- oslo_config/tests/test_generator.py | 32 +++++++++++++++++------------ 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/oslo_config/generator.py b/oslo_config/generator.py index 7b6e5ad4..d3b47cf7 100644 --- a/oslo_config/generator.py +++ b/oslo_config/generator.py @@ -165,14 +165,16 @@ class _OptFormatter(object): """Format configuration option descriptions to a file.""" - def __init__(self, output_file=None, wrap_width=70): + def __init__(self, conf, output_file=None): """Construct an OptFormatter object. + :param conf: The config object from _generator_opts :param output_file: a writeable file object - :param wrap_width: The maximum length of help lines, 0 to not wrap """ self.output_file = output_file or sys.stdout - self.wrap_width = wrap_width + self.wrap_width = conf.wrap_width + self.minimal = conf.minimal + self.summarize = conf.summarize def _format_help(self, help_text): """Format the help for a group or option to the output file. @@ -217,13 +219,11 @@ class _OptFormatter(object): lines = ['[%s]\n' % groupname] self.writelines(lines) - def format(self, opt, group_name, minimal=False, summarize=False): + def format(self, opt, group_name): """Format a description of an option to the output file. :param opt: a cfg.Opt instance :param group_name: name of the group to which the opt is assigned - :param minimal: enable option by default, marking it as required - :param summarize: output a summarized description of the opt :returns: a formatted opt description string """ if not opt.help: @@ -238,7 +238,7 @@ class _OptFormatter(object): if opt.help: # an empty line signifies a new paragraph. We only want the # summary line - if summarize: + if self.summarize: _split = opt.help.split('\n\n') opt_help = _split[0].rstrip(':').rstrip('.') if len(_split) > 1: @@ -335,7 +335,7 @@ class _OptFormatter(object): for default_str in defaults: if default_str: default_str = ' ' + default_str.replace('\n', '\n# ') - if minimal: + if self.minimal: lines.append('%s =%s\n' % (opt.dest, default_str)) else: lines.append('#%s =%s\n' % (opt.dest, default_str)) @@ -520,18 +520,18 @@ def on_load_failure_callback(*args, **kwargs): raise -def _output_opts(f, group, group_data, minimal=False, summarize=False): +def _output_opts(f, group, group_data): f.format_group(group_data['object'] or group) for (namespace, opts) in sorted(group_data['namespaces'], key=operator.itemgetter(0)): f.write('\n#\n# From %s\n#\n' % namespace) for opt in sorted(opts, key=operator.attrgetter('advanced')): try: - if minimal and not opt.required: + if f.minimal and not opt.required: pass else: f.write('\n') - f.format(opt, group, minimal, summarize) + f.format(opt, group) except Exception as err: f.write('# Warning: Failed to format sample for %s\n' % (opt.dest,)) @@ -731,18 +731,15 @@ def generate(conf, output_file=None): groups = _get_groups(_list_opts(conf.namespace)) if conf.format_ == 'ini': - formatter = _OptFormatter(output_file=output_file, - wrap_width=conf.wrap_width) + formatter = _OptFormatter(conf, output_file=output_file) # Output the "DEFAULT" section as the very first section - _output_opts(formatter, 'DEFAULT', groups.pop('DEFAULT'), conf.minimal, - conf.summarize) + _output_opts(formatter, 'DEFAULT', groups.pop('DEFAULT')) # output all other config sections with groups in alphabetical order for group, group_data in sorted(groups.items()): formatter.write('\n\n') - _output_opts(formatter, group, group_data, conf.minimal, - conf.summarize) + _output_opts(formatter, group, group_data) elif conf.format_ == 'rst': _output_human_readable( conf.namespace, diff --git a/oslo_config/tests/test_generator.py b/oslo_config/tests/test_generator.py index c966b40f..a9bc5593 100644 --- a/oslo_config/tests/test_generator.py +++ b/oslo_config/tests/test_generator.py @@ -38,6 +38,14 @@ def custom_type(a): return a +def build_formatter(output_file, **kwargs): + conf = cfg.ConfigOpts() + conf.register_opts(generator._generator_opts) + for k, v in kwargs.items(): + conf.set_override(k, v) + return generator._OptFormatter(conf, output_file=output_file) + + class GeneratorTestCase(base.BaseTestCase): groups = { @@ -1498,7 +1506,7 @@ class GeneratorAdditionalTestCase(base.BaseTestCase): fd, tmp_file = tempfile.mkstemp() with open(tmp_file, 'w+') as f: - formatter = generator._OptFormatter(output_file=f) + formatter = build_formatter(f) generator._output_opts(formatter, 'DEFAULT', groups.pop('DEFAULT')) expected = '''[DEFAULT] ''' @@ -1514,7 +1522,7 @@ class GeneratorAdditionalTestCase(base.BaseTestCase): fd, tmp_file = tempfile.mkstemp() with open(tmp_file, 'w+') as f: - formatter = generator._OptFormatter(output_file=f) + formatter = build_formatter(f) generator._output_opts(formatter, 'alpha', groups.pop('alpha')) expected = '''[alpha] @@ -1537,7 +1545,7 @@ class GeneratorAdditionalTestCase(base.BaseTestCase): fd, tmp_file = tempfile.mkstemp() f = open(tmp_file, 'w+') - formatter = generator._OptFormatter(output_file=f) + formatter = build_formatter(f) expected = '''[alpha] # @@ -1564,7 +1572,7 @@ class GeneratorMutableOptionTestCase(base.BaseTestCase): def test_include_message(self): out = moves.StringIO() opt = cfg.StrOpt('foo', help='foo option', mutable=True) - gen = generator._OptFormatter(output_file=out) + gen = build_formatter(out) gen.format(opt, 'group1') result = out.getvalue() self.assertIn( @@ -1575,7 +1583,7 @@ class GeneratorMutableOptionTestCase(base.BaseTestCase): def test_do_not_include_message(self): out = moves.StringIO() opt = cfg.StrOpt('foo', help='foo option', mutable=False) - gen = generator._OptFormatter(output_file=out) + gen = build_formatter(out) gen.format(opt, 'group1') result = out.getvalue() self.assertNotIn( @@ -1669,11 +1677,10 @@ class RequiredOptionTestCase(base.BaseTestCase): fd, tmp_file = tempfile.mkstemp() with open(tmp_file, 'w+') as f: - formatter = generator._OptFormatter(output_file=f) + formatter = build_formatter(f, minimal=True) generator._output_opts(formatter, 'alpha', - groups.pop('alpha'), - minimal=True) + groups.pop('alpha')) expected = '''[alpha] # @@ -1727,11 +1734,10 @@ messages!""")] fd, tmp_file = tempfile.mkstemp() with open(tmp_file, 'w+') as f: - formatter = generator._OptFormatter(output_file=f) + formatter = build_formatter(f, summarize=True) generator._output_opts(formatter, 'alpha', - groups.pop('alpha'), - summarize=True) + groups.pop('alpha')) expected = '''[alpha] # @@ -1769,7 +1775,7 @@ class AdvancedOptionsTestCase(base.BaseTestCase): fd, tmp_file = tempfile.mkstemp() with open(tmp_file, 'w+') as f: - formatter = generator._OptFormatter(output_file=f) + formatter = build_formatter(f) generator._output_opts(formatter, 'alpha', groups.pop('alpha')) expected = '''[alpha] @@ -1810,7 +1816,7 @@ class HostAddressTestCase(base.BaseTestCase): groups = generator._get_groups(config) out = moves.StringIO() - formatter = generator._OptFormatter(output_file=out) + formatter = build_formatter(out) generator._output_opts(formatter, 'alpha', groups.pop('alpha')) result = out.getvalue()