Krikri::FiletreeLookup
Krikri::FiletreeLookup - a native reimplementation of the
community.general.filetree lookup plugin (with_community.general.filetree:),
translated from community.general/plugins/lookup/filetree.py (verified
against the collection source, not guessed).
Real semantics (all load-bearing for the roles that use it):
- Each term is a directory to walk RECURSIVELY, top-down. Entries are yielded one per file OR subdirectory at every depth - directories first, then files, per level - each as a dict of stat properties.
pathis relative to the walked root;rootis the walked root itself. Multiple terms implement a first-found-ish dedup: a relative path already yielded by an earlier root is skipped.stateis 'directory' / 'file' / 'link' (lstat semantics - the walk never follows symlinks, matching os.walk's default).srcis present ONLY for 'file' (the absolute path) and 'link' (the raw readlink target) - a directory entry has nosrckey at all, which is exactly what roles'when: item.state == 'file'gating leans on.modeis the 4-char octal string ("0" + 3 octal digits, e.g. "0644"); owner/group resolve to NAMES (falling back to the raw uid/gid when the id has no passwd/group entry); mtime/ctime are epoch floats.
A missing root yields no entries rather than failing - os.walk of a nonexistent path simply yields nothing, and real Ansible passes that empty list straight through (a fully-empty loop skips the task; it is never an error).
Missing entirely before - buluma.vector's own "config | Create templates
config skeleton" task (with_community.general.filetree: +
when: item.state == 'directory') had with_community.general.filetree
silently fall through as an unrecognized task key, so item was never
bound and the when: raised "'item.state' is undefined" instead of
iterating the tree (round 300054's warm divergence).
Class methods
Resolves each source (a raw, already-{{ }}-substituted directory path)
to a walked root, walks it, and returns the combined entry list in
real filetree's own yield order. role_path (the current role's
root, when the task runs inside a role) is what a RELATIVE source
resolves against - real Ansible's lookup dwims relative paths through
path_dwim_relative(basedir, 'files', ...), which for a role task
means the role's own files/ directory; an absolute source (the
overwhelmingly common form - {{ role_path }}/templates/config/ and
friends) is used as-is.