diff --git a/autogenerate_config_docs/autohelp.py b/autogenerate_config_docs/autohelp.py index 3203f7b6..09270223 100755 --- a/autogenerate_config_docs/autohelp.py +++ b/autogenerate_config_docs/autohelp.py @@ -27,7 +27,7 @@ import pickle import re import sys -from lxml import etree +import jinja2 import stevedore from hooks import HOOKS # noqa @@ -73,62 +73,6 @@ IGNORE = [ ] -BASE_XML = ''' - - - - - - - - - - - - - -
Description of %(nice_cat)s configuration options
Configuration option = Default valueDescription
-
''' - -BASE_RST = ''' -.. list-table:: Description of %(nice_cat)s configuration options - :header-rows: 2 - :widths: 100 100 - :class: config-ref-table - - * - Configuration option = Default value - - Description -''' - -NEW_GROUP_RST = ''' -.. list-table:: - :header-rows: 1 - :widths: 100 100 - :class: config-ref-table - -''' - register_re = re.compile(r'''^ +.*\.register_opts\((?P[^,)]+)''' r'''(, (group=)?["'](?P.*)["'])?\)''') @@ -435,12 +379,16 @@ def _get_category_names(package_name): return category_names -def write_docbook(package_name, options, target, verbose=0): - """Write DocBook tables. +def write_files(package_name, options, target, output_format): + """Write tables. - Prints a docbook-formatted table for every group of options. + Prints a table for every group of options. """ - target = target or '../../doc/common/tables/' + if not target: + if output_format == 'rst': + target = '../../doc/config-ref-rst/source/tables' + else: + target = '../../doc/common/tables/' options_by_cat = _get_options_by_cat(package_name) category_names = _get_category_names(package_name) @@ -448,101 +396,53 @@ def write_docbook(package_name, options, target, verbose=0): os.makedirs(target) for cat in options_by_cat.keys(): - parser = etree.XMLParser(remove_blank_text=True) + env = { + 'pkg': package_name, + 'cat': cat, + 'groups': [], + 'items': [], + } + if cat in category_names: - nice_cat = category_names[cat] + env['nice_cat'] = category_names[cat] else: - nice_cat = cat + env['nice_cat'] = cat print("No nicename for %s" % cat) - xml = etree.XML(BASE_XML % - {'pkg': package_name, 'cat': cat, - 'nice_cat': nice_cat}, - parser) - tbody = xml.find(".//{http://docbook.org/ns/docbook}tbody") + curgroup = None + items = None for optname in options_by_cat[cat]: group, option = options.get_option(optname) + if group != curgroup: - curgroup = group - tr = etree.Element('tr') - th = etree.Element('th', colspan="2") - th.text = "[%s]" % group - tr.append(th) - tbody.append(tr) + if group is not None: + curgroup = group + env['groups'].append(group) + if items is not None: + env['items'].append(items) + items = [] if not option.help: option.help = "No help text available for this option." - default = _sanitize_default(option) + item = (option.dest, + _sanitize_default(option), + "(%s) %s" % (type(option).__name__, option.help.strip())) + items.append(item) - tr = etree.Element('tr') - tbody.append(tr) + env['items'].append(items) - td = etree.Element('td') - option_xml = etree.SubElement(td, 'option') - option_xml.text = "%s" % option.dest - option_xml.tail = " = " - replaceable_xml = etree.SubElement(td, 'replaceable') - replaceable_xml.text = "%s" % default - tr.append(td) - - td = etree.Element('td') - td.text = "(%s) %s" % (type(option).__name__, option.help.strip()) - tr.append(td) - - file_path = ("%(target)s/%(package_name)s-%(cat)s.xml" % + ext = 'rst' if output_format == 'rst' else 'xml' + file_path = ("%(target)s/%(package_name)s-%(cat)s.%(ext)s" % {'target': target, 'package_name': package_name, - 'cat': cat}) + 'cat': cat, 'ext': ext}) + tmpl_file = os.path.join(os.path.dirname(__file__), + 'templates/autohelp.%s.j2' % output_format) + with open(tmpl_file) as fd: + template = jinja2.Template(fd.read(), trim_blocks=True) + output = template.render(filename=file_path, **env) + with open(file_path, 'w') as fd: - fd.write(etree.tostring(xml, pretty_print=True, - xml_declaration=True, - encoding="UTF-8")) - - -def write_rst(package_name, options, target, verbose=0): - """Write RST tables. - - Prints an RST-formatted table for every group of options. - """ - target = target or '../../doc/common/tables/rst/' - options_by_cat = _get_options_by_cat(package_name) - category_names = _get_category_names(package_name) - - if not os.path.isdir(target): - os.makedirs(target) - - for cat in options_by_cat.keys(): - if cat in category_names: - nice_cat = category_names[cat] - else: - nice_cat = cat - print("No nicename for %s" % cat) - rst_table = (BASE_RST % {'pkg': package_name, - 'cat': cat, - 'nice_cat': nice_cat}) - curgroup = None - for optname in options_by_cat[cat]: - group, option = options.get_option(optname) - if group != curgroup: - if curgroup is not None: - rst_table += NEW_GROUP_RST - rst_table += ' * - **[%s]**\n -\n' % group - curgroup = group - - if not option.help: - option.help = "No help text available for this option." - default = _sanitize_default(option) - - option_text = "%s = %s" % (option.dest, default) - option_text = "``%s``" % option_text.strip() - option_help = "(%s) %s" % (type(option).__name__, - option.help.strip()) - rst_table += " * - %s\n - %s\n" % (option_text, option_help) - - file_path = ("%(target)s/%(package_name)s-%(cat)s.rst" % - {'target': target, 'package_name': package_name, - 'cat': cat}) - with open(file_path, 'w') as fd: - fd.write(rst_table) + fd.write(output) def create_flagmappings(package_name, options, verbose=0): @@ -663,11 +563,8 @@ def main(): elif args.subcommand == 'update': update_flagmappings(args.package, options, verbose=args.verbose) - elif args.subcommand == 'docbook': - write_docbook(args.package, options, args.target, verbose=args.verbose) - - elif args.subcommand == 'rst': - write_rst(args.package, options, args.target, verbose=args.verbose) + elif args.subcommand in ('docbook', 'rst'): + write_files(args.package, options, args.target, args.subcommand) elif args.subcommand == 'dump': options.dump() diff --git a/autogenerate_config_docs/releasenotes/notes/switch-to-jinja-4b8d143f872a2495.yaml b/autogenerate_config_docs/releasenotes/notes/switch-to-jinja-4b8d143f872a2495.yaml new file mode 100644 index 00000000..6369bfa3 --- /dev/null +++ b/autogenerate_config_docs/releasenotes/notes/switch-to-jinja-4b8d143f872a2495.yaml @@ -0,0 +1,3 @@ +--- +other: + - Use jinja templating system to generate configuration reference tables. diff --git a/autogenerate_config_docs/templates/autohelp.docbook.j2 b/autogenerate_config_docs/templates/autohelp.docbook.j2 new file mode 100644 index 00000000..cb4ddce8 --- /dev/null +++ b/autogenerate_config_docs/templates/autohelp.docbook.j2 @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + +{% for group in groups %} + + + +{% for item in items[loop.index0] %} + + + + +{% endfor %} +{% endfor %} + +
Description of {{ nice_cat }} configuration options
Configuration option = Default valueDescription
[{{ group }}]
= {{ item[1] }}{{ item[2]|replace('<', '<')|replace('>', '>') }}
+
+ diff --git a/autogenerate_config_docs/templates/autohelp.rst.j2 b/autogenerate_config_docs/templates/autohelp.rst.j2 new file mode 100644 index 00000000..f1a80974 --- /dev/null +++ b/autogenerate_config_docs/templates/autohelp.rst.j2 @@ -0,0 +1,24 @@ +.. + Warning: Do not edit this file. It is automatically generated from the + software project's code and your changes will be overwritten. + + The tool to generate this file lives in openstack-doc-tools repository. + + Please make any changes needed in the code, then run the + autogenerate-config-doc tool from the openstack-doc-tools repository, or + ask for help on the documentation mailing list, IRC channel or meeting. + +.. list-table:: Description of {{ nice_cat }} configuration options + :header-rows: 1 + :class: config-ref-table + + * - Configuration option = Default value + - Description +{% for group in groups %} + * - **[{{ group }}]** + - +{% for item in items[loop.index0] %} + * - ``{{ item[0] }}`` = ``{{ item[1]|default(' ') }}`` + - {{ item[2] }} +{% endfor %} +{% endfor %}