anodizer_core/template/mod.rs
1// Template rendering powered by Tera.
2// Supports both Go-style `{{ .Field }}` and Tera-style `{{ Field }}`.
3// Go-style templates are preprocessed (leading dots stripped) before Tera renders them.
4// Tera gives us: if/else/endif, for loops, pipes (| lower, | upper, | replace),
5// | default, | trim, | title, and many more built-in filters.
6//
7// ## Template-render-error handling policy
8//
9// **Hard-bail on any user-supplied template render error.**
10//
11// Silently falling back to the raw template string (or to an empty value) on a
12// render failure has burned users repeatedly: a typo like `{{ .Teg }}` in a
13// signature path is rendered-as-literal and the signer is invoked with a path
14// that doesn't exist, producing a confusing downstream error rather than a
15// clear template diagnostic.
16//
17// Callers that render user-supplied templates (config fields, hook commands,
18// signing args, release header/footer, etc.) MUST propagate the
19// `render_template` / `render` error via `?` or `.with_context(...)?`. If you
20// see `.unwrap_or_else(|e| { log.warn(...); raw.clone() })` in lib code,
21// convert it to a bail with a stage-named context message.
22//
23// The single exception is `render_template_opt` for purely internal defaults
24// (e.g. "default icon url") where a render-failure genuinely has a sensible
25// fallback — those sites should be rare and commented.
26//
27// Enforcement: code review + the `anti-patterns.md` hook (which already
28// forbids `.unwrap()` in lib code, catching most drift automatically).
29
30mod base_tera;
31mod render;
32mod static_render;
33mod vars;
34
35#[cfg(test)]
36mod tests;
37
38pub use render::{extract_artifact_ext, render};
39pub use static_render::{parse_static, render_static};
40pub use vars::{
41 PER_ARTIFACT_VARS, PER_TARGET_VARS, TemplateVars, clear_per_artifact_vars,
42 clear_per_target_vars,
43};