From dc2a79f1c3e45ac9b3c44f8d03b966903ca66de0 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Tue, 6 Sep 2022 16:13:18 -0400 Subject: [PATCH] ansilbe-doc fixes for filters/test listing (#78696) * split filters * listing fixes * return to no docs being exception --- changelogs/fragments/adoc_moarf.yml | 2 ++ lib/ansible/cli/doc.py | 8 +------- lib/ansible/plugins/loader.py | 10 ++++++---- lib/ansible/utils/plugin_docs.py | 12 ++++++------ .../targets/ansible-doc/filter_plugins/other.py | 1 + .../targets/ansible-doc/filter_plugins/split.yml | 1 + test/integration/targets/ansible-doc/runme.sh | 5 +++++ 7 files changed, 22 insertions(+), 17 deletions(-) create mode 100644 changelogs/fragments/adoc_moarf.yml create mode 120000 test/integration/targets/ansible-doc/filter_plugins/split.yml diff --git a/changelogs/fragments/adoc_moarf.yml b/changelogs/fragments/adoc_moarf.yml new file mode 100644 index 00000000000..8d83035562d --- /dev/null +++ b/changelogs/fragments/adoc_moarf.yml @@ -0,0 +1,2 @@ +bugfixes: + - ansible-doc will not again warn and skip when missing docs, always show the doc file (for edit on github) and match legacy plugins. diff --git a/lib/ansible/cli/doc.py b/lib/ansible/cli/doc.py index c93fc9103b4..07abf32f326 100755 --- a/lib/ansible/cli/doc.py +++ b/lib/ansible/cli/doc.py @@ -764,13 +764,7 @@ class DocCLI(CLI, RoleMixin): docs['all'] = {} for ptype in ptypes: - # TODO: remove when we have all shipped plugins of these types documented - # also fail_ok below should be False - if ptype in ('test', 'filter'): - no_fail = True - else: - no_fail = (not context.CLIARGS['no_fail_on_errors']) - + no_fail = bool(not context.CLIARGS['no_fail_on_errors']) if ptype == 'role': roles = self._create_role_list(fail_on_errors=no_fail) docs['all'][ptype] = self._create_role_doc(roles.keys(), context.CLIARGS['entry_point'], fail_on_errors=no_fail) diff --git a/lib/ansible/plugins/loader.py b/lib/ansible/plugins/loader.py index a12aaf01fb3..2e343d0b2e6 100644 --- a/lib/ansible/plugins/loader.py +++ b/lib/ansible/plugins/loader.py @@ -945,10 +945,11 @@ class PluginLoader: found_in_cache = True for i in self._get_paths(): - all_matches.extend(glob.glob(to_native(os.path.join(i, "*.py")))) + # we sort within each path, but keep path precedence from config + all_matches.extend(sorted(glob.glob(to_native(os.path.join(i, "*.py"))), key=os.path.basename)) loaded_modules = set() - for path in sorted(all_matches, key=os.path.basename): + for path in all_matches: name = os.path.splitext(path)[0] basename = os.path.basename(name) @@ -1084,11 +1085,12 @@ class Jinja2Loader(PluginLoader): for func_name, func in plugin_map: fq_name = '.'.join((collection, func_name)) + full = '.'.join((full_name, func_name)) pclass = self._load_jinja2_class() plugin = pclass(func) if plugin in plugins: continue - self._update_object(plugin, fq_name, plugin_path) + self._update_object(plugin, full, plugin_path) plugins.append(plugin) return plugins @@ -1230,7 +1232,7 @@ class Jinja2Loader(PluginLoader): # inputs, we ignore 'dedupe' we always do, used in base class to find files for this one path_only = kwargs.pop('path_only', False) - class_only = kwargs.pop('class_only', False) # basically ignored for test/filters since they are functions + class_only = kwargs.pop('class_only', False) # basically ignored for test/filters since they are functions # Having both path_only and class_only is a coding bug if path_only and class_only: diff --git a/lib/ansible/utils/plugin_docs.py b/lib/ansible/utils/plugin_docs.py index b95a4c0bfde..a4c10229920 100644 --- a/lib/ansible/utils/plugin_docs.py +++ b/lib/ansible/utils/plugin_docs.py @@ -342,15 +342,15 @@ def get_plugin_docs(plugin, plugin_type, loader, fragment_loader, verbose): newfile = _find_adjacent(filename, plugin, C.DOC_EXTENSIONS) if newfile: docs = get_docstring(newfile, fragment_loader, verbose=verbose, collection_name=collection_name, plugin_type=plugin_type) + filename = newfile except Exception as e: raise AnsibleParserError('Adjacent file %s did not contain a DOCUMENTATION attribute (%s)' % (plugin, filename), orig_exc=e) - # got nothing, so this is 'undocumented', but lets populate at least some friendly info - if not docs[0]: - docs[0] = {'description': 'UNDOCUMENTED', 'short_description': 'UNDOCUMENTED'} - # add extra data to docs[0] (aka 'DOCUMENTATION') - docs[0]['filename'] = filename - docs[0]['collection'] = collection_name + if docs[0] is None: + raise AnsibleParserError('No documentation availalbe for %s (%s)' % (plugin, filename)) + else: + docs[0]['filename'] = filename + docs[0]['collection'] = collection_name return docs diff --git a/test/integration/targets/ansible-doc/filter_plugins/other.py b/test/integration/targets/ansible-doc/filter_plugins/other.py index fcc1e10d30c..5619fb299db 100644 --- a/test/integration/targets/ansible-doc/filter_plugins/other.py +++ b/test/integration/targets/ansible-doc/filter_plugins/other.py @@ -20,4 +20,5 @@ class FilterModule(object): return { 'donothing': donothing, 'nodocs': donothing, + 'split': donothing, } diff --git a/test/integration/targets/ansible-doc/filter_plugins/split.yml b/test/integration/targets/ansible-doc/filter_plugins/split.yml new file mode 120000 index 00000000000..7fad18925de --- /dev/null +++ b/test/integration/targets/ansible-doc/filter_plugins/split.yml @@ -0,0 +1 @@ +donothing.yml \ No newline at end of file diff --git a/test/integration/targets/ansible-doc/runme.sh b/test/integration/targets/ansible-doc/runme.sh index fcb858b8296..ef392cf3964 100755 --- a/test/integration/targets/ansible-doc/runme.sh +++ b/test/integration/targets/ansible-doc/runme.sh @@ -175,3 +175,8 @@ ansible-doc --list --module-path ./modules > /dev/null # ensure we dedupe by fqcn and not base name #[ "$(ansible-doc -l -t filter --playbook-dir ./ |grep 'b64decode' | wc -l)" -eq "2"] + +# with playbook dir, legacy should override +ansible-doc -t filter split --playbook-dir ./ |grep histerical +# without playbook dir, builtin should return +ansible-doc -t filter split |grep -v histerical