From 840d3a9dd7d1233ab55aa9516fc9b44e4c865a81 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 8 Jun 2020 17:51:33 +0200 Subject: [PATCH] ansible-doc: properly handle suboptions (#69795) * Specifically handle suboptions, contains, etc in ansible-doc. --- .../69795-ansible-doc-suboptions.yml | 2 + lib/ansible/cli/doc.py | 23 +++--- .../library/test_docs_suboptions.py | 70 +++++++++++++++++++ test/integration/targets/ansible-doc/runme.sh | 5 ++ .../ansible-doc/test_docs_suboptions.output | 46 ++++++++++++ 5 files changed, 136 insertions(+), 10 deletions(-) create mode 100644 changelogs/fragments/69795-ansible-doc-suboptions.yml create mode 100644 test/integration/targets/ansible-doc/library/test_docs_suboptions.py create mode 100644 test/integration/targets/ansible-doc/test_docs_suboptions.output diff --git a/changelogs/fragments/69795-ansible-doc-suboptions.yml b/changelogs/fragments/69795-ansible-doc-suboptions.yml new file mode 100644 index 00000000000..8d52aba3fc2 --- /dev/null +++ b/changelogs/fragments/69795-ansible-doc-suboptions.yml @@ -0,0 +1,2 @@ +minor_changes: +- "ansible-doc - improve suboptions formatting (https://github.com/ansible/ansible/pull/69795)." diff --git a/lib/ansible/cli/doc.py b/lib/ansible/cli/doc.py index dec582fb98d..fbf0223baca 100644 --- a/lib/ansible/cli/doc.py +++ b/lib/ansible/cli/doc.py @@ -503,7 +503,7 @@ class DocCLI(CLI): Dumper=AnsibleDumper).split('\n')])) @staticmethod - def add_fields(text, fields, limit, opt_indent): + def add_fields(text, fields, limit, opt_indent, base_indent=''): for o in sorted(fields): opt = fields[o] @@ -516,7 +516,7 @@ class DocCLI(CLI): else: opt_leadin = "-" - text.append("%s %s" % (opt_leadin, o)) + text.append("%s%s %s" % (base_indent, opt_leadin, o)) if isinstance(opt['description'], list): for entry_idx, entry in enumerate(opt['description'], 1): @@ -546,13 +546,10 @@ class DocCLI(CLI): text.append(textwrap.fill(DocCLI.tty_ify(aliases + choices + default), limit, initial_indent=opt_indent, subsequent_indent=opt_indent)) - if 'options' in opt: - text.append("%soptions:\n" % opt_indent) - DocCLI.add_fields(text, opt.pop('options'), limit, opt_indent + opt_indent) - - if 'spec' in opt: - text.append("%sspec:\n" % opt_indent) - DocCLI.add_fields(text, opt.pop('spec'), limit, opt_indent + opt_indent) + suboptions = [] + for subkey in ('options', 'suboptions', 'contains', 'spec'): + if subkey in opt: + suboptions.append((subkey, opt.pop(subkey))) conf = {} for config in ('env', 'ini', 'yaml', 'vars', 'keywords'): @@ -578,7 +575,13 @@ class DocCLI(CLI): text.append(DocCLI.tty_ify('%s%s: %s' % (opt_indent, k, ', '.join(opt[k])))) else: text.append(DocCLI._dump_yaml({k: opt[k]}, opt_indent)) - text.append('') + + for subkey, subdata in suboptions: + text.append('') + text.append("%s%s:\n" % (opt_indent, subkey.upper())) + DocCLI.add_fields(text, subdata, limit, opt_indent + ' ', opt_indent) + if not suboptions: + text.append('') @staticmethod def get_man_text(doc): diff --git a/test/integration/targets/ansible-doc/library/test_docs_suboptions.py b/test/integration/targets/ansible-doc/library/test_docs_suboptions.py new file mode 100644 index 00000000000..c922d1d6cc3 --- /dev/null +++ b/test/integration/targets/ansible-doc/library/test_docs_suboptions.py @@ -0,0 +1,70 @@ +#!/usr/bin/python +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +DOCUMENTATION = ''' +--- +module: test_docs_suboptions +short_description: Test module +description: + - Test module +author: + - Ansible Core Team +options: + with_suboptions: + description: + - An option with suboptions. + - Use with care. + type: dict + suboptions: + z_last: + description: The last suboption. + type: str + m_middle: + description: + - The suboption in the middle. + - Has its own suboptions. + suboptions: + a_suboption: + description: A sub-suboption. + type: str + a_first: + description: The first suboption. + type: str +''' + +EXAMPLES = ''' +''' + +RETURN = ''' +''' + + +from ansible.module_utils.basic import AnsibleModule + + +def main(): + module = AnsibleModule( + argument_spec=dict( + test_docs_suboptions=dict( + type='dict', + options=dict( + a_first=dict(type='str'), + m_middle=dict( + type='dict', + options=dict( + a_suboption=dict(type='str') + ), + ), + z_last=dict(type='str'), + ), + ), + ), + ) + + module.exit_json() + + +if __name__ == '__main__': + main() diff --git a/test/integration/targets/ansible-doc/runme.sh b/test/integration/targets/ansible-doc/runme.sh index 2dc32b8674d..84a69ee103b 100755 --- a/test/integration/targets/ansible-doc/runme.sh +++ b/test/integration/targets/ansible-doc/runme.sh @@ -12,6 +12,11 @@ current_out="$(ansible-doc --playbook-dir ./ testns.testcol.fakemodule)" expected_out="$(cat fakemodule.output)" test "$current_out" == "$expected_out" +# test module docs from collection +current_out="$(ansible-doc --playbook-dir ./ test_docs_suboptions)" +expected_out="$(cat test_docs_suboptions.output)" +test "$current_out" == "$expected_out" + # test listing diff plugin types from collection for ptype in cache inventory lookup vars do diff --git a/test/integration/targets/ansible-doc/test_docs_suboptions.output b/test/integration/targets/ansible-doc/test_docs_suboptions.output new file mode 100644 index 00000000000..fb2a993f237 --- /dev/null +++ b/test/integration/targets/ansible-doc/test_docs_suboptions.output @@ -0,0 +1,46 @@ +> TEST_DOCS_SUBOPTIONS (/home/felix/projects/code/github-cloned/ansible/test/integration/targets/ansible-doc/library/test_docs_suboptions.py) + + Test module + +OPTIONS (= is mandatory): + +- with_suboptions + An option with suboptions. + Use with care. + [Default: (null)] + type: dict + + SUBOPTIONS: + + - a_first + The first suboption. + [Default: (null)] + type: str + + - m_middle + The suboption in the middle. + Has its own suboptions. + [Default: (null)] + + SUBOPTIONS: + + - a_suboption + A sub-suboption. + [Default: (null)] + type: str + + - z_last + The last suboption. + [Default: (null)] + type: str + + +AUTHOR: Ansible Core Team + +EXAMPLES: + + + + +RETURN VALUES: +