diff --git a/docs/bin/dump_config.py b/docs/bin/dump_config.py new file mode 100755 index 0000000000..bc3891d5c5 --- /dev/null +++ b/docs/bin/dump_config.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python + +import optparse +import os +import sys +import yaml + +from jinja2 import Environment, FileSystemLoader + +DEFAULT_TEMPLATE_FILE = 'config.rst.j2' + + +def generate_parser(): + p = optparse.OptionParser( + version='%prog 1.0', + usage='usage: %prog [options]', + description='Generate module documentation from metadata', + ) + p.add_option("-t", "--template-file", action="store", dest="template_file", default=DEFAULT_TEMPLATE_FILE, help="directory containing Jinja2 templates") + p.add_option("-o", "--output-dir", action="store", dest="output_dir", default='/tmp/', help="Output directory for rst files") + p.add_option("-d", "--docs-source", action="store", dest="docs", default=None, help="Source for attribute docs") + + (options, args) = p.parse_args() + + return p + + +def fix_description(config_options): + '''some descriptions are strings, some are lists. workaround it...''' + + for config_key in config_options: + description = config_options[config_key].get('description', []) + if isinstance(description, list): + desc_list = description + else: + desc_list = [description] + config_options[config_key]['description'] = desc_list + return config_options + + +def main(args): + + parser = generate_parser() + (options, args) = parser.parse_args() + + output_dir = os.path.abspath(options.output_dir) + template_file_full_path = os.path.abspath(options.template_file) + template_file = os.path.basename(template_file_full_path) + template_dir = os.path.dirname(os.path.abspath(template_file_full_path)) + + if options.docs: + with open(options.docs) as f: + docs = yaml.safe_load(f) + else: + docs = {} + + config_options = docs + config_options = fix_description(config_options) + + env = Environment(loader=FileSystemLoader(template_dir), trim_blocks=True,) + template = env.get_template(template_file) + output_name = os.path.join(output_dir, template_file.replace('.j2', '')) + temp_vars = {'config_options': config_options} + + with open(output_name, 'w') as f: + f.write(template.render(temp_vars).encode('utf-8')) + + return 0 + + +if __name__ == '__main__': + sys.exit(main(sys.argv[:])) diff --git a/docs/docsite/Makefile b/docs/docsite/Makefile index d3bda5a4ea..d9e759edba 100644 --- a/docs/docsite/Makefile +++ b/docs/docsite/Makefile @@ -3,6 +3,7 @@ SITELIB = $(shell python -c "from distutils.sysconfig import get_python_lib; pri FORMATTER=../bin/plugin_formatter.py TESTING_FORMATTER=../bin/testing_formatter.sh DUMPER=../bin/dump_keywords.py +CONFIG_DUMPER=../bin/dump_config.py ifeq ($(shell echo $(OS) | egrep -ic 'Darwin|FreeBSD|OpenBSD|DragonFly'),1) CPUS ?= $(shell sysctl hw.ncpu|awk '{print $$2}') else @@ -18,7 +19,7 @@ all: docs docs: clean htmldocs -htmldocs: testing keywords modules staticmin +htmldocs: testing keywords modules staticmin config CPUS=$(CPUS) $(MAKE) -f Makefile.sphinx html webdocs: docs @@ -50,6 +51,9 @@ clean: keywords: $(FORMATTER) ../templates/playbooks_keywords.rst.j2 PYTHONPATH=../../lib $(DUMPER) --template-dir=../templates --output-dir=rst/ -d ./keyword_desc.yml +config: + PYTHONPATH=../../lib $(CONFIG_DUMPER) --template-file=../templates/config.rst.j2 --output-dir=rst/ -d ../../lib/ansible/config/base.yml + modules: $(FORMATTER) ../templates/plugin.rst.j2 # Limit building of module documentation if requested. ifdef MODULES diff --git a/docs/docsite/rst/index.rst b/docs/docsite/rst/index.rst index 02e12c97b6..b35235ff73 100644 --- a/docs/docsite/rst/index.rst +++ b/docs/docsite/rst/index.rst @@ -38,6 +38,7 @@ Ansible, Inc. releases a new major release of Ansible approximately every two mo galaxy test_strategies faq + config glossary YAMLSyntax porting_guides diff --git a/docs/templates/config.rst.j2 b/docs/templates/config.rst.j2 new file mode 100644 index 0000000000..5afb76aa0e --- /dev/null +++ b/docs/templates/config.rst.j2 @@ -0,0 +1,69 @@ +{% set name = 'Configuration' -%} +{% set name_slug = 'config' -%} + +{% set name_len = name|length + 0-%} +{{ '=' * name_len }} +{{name}} +{{ '=' * name_len }} + +Common Options +============== + +{% if config_options %} + + +{% for config_option in config_options|sort %} +{% set config_len = config_option|length -%} +{% set config = config_options[config_option] %} +.. _{{config_option}}: + +{{config_option}} +{{ '-' * config_len }} + +{% if config['description'] and config['description'] != [''] %} +{% if config['description'] != ['TODO: write it'] %} +:Description: {{' '.join(config['description'])}} +{% endif %} +{% endif %} +{% if config['type'] %} +:Type: {{config['type']}} +{% endif %} +:Default: {{config['default']}} +{% if config['version_added'] %} +:Version Added: {{config['version_added']}} +{% endif %} +{% for ini_map in config['ini']|sort %} +:Ini Section: {{ini_map['section']}} +:Ini Key: {{ini_map['key']}} +{% endfor %} +{% for env_var_map in config['env']|sort %} +:Environment: :envvar:`{{env_var_map['name']}}` +{% endfor %} +{% if config['deprecated'] %} +:Deprecated in: {{config['deprecated']['version']}} +:Deprecated detail: {{config['deprecated']['why']}} +:Deprecated alternatives: {{config['deprecated']['alternatives']}} +{% endif %} + +{% endfor %} + +Environment Variables +===================== + +{% for config_option in config_options %} +{% for env_var_map in config_options[config_option]['env'] %} +.. envvar:: {{env_var_map['name']}} + +{% if config_options[config_option]['description'] and config_options[config_option]['description'] != [''] %} +{% if config_options[config_option]['description'] != ['TODO: write it'] %} + {{ ''.join(config_options[config_option]['description']) }} +{% endif %} +{% endif %} + + See also :ref:`{{config_option}} <{{config_option}}>` + +{% endfor %} + +{% endfor %} + +{% endif %}