From 959637ff59681250fe62c8e0cc7d81989cdc13f5 Mon Sep 17 00:00:00 2001 From: John R Barker Date: Fri, 10 Feb 2017 12:15:55 +0000 Subject: [PATCH] How to document your module (#21021) * How to document your module * Remove blank lines * note:: Versions should be strings * requirements on the host that executes the module. * option names & option values * Feedback * formatting * Scott's final feedback --- .../developing_modules_documenting.rst | 144 ++++++++++++++---- examples/DOCUMENTATION.yml | 36 +++-- 2 files changed, 136 insertions(+), 44 deletions(-) diff --git a/docs/docsite/rst/dev_guide/developing_modules_documenting.rst b/docs/docsite/rst/dev_guide/developing_modules_documenting.rst index 31ee04d1233..83d6ff13723 100644 --- a/docs/docsite/rst/dev_guide/developing_modules_documenting.rst +++ b/docs/docsite/rst/dev_guide/developing_modules_documenting.rst @@ -3,15 +3,16 @@ Documenting Your Module ``````````````````````` -All modules included in the CORE distribution must have a -``DOCUMENTATION`` string. This string MUST be a valid YAML document +The online module documentation is generated from the modules themselves. +As the module documentation is generated from documentation strings contained in the modules, all modules included with Ansible must have a ``DOCUMENTATION`` string. +This string must be a valid YAML document which conforms to the schema defined below. You may find it easier to start writing your ``DOCUMENTATION`` string in an editor with YAML syntax highlighting before you include it in your Python file. -Example -''''''' +DOCUMENTATION Block +''''''''''''''''''' See an example documentation string in the checkout under `examples/DOCUMENTATION.yml `_. @@ -29,30 +30,86 @@ Include it in your module file like this: # ... snip ... ''' -The ``description``, and ``notes`` fields -support formatting with some special macros. -These formatting functions are ``U()``, ``M()``, ``I()``, and ``C()`` -for URL, module, italic, and constant-width respectively. It is suggested -to use ``C()`` for file and option names, and ``I()`` when referencing -parameters; module names should be specified as ``M(module)``. +The following fields can be used and are all required unless specified otherwise: + +* ``module:`` + The name of the module. This must be the same as the filename, without the ``.py`` extension. +* ``short_description:`` + + * A short description which is displayed on the :doc:`../list_of_all_modules` page and ``ansible-doc -l``. + * As the short description is displayed by ``ansible-doc -l`` without the category grouping it needs enough detail to explain its purpose without the context of the directory structure in which it lives. + * Unlike ``description:`` this field should not have a trailing full stop. +* ``description:`` + * A detailed description (generally two or more sentences). + * Must be written in full sentences, i.e. with capital letters and fullstops. + * Shouldn't mention the name module. +* ``version_added:`` + The version of Ansible when the module was added. + This is a `string`, and not a float, i.e. ``version_added: "2.1"`` +* ``author:`` + Name of the module author in the form ``First Last (@GitHubID)``. Use a multi-line list if there is more than one author. +* ``options:`` + One per module argument + + * ``description:`` + + * Detailed explanation of what this option does. It should be written in full sentences. + * Should not list the options values (that's what ``choices:`` is for, though it should explain `what` the values do if they aren't obvious. + * If an argument takes both True)/False and Yes)/No, the documentation should use True and False. + * If an optional parameter is sometimes required this need to be reflected in the documentation, e.g. "Required when I(state=present)." + * Mutually exclusive options must be documented as the final sentence on each of the options. + * ``required:`` + Only needed if true, otherwise it is assumed to be false. + * ``default:`` + + * If `required` is false/missing, `default` may be specified (assumed 'null' if missing). + * Ensure that the default parameter in the docs matches the default parameter in the code. + * The default option must not be listed as part of the description. + * ``choices:`` + List of option values. Should be absent if empty. + * ``aliases:`` + List of option name aliases; generally not needed. + * ``version_added:`` + Only needed if this option was extended after initial Ansible release, i.e. this is greater than the top level `version_added` field. + This is a string, and not a float, i.e. ``version_added: "2.3"``. +* ``requirements:`` + List of requirements, and minimum versions (if applicable) +* ``notes:`` + Details of any important information that doesn't fit in one of the above sections; for example if ``check_mode`` isn't supported, or a link to external documentation. + + + + +EXAMPLES block +'''''''''''''' + +The EXAMPLES section is required for all new modules. + +Examples should demonstrate real world usage, and be written in multi-line plain-text YAML format. + +Ensure that examples are kept in sync with the options during the PR review and any following code refactor. + +As per playbook best practice, a `name:` should be specified. -Examples should be written in YAML format in plain text in an ``EXAMPLES`` string within the module like this:: EXAMPLES = ''' - - modulename: - opt1: arg1 - opt2: arg2 + - name: Ensure foo is installed + modulename: + name: foo + state: present ''' -The EXAMPLES section, just like the documentation section, is required in -all module pull requests for new modules. +If the module returns facts that are often needed, an example of how to use them can be helpful. -The RETURN section documents what the module returns. For each value returned, -provide a ``description``, in what circumstances the value is ``returned``, -the ``type`` of the value and a ``sample``. For example, from -the ``copy`` module:: +RETURN Block +'''''''''''' + +The RETURN section documents what the module returns, and is required for all new modules. + +For each value returned, provide a ``description``, in what circumstances the value is ``returned``, +the ``type`` of the value and a ``sample``. For example, from the ``copy`` module:: RETURN = ''' dest: @@ -73,19 +130,50 @@ the ``copy`` module:: ... ''' -Building & Testing +Formatting options '''''''''''''''''' +These formatting functions are ``U()`` for URLs, ``I()`` for option names, ``C()`` for files and option values and ``M()`` for module names. +Module names should be specified as ``M(module)`` to create a link to the online documentation for that module. -Put your completed module file into the 'library' directory and then + +Example usage:: + + Or if not set the environment variable C(ACME_PASSWORD) will be used. + ... + Required if I(state=present) + ... + Mutually exclusive with I(project_src) and I(files). + ... + See also M(win_copy) or M(win_template). + ... + See U(https://www.ansible.com/tower) for an overview. + + +.. note:: + + If you wish to refer a collection of modules, use ``C(..)``, e.g. ``Refer to the C(win_*) modules.`` + +Documentation fragments +``````````````````````` + +Some categories of modules share common documentation, such as details on how to authenticate options, or file mode settings. Rather than duplicate that information it can be shared using ``docs_fragments``. + +These shared fragments are similar to the standard documentation block used in a module, they are just contained in a ``ModuleDocFragment`` class. + +All the existing ``docs_fragments`` can be found in ``lib/ansible/utils/module_docs_fragments/``. + +To include, simply add in ``extends_documentation_fragment: FRAGMENT_NAME`` into your module. + +Examples can be found by searching for ``extends_documentation_fragment`` under the Ansible source tree. + +Testing documentation +''''''''''''''''''''' + +Put your completed module file into the ``lib/ansible/modules/$CATEGORY/`` directory and then run the command: ``make webdocs``. The new 'modules.html' file will be -built and appear in the 'docsite/' directory. +built in the ``docs/docsite/_build/html/$MODULENAME_module.html`` directory. .. tip:: If you're having a problem with the syntax of your YAML you can validate it on the `YAML Lint `_ website. - -.. tip:: - - You can set the environment variable ANSIBLE_KEEP_REMOTE_FILES=1 on the controlling host to prevent ansible from - deleting the remote files so you can debug your module. diff --git a/examples/DOCUMENTATION.yml b/examples/DOCUMENTATION.yml index 86f9c9462f5..f3b64c21d36 100644 --- a/examples/DOCUMENTATION.yml +++ b/examples/DOCUMENTATION.yml @@ -2,29 +2,33 @@ # If a key doesn't apply to your module (ex: choices, default, or # aliases) you can use the word 'null', or an empty list, [], where # appropriate. +# +# See docs.ansible.com/ansible/dev_guide/developing_modules.html for more information +# module: modulename short_description: This is a sentence describing the module description: - - Longer description of the module - - You might include instructions + - Longer description of the module. + - You might include instructions. version_added: "X.Y" -author: "Your AWESOME name, @awesome-github-id" -notes: - - Other things consumers of your module should know - - Additional setting requirements -requirements: - - list of required things - - like the factor package - - or a specific platform +author: "Your AWESOME name (@awesome-github-id)" options: # One or more of the following option_name: description: - - Words go here - - that describe - - this option + - Description of the options goes here. + - Must be written in sentences. required: true or false default: a string or the word null - choices: [list, of, choices] - aliases: [list, of, aliases] - version_added: 1.X + choices: + - enable + - disable + aliases: + - repo_name + version_added: "1.X" +notes: + - Other things consumers of your module should know. +requirements: + - list of required things. + - like the factor package + - zypper >= 1.0