summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDag Wieers <dag@wieers.com>2018-12-12 21:19:58 +0100
committerAlicia Cozine <879121+acozine@users.noreply.github.com>2018-12-12 21:19:58 +0100
commitbaf0ad23098565d295e54e30b531dcc2f018f7ac (patch)
treec0497961acafa31e98d55c6132a4e084017a4bed
parentFix example with spacing error in hostname (#49812) (diff)
downloadansible-baf0ad23098565d295e54e30b531dcc2f018f7ac.tar.xz
ansible-baf0ad23098565d295e54e30b531dcc2f018f7ac.zip
Docs: Add a "seealso" section to the module docs (#45949)
* Docs: Add a separate "seealso" section to the module docs to list related modules and/or related references. This clears up the notes section for things that are actual notes. So you can add a section in your module documentation and four types of references are possible. seealso: # Reference by module name - module: aci_tenant # Reference by module name, including description - module: aci_tenant description: ACI module to create tenants on a Cisco ACI fabric. # Reference by rST documentation anchor - ref: aci_guide description: Detailed information on how to manage your ACI infrastructure using Ansible. # Reference by Internet resource - name: APIC Management Information Model reference description: Complete reference of the APIC object model. link: https://developer.cisco.com/docs/apic-mim-ref/ This PR also includes: - Implements ansible-doc support - Implements schema support for the seealso options - Updates to the development documentation - Rename filter convert_symbols_to_format to rst_ify, cfr the existing html_ify and tty_ify filters - This makes the existing template a lot easier to read and fixes the confusion I had myself rereading the template (again). - We fixed the possible suboption types (which was limited to 'bool' only) * Use latest stable instead of devel docs
-rwxr-xr-xdocs/bin/plugin_formatter.py3
-rw-r--r--docs/docsite/rst/dev_guide/developing_modules_documenting.rst35
-rw-r--r--docs/templates/plugin.rst.j243
-rw-r--r--lib/ansible/cli/doc.py57
-rw-r--r--lib/ansible/modules/network/aci/aci_bd_subnet.py5
-rw-r--r--lib/ansible/parsing/plugin_docs.py6
-rw-r--r--lib/ansible/utils/module_docs_fragments/aci.py8
-rw-r--r--lib/ansible/utils/plugin_docs.py7
-rw-r--r--test/sanity/validate-modules/schema.py41
9 files changed, 153 insertions, 52 deletions
diff --git a/docs/bin/plugin_formatter.py b/docs/bin/plugin_formatter.py
index 2d612a4605..cfcd9c0399 100755
--- a/docs/bin/plugin_formatter.py
+++ b/docs/bin/plugin_formatter.py
@@ -207,6 +207,7 @@ def get_plugin_info(module_dir, limit_to=None, verbose=False):
:aliases: set of aliases to this module name
:metadata: The modules metadata (as recorded in the module)
:doc: The documentation structure for the module
+ :seealso: The list of dictionaries with references to related subjects
:examples: The module's examples
:returndocs: The module's returndocs
@@ -363,7 +364,7 @@ def jinja2_environment(template_dir, typ, plugin_type):
templates = {}
if typ == 'rst':
- env.filters['convert_symbols_to_format'] = rst_ify
+ env.filters['rst_ify'] = rst_ify
env.filters['html_ify'] = html_ify
env.filters['fmt'] = rst_fmt
env.filters['xline'] = rst_xline
diff --git a/docs/docsite/rst/dev_guide/developing_modules_documenting.rst b/docs/docsite/rst/dev_guide/developing_modules_documenting.rst
index 6c7755b068..66e6606db2 100644
--- a/docs/docsite/rst/dev_guide/developing_modules_documenting.rst
+++ b/docs/docsite/rst/dev_guide/developing_modules_documenting.rst
@@ -224,7 +224,34 @@ All fields in the ``DOCUMENTATION`` block are lower-case. All fields are require
:notes:
* Details of any important information that doesn't fit in one of the above sections.
- * For example, whether ``check_mode`` is or is not supported, or links to external documentation.
+ * For example, whether ``check_mode`` is or is not supported.
+
+:seealso:
+
+ * A list of references to other modules, documentation or Internet resources
+ * A reference can be one of the following formats:
+
+
+ .. code-block:: yaml+jinja
+
+ seealso::
+
+ # Reference by module name
+ - module: aci_tenant
+
+ # Reference by module name, including description
+ - module: aci_tenant
+ description: ACI module to create tenants on a Cisco ACI fabric.
+
+ # Reference by rST documentation anchor
+ - ref: aci_guide
+ description: Detailed information on how to manage your ACI infrastructure using Ansible.
+
+ # Reference by Internet resource
+ - name: APIC Management Information Model reference
+ description: Complete reference of the APIC object model.
+ link: https://developer.cisco.com/docs/apic-mim-ref/
+
Linking within module documentation
-----------------------------------
@@ -239,7 +266,8 @@ You can link from your module documentation to other module docs, other resource
.. note::
- To refer a collection of modules, use ``C(..)``, e.g. ``Refer to the C(win_*) modules.``
+ - To refer a collection of modules, use ``C(..)``, e.g. ``Refer to the C(win_*) modules.``
+ - Because it stands out better, using ``seealso`` is preferred for general references over the use of notes or adding links to the description.
Documentation fragments
-----------------------
@@ -248,10 +276,13 @@ If you're writing multiple related modules, they may share common documentation,
For example, all AWS modules should include::
+.. code-block:: yaml+jinja
+
extends_documentation_fragment:
- aws
- ec2
+
You can find more examples by searching for ``extends_documentation_fragment`` under the Ansible source tree.
.. _examples_block:
diff --git a/docs/templates/plugin.rst.j2 b/docs/templates/plugin.rst.j2
index 095b9aa346..7e971a4c6a 100644
--- a/docs/templates/plugin.rst.j2
+++ b/docs/templates/plugin.rst.j2
@@ -11,7 +11,7 @@
{% endfor %}
{% if short_description %}
-{% set title = module + ' - ' + short_description|convert_symbols_to_format %}
+{% set title = module + ' - ' + short_description | rst_ify %}
{% else %}
{% set title = module %}
{% endif %}
@@ -39,9 +39,9 @@
DEPRECATED
----------
{# use unknown here? skip the fields? #}
-:Removed in Ansible: version: @{ deprecated['removed_in'] | default('') | string | convert_symbols_to_format }@
-:Why: @{ deprecated['why'] | default('') | convert_symbols_to_format }@
-:Alternative: @{ deprecated['alternative'] | default('')| convert_symbols_to_format }@
+:Removed in Ansible: version: @{ deprecated['removed_in'] | default('') | string | rst_ify }@
+:Why: @{ deprecated['why'] | default('') | rst_ify }@
+:Alternative: @{ deprecated['alternative'] | default('') | rst_ify }@
{% endif %}
@@ -51,10 +51,10 @@ Synopsis
{% if description -%}
{% if description is string -%}
-- @{ description | convert_symbols_to_format }@
+- @{ description | rst_ify }@
{% else %}
{% for desc in description %}
-- @{ desc | convert_symbols_to_format }@
+- @{ desc | rst_ify }@
{% endfor %}
{% endif %}
@@ -75,7 +75,7 @@ The below requirements are needed on the local master node that executes this @{
{% endif %}
{% for req in requirements %}
-- @{ req | convert_symbols_to_format }@
+- @{ req | rst_ify }@
{% endfor %}
{% endif %}
@@ -206,17 +206,40 @@ Parameters
{% endif %}
{% if notes -%}
-
Notes
-----
.. note::
{% for note in notes %}
- - @{ note | convert_symbols_to_format }@
+ - @{ note | rst_ify }@
{% endfor %}
{% endif %}
+{% if seealso -%}
+See Also
+--------
+
+.. seealso::
+
+{% for item in seealso %}
+{% if item.module is defined and item.description is defined %}
+ :ref:`Module @{ item.module }@ <@{ item.module }@_module>`
+ @{ item.description | rst_ify }@
+{% elif item.module is defined %}
+ :ref:`@{ item.module }@_module`
+ The official documentation on the **@{ item.module }@** module.
+{% elif item.name is defined and item.link is defined and item.description is defined %}
+ `@{ item.name }@ <@{ item.link }@>`_
+ @{ item.description | rst_ify }@
+{% elif item.ref is defined and item.description is defined %}
+ :ref:`@{ item.ref }@`
+ @{ item.description | rst_ify }@
+{% endif %}
+{% endfor %}
+
+{% endif %}
+
{% if examples or plainexamples -%}
Examples
@@ -421,7 +444,7 @@ please refer to this `Knowledge Base article <https://access.redhat.com/articles
{% else %}
-This @{ plugin_type }@ is flagged as **deprecated** and will be removed in version @{ deprecated['removed_in'] | default('') | string | convert_symbols_to_format }@. For more information see `DEPRECATED`_.
+This @{ plugin_type }@ is flagged as **deprecated** and will be removed in version @{ deprecated['removed_in'] | default('') | string | rst_ify }@. For more information see `DEPRECATED`_.
{% endif %}
diff --git a/lib/ansible/cli/doc.py b/lib/ansible/cli/doc.py
index 256c68779f..bb541145eb 100644
--- a/lib/ansible/cli/doc.py
+++ b/lib/ansible/cli/doc.py
@@ -1,17 +1,5 @@
-# (c) 2014, James Tanner <tanner.jc@gmail.com>
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+# Copyright: (c) 2014, James Tanner <tanner.jc@gmail.com>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
@@ -573,8 +561,45 @@ class DocCLI(CLI):
for note in doc['notes']:
text.append(textwrap.fill(CLI.tty_ify(note), limit - 6, initial_indent=opt_indent[:-2] + "* ", subsequent_indent=opt_indent))
text.append('')
+ text.append('')
del doc['notes']
+ if 'seealso' in doc and doc['seealso']:
+ text.append("SEE ALSO:")
+ for item in doc['seealso']:
+ if 'module' in item and 'description' in item:
+ text.append(textwrap.fill(CLI.tty_ify('Module %s' % item['module']),
+ limit - 6, initial_indent=opt_indent[:-2] + "* ", subsequent_indent=opt_indent))
+ text.append(textwrap.fill(CLI.tty_ify(item['description']),
+ limit - 6, initial_indent=opt_indent, subsequent_indent=opt_indent))
+ text.append(textwrap.fill(CLI.tty_ify('https://docs.ansible.com/ansible/latest/modules/%s_module.html' % item['module']),
+ limit - 6, initial_indent=opt_indent + ' ', subsequent_indent=opt_indent))
+ elif 'module' in item:
+ text.append(textwrap.fill(CLI.tty_ify('Module %s' % item['module']),
+ limit - 6, initial_indent=opt_indent[:-2] + "* ", subsequent_indent=opt_indent))
+ text.append(textwrap.fill(CLI.tty_ify('The official documentation on the %s module.' % item['module']),
+ limit - 6, initial_indent=opt_indent + ' ', subsequent_indent=opt_indent + ' '))
+ text.append(textwrap.fill(CLI.tty_ify('https://docs.ansible.com/ansible/latest/modules/%s_module.html' % item['module']),
+ limit - 6, initial_indent=opt_indent + ' ', subsequent_indent=opt_indent))
+ elif 'name' in item and 'link' in item and 'description' in item:
+ text.append(textwrap.fill(CLI.tty_ify(item['name']),
+ limit - 6, initial_indent=opt_indent[:-2] + "* ", subsequent_indent=opt_indent))
+ text.append(textwrap.fill(CLI.tty_ify(item['description']),
+ limit - 6, initial_indent=opt_indent + ' ', subsequent_indent=opt_indent + ' '))
+ text.append(textwrap.fill(CLI.tty_ify(item['link']),
+ limit - 6, initial_indent=opt_indent + ' ', subsequent_indent=opt_indent + ' '))
+ elif 'ref' in item and 'description' in item:
+ text.append(textwrap.fill(CLI.tty_ify('Ansible documentation [%s]' % item['ref']),
+ limit - 6, initial_indent=opt_indent[:-2] + "* ", subsequent_indent=opt_indent))
+ text.append(textwrap.fill(CLI.tty_ify(item['description']),
+ limit - 6, initial_indent=opt_indent + ' ', subsequent_indent=opt_indent + ' '))
+ text.append(textwrap.fill(CLI.tty_ify('https://docs.ansible.com/ansible/latest/#stq=%s&stp=1' % item['ref']),
+ limit - 6, initial_indent=opt_indent + ' ', subsequent_indent=opt_indent + ' '))
+
+ text.append('')
+ text.append('')
+ del doc['seealso']
+
if 'requirements' in doc and doc['requirements'] is not None and len(doc['requirements']) > 0:
req = ", ".join(doc.pop('requirements'))
text.append("REQUIREMENTS:%s\n" % textwrap.fill(CLI.tty_ify(req), limit - 16, initial_indent=" ", subsequent_indent=opt_indent))
@@ -594,14 +619,16 @@ class DocCLI(CLI):
if 'plainexamples' in doc and doc['plainexamples'] is not None:
text.append("EXAMPLES:")
+ text.append('')
if isinstance(doc['plainexamples'], string_types):
text.append(doc.pop('plainexamples').strip())
else:
text.append(yaml.dump(doc.pop('plainexamples'), indent=2, default_flow_style=False))
text.append('')
+ text.append('')
if 'returndocs' in doc and doc['returndocs'] is not None:
- text.append("RETURN VALUES:\n")
+ text.append("RETURN VALUES:")
if isinstance(doc['returndocs'], string_types):
text.append(doc.pop('returndocs'))
else:
diff --git a/lib/ansible/modules/network/aci/aci_bd_subnet.py b/lib/ansible/modules/network/aci/aci_bd_subnet.py
index 80daa14786..f4e743a126 100644
--- a/lib/ansible/modules/network/aci/aci_bd_subnet.py
+++ b/lib/ansible/modules/network/aci/aci_bd_subnet.py
@@ -21,8 +21,9 @@ notes:
is required when the state is C(absent) or C(present).
- The C(tenant) and C(bd) used must exist before using this module in your playbook.
The M(aci_tenant) module and M(aci_bd) can be used for these.
-- More information about the internal APIC class B(fv:Subnet) from
- L(the APIC Management Information Model reference,https://developer.cisco.com/docs/apic-mim-ref/).
+seealso:
+- module: aci_bd
+- module: aci_tenant
author:
- Jacob McGill (@jmcgill298)
version_added: '2.4'
diff --git a/lib/ansible/parsing/plugin_docs.py b/lib/ansible/parsing/plugin_docs.py
index d589fa9770..15b2ba72e9 100644
--- a/lib/ansible/parsing/plugin_docs.py
+++ b/lib/ansible/parsing/plugin_docs.py
@@ -1,7 +1,6 @@
-# Copyright (c) 2017 Ansible Project
+# Copyright: (c) 2017, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
@@ -26,7 +25,8 @@ def read_docstring(filename, verbose=True, ignore_errors=True):
'doc': None,
'plainexamples': None,
'returndocs': None,
- 'metadata': None
+ 'metadata': None,
+ 'seealso': None,
}
string_to_vars = {
diff --git a/lib/ansible/utils/module_docs_fragments/aci.py b/lib/ansible/utils/module_docs_fragments/aci.py
index 71e3e48e4a..24e927f967 100644
--- a/lib/ansible/utils/module_docs_fragments/aci.py
+++ b/lib/ansible/utils/module_docs_fragments/aci.py
@@ -2,7 +2,6 @@
# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com>
# Copyright: (c) 2017, Swetha Chunduri (@schunduri)
-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
@@ -70,6 +69,9 @@ options:
- This should only set to C(no) when used on personally controlled sites using self-signed certificates.
type: bool
default: 'yes'
-notes:
-- Please read the :ref:`aci_guide` for more detailed information on how to manage your ACI infrastructure using Ansible.
+seealso:
+- ref: aci_guide
+ description: Detailed information on how to manage your ACI infrastructure using Ansible.
+- ref: aci_dev_guide
+ description: Detailed guide on how to write your own Cisco ACI modules to contribute.
'''
diff --git a/lib/ansible/utils/plugin_docs.py b/lib/ansible/utils/plugin_docs.py
index 30816462db..6bf9d2a801 100644
--- a/lib/ansible/utils/plugin_docs.py
+++ b/lib/ansible/utils/plugin_docs.py
@@ -69,6 +69,13 @@ def add_fragments(doc, filename, fragment_loader):
doc['notes'] = []
doc['notes'].extend(notes)
+ if 'seealso' in fragment:
+ seealso = fragment.pop('seealso')
+ if seealso:
+ if 'seealso' not in doc:
+ doc['seealso'] = []
+ doc['seealso'].extend(seealso)
+
if 'options' not in fragment:
raise Exception("missing options in fragment (%s), possibly misformatted?: %s" % (fragment_name, filename))
diff --git a/test/sanity/validate-modules/schema.py b/test/sanity/validate-modules/schema.py
index 0c98b679a3..1f77b2dc2d 100644
--- a/test/sanity/validate-modules/schema.py
+++ b/test/sanity/validate-modules/schema.py
@@ -1,20 +1,8 @@
# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2015 Matt Martz <matt@sivel.net>
-# Copyright (C) 2015 Rackspace US, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Copyright: (c) 2015, Matt Martz <matt@sivel.net>
+# Copyright: (c) 2015, Rackspace US, Inc.
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
import re
from voluptuous import ALLOW_EXTRA, PREVENT_EXTRA, All, Any, Length, Invalid, Required, Schema, Self
@@ -47,6 +35,26 @@ def sequence_of_sequences(min=None, max=None):
)
+seealso_schema = Schema(
+ [
+ Any(
+ {
+ Required('module'): Any(*string_types),
+ 'description': Any(*string_types),
+ },
+ {
+ Required('ref'): Any(*string_types),
+ Required('description'): Any(*string_types),
+ },
+ {
+ Required('name'): Any(*string_types),
+ Required('link'): Any(*string_types),
+ Required('description'): Any(*string_types),
+ },
+ ),
+ ]
+)
+
ansible_module_kwargs_schema = Schema(
{
'argument_spec': dict,
@@ -174,6 +182,7 @@ def doc_schema(module_name):
Required('version_added'): Any(float, *string_types),
Required('author'): All(Any(None, list_string_types, *string_types), author),
'notes': Any(None, list_string_types),
+ 'seealso': Any(None, seealso_schema),
'requirements': list_string_types,
'todo': Any(None, list_string_types, *string_types),
'options': Any(None, *list_dict_option_schema),