feat(scanner): Resolve Askama template dependencies - #126
Conversation
Resolve #[template(path = ...)] attributes to template files within the owning Cargo package, rejecting dynamic or ambiguous targets. Co-Authored-By: GPT-5.6 Sol <codex@openai.com>
JordanCoin
left a comment
There was a problem hiding this comment.
Verified on real Cargo crates. The property that makes this safe: resolution is existence-gated — an edge is only emitted when a file sits at exactly <pkg>/templates/<literal> and is uniquely indexed, with files[0] != target guarding against the index's extension-stripped keys. Tested the case that matters most: a crate with askama.toml pointing at views/ plus a decoy at templates/hello.html produces no edge at all rather than guessing the decoy. #[template(source = "...")] with a same-named decoy file also correctly produces nothing.
On scope — it's a fair question whether codemap should carry per-crate support, and I think this earns it: #[template(path=...)] against <crate>/templates/ is shared by askama, rinja, sailfish and yarte, so it's closer to a Rust convention than one library. And a special case that can only fail closed is much cheaper to own than one that guesses.
Two follow-ups, neither blocking: path must be the first attribute argument, so #[template(escape = "none", path = "x.html")] is silently missed (one more pattern fixes it); and on Windows filepath.IsAbs("/foo.html") is false, so a leading-slash literal resolves there while it's correctly rejected on Unix — a cross-platform divergence worth closing with a strings.HasPrefix(value, "/") check.
If a second template crate ever arrives, please table-drive it (attribute name, default dir, config filename) rather than adding a second resolver — the hard-coded askama.toml check is already the seam.
What does this PR do?
Record file dependencies introduced by literal Askama
#[template(path = "...")]attributes. Paths reuse the existing Rust literal decoder and Cargo package ownership, resolve under the package's defaulttemplates/directory, and are accepted only for one exact configured, indexed in-repository target. Dynamic, malformed, missing, external, excluded, escaping, ambiguous, and unowned routes remain unresolved. Packages withaskama.tomland attributes withconfig = ...also fail closed; custom template-directory configuration is intentionally partial coverage.Type of change
Checklist
go build && ./codemap .CONTRIBUTING.md; this does not add a new language.Additional notes
Focused extraction and conservative-resolution tests, the scanner suite, and staticcheck are GREEN.
Real-world Worktrunk smoke tests recover all six template dependencies from
src/shell/mod.rsto the Bash, Fish, Fish wrapper, Nushell, PowerShell, and Zsh files undertemplates/.This branch targets and contains no generic proc-macro, Cargo-topology, configuration, or non-Rust changes.
Developed with carefully directed, manually reviewed AI assistance.