Skip to content

Commit 0b0e44c

Browse files
Callback plugins: show type, render indexes of callback plugins per type (#90)
* Show callback type, and render callback type indexes. * Undo changes necessary for #65. * Update tests. * Improve callback docs. * Apply suggestions from code review Co-authored-by: Sandra McCann <samccann@redhat.com> Co-authored-by: Sandra McCann <samccann@redhat.com>
1 parent 022c6b6 commit 0b0e44c

File tree

17 files changed

+265
-1
lines changed

17 files changed

+265
-1
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
minor_changes:
2+
- "Show callback plugin type on callback plugin pages. Also write callback indexes by callback plugin type (https://github.com/ansible-community/antsibull-docs/issues/89, https://github.com/ansible-community/antsibull-docs/pull/90)."

src/antsibull_docs/cli/doc_commands/stable.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@
4141
from ...utils.collection_name_transformer import CollectionNameTransformer
4242
from ...write_docs.collections import output_extra_docs, output_indexes
4343
from ...write_docs.hierarchy import output_collection_index, output_collection_namespace_indexes
44-
from ...write_docs.indexes import output_environment_variables, output_plugin_indexes
44+
from ...write_docs.indexes import (
45+
output_callback_indexes,
46+
output_environment_variables,
47+
output_plugin_indexes,
48+
)
4549
from ...write_docs.plugin_stubs import output_all_plugin_stub_rst
4650
from ...write_docs.plugins import output_all_plugin_rst
4751

@@ -269,6 +273,35 @@ def get_plugin_contents(plugin_info: t.Mapping[str, t.Mapping[str, t.Any]],
269273
return plugin_contents
270274

271275

276+
def get_callback_plugin_contents(plugin_info: t.Mapping[str, t.Mapping[str, t.Any]],
277+
) -> t.DefaultDict[str, t.DefaultDict[str, t.Dict[str, str]]]:
278+
"""
279+
Return the collections with their plugins for every callback plugin type.
280+
281+
:arg plugin_info: Mapping of plugin type to a mapping of plugin name to plugin record.
282+
The plugin_type, plugin_name, and short_description from plugin_records are used.
283+
:returns: A Mapping of callback plugin type to a mapping of collection name to a mapping of
284+
plugin names to short_descriptions.
285+
callback_type:
286+
collection:
287+
- plugin_short_name: short_description
288+
"""
289+
callback_plugin_contents: t.DefaultDict[str, t.DefaultDict[str, t.Dict[str, str]]]
290+
callback_plugin_contents = defaultdict(lambda: defaultdict(dict))
291+
292+
if plugin_info.get('callback'):
293+
for plugin_name, plugin_desc in plugin_info['callback'].items():
294+
if 'doc' in plugin_desc:
295+
desc = plugin_desc['doc'].get('short_description') or ''
296+
callback_type = plugin_desc['doc'].get('type') or ''
297+
if callback_type:
298+
namespace, collection, short_name = get_fqcn_parts(plugin_name)
299+
collection_name = '.'.join((namespace, collection))
300+
callback_plugin_contents[callback_type][collection_name][short_name] = desc
301+
302+
return callback_plugin_contents
303+
304+
272305
def get_collection_contents(plugin_content: t.Mapping[str, t.Mapping[str, t.Mapping[str, str]]],
273306
) -> t.DefaultDict[str, t.Dict[str, t.Mapping[str, str]]]:
274307
"""
@@ -369,6 +402,7 @@ def generate_docs_for_all_collections(venv: t.Union[VenvRunner, FakeVenvRunner],
369402
flog.debug('Finished getting collection link data')
370403

371404
plugin_contents = get_plugin_contents(new_plugin_info, nonfatal_errors)
405+
callback_plugin_contents = get_callback_plugin_contents(new_plugin_info)
372406
collection_to_plugin_info = get_collection_contents(plugin_contents)
373407
# Make sure collections without documentable plugins are mentioned
374408
for collection in collection_metadata:
@@ -414,6 +448,11 @@ def generate_docs_for_all_collections(venv: t.Union[VenvRunner, FakeVenvRunner],
414448
collection_install=collection_install,
415449
for_official_docsite=for_official_docsite))
416450
flog.notice('Finished writing plugin indexes')
451+
asyncio_run(output_callback_indexes(callback_plugin_contents,
452+
dest_dir, collection_url=collection_url,
453+
collection_install=collection_install,
454+
for_official_docsite=for_official_docsite))
455+
flog.notice('Finished writing callback plugin indexes')
417456

418457
asyncio_run(output_indexes(collection_to_plugin_info, dest_dir,
419458
collection_url=collection_url,
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{#
2+
Copyright (c) Ansible Project
3+
GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
4+
SPDX-License-Identifier: GPL-3.0-or-later
5+
#}
6+
7+
:orphan:
8+
9+
.. _list_of_@{ callback_type }@_callback_plugins:
10+
11+
Index of all @{ callback_type | capitalize }@ Callback Plugins
12+
=============@{ '=' * (callback_type | length) }@=================
13+
14+
See :ref:`list_of_callback_plugins` for the list of *all* callback plugins.
15+
16+
{% for collection_name, plugins in per_collection_plugins.items() | sort %}
17+
@{ collection_name }@
18+
@{ '-' * (collection_name | length) }@
19+
20+
{% for plugin_name, plugin_desc in plugins.items() | sort %}
21+
* :ref:`@{ collection_name }@.@{ plugin_name }@ <ansible_collections.@{ collection_name }@.@{ plugin_name }@_callback>` -- @{ plugin_desc | rst_ify }@
22+
{% endfor %}
23+
24+
{% else %}
25+
No public @{ callback_type }@ callback plugin found.
26+
{% endfor %}

src/antsibull_docs/data/docsite/list_of_plugins.rst.j2

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ Index of all Roles
1818
Index of all @{ plugin_type | capitalize }@ Plugins
1919
=============@{ '=' * (plugin_type | length) }@========
2020
{% endif %}
21+
{% if plugin_type == 'callback' %}
22+
23+
.. toctree::
24+
:maxdepth: 1
25+
:caption: List of callback plugins by callback type
26+
:glob:
27+
28+
callback_index_*
29+
30+
{% endif %}
2131

2232
{% for collection_name, plugins in per_collection_plugins.items() | sort %}
2333
@{ collection_name }@

src/antsibull_docs/data/docsite/plugin.rst.j2

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,20 @@ DEPRECATED
139139
:Alternative: @{ doc['deprecated']['alternative'] | rst_ify }@
140140
{% endif %}
141141

142+
{% if plugin_type == 'callback' %}
143+
Callback plugin
144+
---------------
145+
146+
{% if doc['type'] == 'stdout' %}
147+
This plugin is a **stdout callback**. You can use only use one stdout callback at a time. Additional aggregate or notification callbacks can be enabled though.
148+
{% elif doc['type'] == 'aggregate' %}
149+
This plugin is an **aggregate callback**. It adds additional console output next to the configured stdout callback.
150+
{% elif doc['type'] == 'notification' %}
151+
This plugin is a **notification callback**. It sends information for a playbook run to other applications, services, or systems.
152+
{% endif %}
153+
See :ref:`callback_plugins` for more information on callback plugins.
154+
155+
{% endif %}
142156
Synopsis
143157
--------
144158

src/antsibull_docs/write_docs/indexes.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,33 @@
2424
mlog = log.fields(mod=__name__)
2525

2626

27+
async def write_callback_type_index(callback_type: str,
28+
per_collection_plugins: t.Mapping[str, t.Mapping[str, str]],
29+
template: Template,
30+
dest_filename: str,
31+
for_official_docsite: bool = False) -> None:
32+
"""
33+
Write an index page for each plugin type.
34+
35+
:arg callback_type: The callback plugin type to write the index for.
36+
:arg per_collection_plugins: Mapping of collection_name to Mapping of plugin_name to
37+
short_description.
38+
:arg template: A template to render the plugin index.
39+
:arg dest_filename: The destination filename.
40+
:kwarg for_official_docsite: Default False. Set to True to use wording specific for the
41+
official docsite on docs.ansible.com.
42+
"""
43+
index_contents = _render_template(
44+
template,
45+
dest_filename,
46+
callback_type=callback_type,
47+
per_collection_plugins=per_collection_plugins,
48+
for_official_docsite=for_official_docsite,
49+
)
50+
51+
await write_file(dest_filename, index_contents)
52+
53+
2754
async def write_plugin_type_index(plugin_type: str,
2855
per_collection_plugins: t.Mapping[str, t.Mapping[str, str]],
2956
template: Template,
@@ -51,6 +78,53 @@ async def write_plugin_type_index(plugin_type: str,
5178
await write_file(dest_filename, index_contents)
5279

5380

81+
async def output_callback_indexes(plugin_info: PluginCollectionInfoT,
82+
dest_dir: str,
83+
collection_url: CollectionNameTransformer,
84+
collection_install: CollectionNameTransformer,
85+
for_official_docsite: bool = False) -> None:
86+
"""
87+
Generate top-level callback plugin index pages for all callback plugins of a type in all
88+
collections.
89+
90+
:arg plugin_info: Mapping of callback_type to Mapping of collection_name to Mapping of
91+
plugin_name to short_description.
92+
:arg dest_dir: The directory to place the documentation in.
93+
:kwarg for_official_docsite: Default False. Set to True to use wording specific for the
94+
official docsite on docs.ansible.com.
95+
"""
96+
flog = mlog.fields(func='output_callback_indexes')
97+
flog.debug('Enter')
98+
99+
env = doc_environment(
100+
('antsibull_docs.data', 'docsite'),
101+
collection_url=collection_url,
102+
collection_install=collection_install)
103+
# Get the templates
104+
plugin_list_tmpl = env.get_template('list_of_callback_plugins.rst.j2')
105+
106+
collection_toplevel = os.path.join(dest_dir, 'collections')
107+
flog.fields(toplevel=collection_toplevel, exists=os.path.isdir(collection_toplevel)).debug(
108+
'collection_toplevel exists?')
109+
# This is only safe because we made sure that the top of the directory tree we're writing to
110+
# (docs/docsite/rst) is only writable by us.
111+
os.makedirs(collection_toplevel, mode=0o755, exist_ok=True)
112+
113+
writers = []
114+
lib_ctx = app_context.lib_ctx.get()
115+
async with asyncio_pool.AioPool(size=lib_ctx.thread_max) as pool:
116+
for callback_type, per_collection_data in plugin_info.items():
117+
filename = os.path.join(collection_toplevel, f'callback_index_{callback_type}.rst')
118+
writers.append(await pool.spawn(
119+
write_callback_type_index(
120+
callback_type, per_collection_data, plugin_list_tmpl,
121+
filename, for_official_docsite=for_official_docsite)))
122+
123+
await asyncio.gather(*writers)
124+
125+
flog.debug('Leave')
126+
127+
54128
async def output_plugin_indexes(plugin_info: PluginCollectionInfoT,
55129
dest_dir: str,
56130
collection_url: CollectionNameTransformer,
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
:orphan:
3+
4+
.. _list_of_stdout_callback_plugins:
5+
6+
Index of all Stdout Callback Plugins
7+
====================================
8+
9+
See :ref:`list_of_callback_plugins` for the list of *all* callback plugins.
10+
11+
ns2.col
12+
-------
13+
14+
* :ref:`ns2.col.foo <ansible_collections.ns2.col.foo_callback>` -- Foo output
15+

tests/functional/baseline-default/collections/index_callback.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@
66
Index of all Callback Plugins
77
=============================
88

9+
.. toctree::
10+
:maxdepth: 1
11+
:caption: List of callback plugins by callback type
12+
:glob:
13+
14+
callback_index_*
15+
16+
917
ns2.col
1018
-------
1119

tests/functional/baseline-default/collections/ns2/col/foo_callback.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ New in ns2.col 0.0.1
6262
.. Deprecated
6363
6464
65+
Callback plugin
66+
---------------
67+
68+
This plugin is a **stdout callback**. You can use only use one stdout callback at a time. Additional aggregate or notification callbacks can be enabled though.
69+
See :ref:`callback_plugins` for more information on callback plugins.
70+
6571
Synopsis
6672
--------
6773

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
:orphan:
3+
4+
.. _list_of_stdout_callback_plugins:
5+
6+
Index of all Stdout Callback Plugins
7+
====================================
8+
9+
See :ref:`list_of_callback_plugins` for the list of *all* callback plugins.
10+
11+
ns2.col
12+
-------
13+
14+
* :ref:`ns2.col.foo <ansible_collections.ns2.col.foo_callback>` -- Foo output
15+

0 commit comments

Comments
 (0)