Krikri::CollectionIndex
Class methods
Could real's plugin loader resolve a BARE lookup plugin name
(query('dig', ...))? Unlike modules/actions - whose bare names
search only ansible.legacy, ansible.builtin and the task's listed
collections - lookup (and filter) names are scanned across EVERY
installed collection (live-verified vs 2.19.11: bare dig/
dnstxt run community.general's own plugins with no collections:
keyword anywhere). The builtin runtime's plugin_routing.lookup
redirect table participates first (redis -> community.general),
so an ansible-core present but redirect-target collection absent
is a definite false, not unsure. nil = unsure (no ansible-core
installation discoverable) - the caller must not refuse on nil.
Is <leaf> an ansible-core builtin module (a module file shipped
inside the ansible-core package)? nil when no ansible-core
installation is discoverable - the caller must then not refuse.
A bare module name's ansible_builtin_runtime.yml redirect target
("modules" routing), when the builtin runtime carries one for it
(bare docker_service: -> community.general.docker_service) - the
hop real's loader takes a bare name through before any target
collection's own meta/runtime.yml (and its tombstones) is
consulted. nil when the name has no builtin-runtime redirect; the
baked 2.19.11 table is the fallback when no ansible-core
installation is discoverable, same as builtin_redirects.
Is the collection directory present under any search root?
Role-private / playbook-adjacent library/<name> module source -
the same lookup PythonModuleRunner.find_source performs at run
time (any extension except Ansible's MODULE_IGNORE_EXTS), so the
parse-time refusal never fires for a module the runner would
actually execute.
The module name real's loader reports after chasing the FULL
redirect chain: ansible_builtin_runtime.yml hops (for a bare name
or an ansible.builtin./ansible.legacy. leaf) and then every target
collection's own meta/runtime.yml plugin_routing.modules redirect,
until no entry matches (cycle-limited like the resolution paths).
The two sources chain: ansible-core's builtin runtime still
redirects the legacy bare hcloud_ssh_key spelling onto
hetzner.hcloud.hcloud_ssh_key, while hetzner.hcloud 7.x's own
runtime.yml renames that FQCN onto the unprefixed module file
hetzner.hcloud.ssh_key - and the name real reports in the
task-args finalization error is the chain END, not the first hop
(issue #800: 'hetzner.hcloud.ssh_key', not the intermediate FQCN,
live-verified vs 2.19.11 for both the bare and the FQCN spelling).
A name with no redirect entry comes back unchanged; a collection
that is not installed ends the chain (no runtime.yml to consult),
exactly where real's loader stops chasing.
Test seam: forget everything scanned, so a spec can point ANSIBLE_COLLECTIONS_PATH at a fixture and rescan (same pattern as ActionGroups.reset!).
A role's own meta/main.yml collections: list - the role's
declaration of the collections its bare module names resolve
through, which ansible-core folds into the task's collection
search (live-verified vs 2.19.11: a role declaring
collections: [community.crypto] resolves its bare
x509_certificate: task). Memoized per role path; a role with no
meta/main.yml or an unreadable one contributes nothing.
Directories that contain an ansible_collections/ subtree, real's
search order. Beyond the env var and the two config-default
locations this also scans the standard Python package directories
for an ansible_collections tree (Debian/Ubuntu install
ansible-core's dependency collections under
/usr/lib/python3/dist-packages/ansible_collections, which
ansible-galaxy collection list reports as a search path) and -
when it can - follows the ansible-playbook on PATH's shebang to
a virtualenv's site-packages, whose collections a bare
dist-packages scan would otherwise miss.