diff --git a/changelogs/fragments/73-env-vars.yml b/changelogs/fragments/73-env-vars.yml new file mode 100644 index 00000000..a4bab932 --- /dev/null +++ b/changelogs/fragments/73-env-vars.yml @@ -0,0 +1,2 @@ +minor_changes: + - "Use correct markup (``envvar`` role) for environment variables. Allow modules to declare environment variables. Compile an index of all environment variables used by plugins and modules. (https://github.com/ansible-community/antsibull-docs/pull/73)." diff --git a/src/antsibull_docs/cli/doc_commands/stable.py b/src/antsibull_docs/cli/doc_commands/stable.py index 58eab144..317b208d 100644 --- a/src/antsibull_docs/cli/doc_commands/stable.py +++ b/src/antsibull_docs/cli/doc_commands/stable.py @@ -37,6 +37,7 @@ load_all_collection_routing, remove_redirect_duplicates, ) +from ...env_variables import load_ansible_config, collect_referenced_environment_variables from ...schemas.docs import DOCS_SCHEMAS from ...utils.collection_name_transformer import CollectionNameTransformer from ...write_docs import ( @@ -47,6 +48,7 @@ output_indexes, output_plugin_indexes, output_extra_docs, + output_environment_variables, ) if t.TYPE_CHECKING: @@ -337,12 +339,16 @@ def generate_docs_for_all_collections(venv: t.Union[VenvRunner, FakeVenvRunner], app_ctx = app_context.app_ctx.get() # Get the info from the plugins - plugin_info, collection_metadata = asyncio_run(get_ansible_plugin_info( + plugin_info, full_collection_metadata = asyncio_run(get_ansible_plugin_info( venv, collection_dir, collection_names=collection_names)) flog.notice('Finished parsing info from plugins and collections') # flog.fields(plugin_info=plugin_info).debug('Plugin data') # flog.fields( - # collection_metadata=collection_metadata).debug('Collection metadata') + # collection_metadata=full_collection_metadata).debug('Collection metadata') + + collection_metadata = dict(full_collection_metadata) + if collection_names is not None and 'ansible.builtin' not in collection_names: + del collection_metadata['ansible.builtin'] # Load collection routing information collection_routing = asyncio_run(load_all_collection_routing(collection_metadata)) @@ -363,7 +369,7 @@ def generate_docs_for_all_collections(venv: t.Union[VenvRunner, FakeVenvRunner], {name: data.path for name, data in collection_metadata.items()})) flog.debug('Finished getting collection extra docs data') - # Load collection extra docs data + # Load collection links data link_data = asyncio_run(load_collections_links( {name: data.path for name, data in collection_metadata.items()})) flog.debug('Finished getting collection link data') @@ -384,6 +390,10 @@ def generate_docs_for_all_collections(venv: t.Union[VenvRunner, FakeVenvRunner], print(f"{plugin_name} {plugin_type}: {textwrap.indent(error, ' ').lstrip()}") return 1 + # Handle environment variables + ansible_config = load_ansible_config(full_collection_metadata['ansible.builtin']) + referenced_env_vars = collect_referenced_environment_variables(new_plugin_info, ansible_config) + collection_namespaces = get_collection_namespaces(collection_to_plugin_info.keys()) collection_url = CollectionNameTransformer( @@ -444,7 +454,14 @@ def generate_docs_for_all_collections(venv: t.Union[VenvRunner, FakeVenvRunner], asyncio_run(output_extra_docs(dest_dir, extra_docs_data, squash_hierarchy=squash_hierarchy)) - flog.debug('Finished writing extra extra docs docs') + flog.debug('Finished writing extra docs') + + if referenced_env_vars: + asyncio_run(output_environment_variables(dest_dir, referenced_env_vars, + squash_hierarchy=squash_hierarchy)) + flog.debug('Finished writing environment variables') + else: + flog.debug('Skipping environment variables (as there are none)') return 0 diff --git a/src/antsibull_docs/data/docsite/list_of_env_variables.rst.j2 b/src/antsibull_docs/data/docsite/list_of_env_variables.rst.j2 new file mode 100644 index 00000000..3bc499f0 --- /dev/null +++ b/src/antsibull_docs/data/docsite/list_of_env_variables.rst.j2 @@ -0,0 +1,39 @@ +{# + Copyright (c) Ansible Project + GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) + SPDX-License-Identifier: GPL-3.0-or-later +#} + +:orphan: + +.. _list_of_collection_env_vars: + +Index of all Collection Environment Variables +============================================= + +The following index documents all environment variables declared by plugins and modules in collections. +Environment variables used by the ansible-core configuation are documented in :ref:`ansible_configuration_settings`. +{# TODO: use label `ansible_configuration_env_vars` once the ansible-core PR is merged #} + +{% for _, env_var in env_variables | dictsort %} +.. envvar:: @{ env_var.name }@ + +{% for paragraph in env_var.description or [] %} + @{ paragraph | replace('\n', '\n ') | rst_ify | indent(4) }@ + +{% endfor %} + *Used by:* +{% set plugins_ = [] %} +{% for plugin_type, plugins in env_var.plugins.items() %} +{% for plugin_name in plugins %} +{% set _ = plugins_.append((plugin_name, plugin_type)) %} +{% endfor %} +{% endfor %} +{% for plugin_name, plugin_type in plugins_ | unique | sort %} + :ref:`@{ plugin_name | rst_escape }@ {% if plugin_type == 'module' %}module{% else %}@{ plugin_type }@ plugin{% endif %} ` +{%- if not loop.last -%} +, +{% endif -%} +{%- endfor %} + +{% endfor %} diff --git a/src/antsibull_docs/data/docsite/macros/parameters.rst.j2 b/src/antsibull_docs/data/docsite/macros/parameters.rst.j2 index 7e5ae650..ad2fb433 100644 --- a/src/antsibull_docs/data/docsite/macros/parameters.rst.j2 +++ b/src/antsibull_docs/data/docsite/macros/parameters.rst.j2 @@ -99,12 +99,16 @@ :ansible-option-default-bold:`Default:` :ansible-option-default:`@{ value['default'] | antsibull_to_json | rst_escape(escape_ending_whitespace=true) | indent(6, blank=true) }@` {% endif %} {# Configuration #} -{% if plugin_type != 'module' and plugin_type != 'role' and (value['ini'] or value['env'] or value['vars'] or value['cli']) %} +{% if plugin_type != 'role' and (value['ini'] or value['env'] or value['vars'] or value['cli']) %} .. rst-class:: ansible-option-line :ansible-option-configuration:`Configuration:` +{% if plugin_type == 'module' and value['env'] %} + The below environment variable{% if value['env'] | length > 1 %}s{% endif %} will be used on the host that executes this module. + +{% endif %} {% if value['ini'] %} - INI {% if value['ini'] | length == 1 %}entry{% else %}entries{% endif %}: {% for ini in value['ini'] %} @@ -125,14 +129,14 @@ {% endfor %} {% endif %} {% for env in value['env'] %} - - Environment variable: @{ env['name'] | rst_escape }@ + - Environment variable: :envvar:`@{ env['name'] | rst_escape(escape_ending_whitespace=true) }@` {% if env['version_added'] is still_relevant(collection=env['version_added_collection'] or collection) %} :ansible-option-versionadded:`added in @{ version_added_rst(env['version_added'], env['version_added_collection'] or collection) }@` {% endif %} @{ deprecates_rst(env['deprecated'], collection, 8) }@ {% endfor %} -{% for myvar in value['vars'] %} +{% for myvar in value['vars'] | default([]) %} - Variable: @{ myvar['name'] | rst_escape }@ {% if myvar['version_added'] is still_relevant(collection=myvar['version_added_collection'] or collection) %} @@ -140,7 +144,7 @@ {% endif %} @{ deprecates_rst(myvar['deprecated'], collection, 8) }@ {% endfor %} -{% for kw in value['keyword'] %} +{% for kw in value['keyword'] | default([]) %} - Keyword: @{ kw['name'] | rst_escape }@ {% if kw['version_added'] is still_relevant(collection=kw['version_added_collection'] or collection) %} @@ -148,7 +152,7 @@ {% endif %} @{ deprecates_rst(kw['deprecated'], collection, 8) }@ {% endfor %} -{% for mycli in value['cli'] %} +{% for mycli in value['cli'] | default([]) %} - CLI argument: @{ mycli['option'] | rst_escape }@ {% if mycli['version_added'] is still_relevant(collection=mycli['version_added_collection'] or collection) %} @@ -228,7 +232,7 @@

Default: @{ value['default'] | antsibull_to_json | escape | indent(6, blank=true) }@

{% endif %} {# Configuration #} -{% if plugin_type != 'module' and plugin_type != 'role' and (value['ini'] or value['env'] or value['vars'] or value['cli']) %} +{% if plugin_type != 'role' and (value['ini'] or value['env'] or value['vars'] or value['cli']) %}

Configuration:

diff --git a/tests/functional/baseline-use-html-blobs/collections/ns2/col/foo_shell.rst b/tests/functional/baseline-use-html-blobs/collections/ns2/col/foo_shell.rst index 696a1c3f..e582806e 100644 --- a/tests/functional/baseline-use-html-blobs/collections/ns2/col/foo_shell.rst +++ b/tests/functional/baseline-use-html-blobs/collections/ns2/col/foo_shell.rst @@ -119,11 +119,11 @@ Parameters
  • -

    Environment variable: ANSIBLE_REMOTE_TEMP

    +

    Environment variable: ANSIBLE_REMOTE_TEMP

  • -

    Environment variable: ANSIBLE_REMOTE_TMP

    +

    Environment variable: ANSIBLE_REMOTE_TMP

  • diff --git a/tests/functional/baseline-use-html-blobs/collections/ns2/col/foo_vars.rst b/tests/functional/baseline-use-html-blobs/collections/ns2/col/foo_vars.rst index 0cab47d2..080ce90c 100644 --- a/tests/functional/baseline-use-html-blobs/collections/ns2/col/foo_vars.rst +++ b/tests/functional/baseline-use-html-blobs/collections/ns2/col/foo_vars.rst @@ -130,7 +130,7 @@ Parameters
  • -

    Environment variable: ANSIBLE_FOO_FILENAME_EXT

    +

    Environment variable: ANSIBLE_FOO_FILENAME_EXT

  • diff --git a/tests/functional/schema/good_data/one_module_results.json b/tests/functional/schema/good_data/one_module_results.json index 6427467b..a9f68b8d 100644 --- a/tests/functional/schema/good_data/one_module_results.json +++ b/tests/functional/schema/good_data/one_module_results.json @@ -214,6 +214,7 @@ "The groups to add the hostname to." ], "elements": "str", + "env": [], "required": false, "suboptions": {}, "type": "list", @@ -231,6 +232,7 @@ "The hostname/ip of the host to add to the inventory, can include a colon and a port number." ], "elements": "str", + "env": [], "required": true, "suboptions": {}, "type": "str",