Skip to content

perf(config): skip tera render for plain strings#9833

Merged
jdx merged 5 commits into
jdx:mainfrom
risu729:codex/tera-render-skip
May 14, 2026
Merged

perf(config): skip tera render for plain strings#9833
jdx merged 5 commits into
jdx:mainfrom
risu729:codex/tera-render-skip

Conversation

@risu729

@risu729 risu729 commented May 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add shared detection for likely Tera template syntax and skip Tera work for plain strings
  • move checks before context construction, async context fetches, and get_tera setup at render call sites
  • keep direct Tera::render_str behind src/tera.rs, and use guarded render_str calls after an early syntax check to avoid redundant re-checks
  • preserve non-Tera side effects, including task dependency shell-style env parsing and env shell expansion, on plain strings

Why this is safe

  • mise is pinned to Tera 1.20.1, whose grammar starts every variable, tag, and comment block with {{, {%, or {#. That includes whitespace-trimmed forms like {{-, {%-, and {#-.
  • The skip only applies when none of those markers are present. In that case Tera has no template block to execute; Tera::render_str would add and render a one-off raw template that returns the same plain string.
  • Any string containing one of those markers still goes through Tera, including malformed templates, unknown variables, raw blocks, comments, includes, macros, and whitespace-control syntax. That preserves existing render errors and behavior for all Tera-looking input.
  • False positives are acceptable because they keep the old render path. The important case is avoiding false negatives, and the marker set matches Tera 1.20.1's block openers.

Testing

  • cargo fmt --all -- --check
  • git diff --check
  • rg -n '\.render_str\(' src --glob '*.rs'
  • /home/risu/.rustup/toolchains/1.95.0-x86_64-unknown-linux-gnu/bin/cargo check --all-features
  • /home/risu/.rustup/toolchains/1.95.0-x86_64-unknown-linux-gnu/bin/cargo clippy -- -D warnings
  • /home/risu/.rustup/toolchains/1.95.0-x86_64-unknown-linux-gnu/bin/cargo test -p mise --bin mise tera::tests
  • /home/risu/.rustup/toolchains/1.95.0-x86_64-unknown-linux-gnu/bin/cargo test -p mise --bin mise config::env_directive
  • /home/risu/.rustup/toolchains/1.95.0-x86_64-unknown-linux-gnu/bin/cargo test -p mise --bin mise task::task_script_parser
  • /home/risu/.rustup/toolchains/1.95.0-x86_64-unknown-linux-gnu/bin/cargo test -p mise --bin mise task::task_dep
  • /home/risu/.rustup/toolchains/1.95.0-x86_64-unknown-linux-gnu/bin/cargo test -p mise --bin mise task::tests

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces contains_template_syntax and render_str_if_template to optimize string processing by skipping Tera rendering for plain text. These helpers are integrated across backends, tasks, and configuration modules. The review feedback focuses on further performance gains by moving the template syntax check earlier in the execution flow to avoid expensive operations like asynchronous context fetching, context cloning, and Tera instance initialization. There are also suggestions to include missing imports for these new utility functions.

Comment thread src/backend/external_plugin_cache.rs Outdated
Comment thread src/backend/external_plugin_cache.rs Outdated
Comment thread src/backend/mod.rs Outdated
Comment thread src/backend/mod.rs Outdated
Comment thread src/task/mod.rs Outdated
@greptile-apps

greptile-apps Bot commented May 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR skips Tera template rendering for plain strings that contain none of the {{, {%, or {# block-opener markers, avoiding context construction, async fetches, and get_tera setup in the common case where no template syntax is present.

  • Centralises the marker check in a shared contains_template_syntax helper in src/tera.rs, removing three separate ad-hoc .contains(\"{{\")chains scattered across call sites.
  • Adds a thin render_str wrapper and render_str_if_template utility to consolidate all direct Tera::render_str calls behind src/tera.rs.
  • Introduces has_render_templates() + store_raw_render_inputs() + parse_plain_depends() helpers in Task::render to skip Tera instance creation and the async tera_ctx fetch entirely when a task has no template fields, while preserving shell-style env parsing for plain dependencies.

Confidence Score: 5/5

Safe to merge — the skip logic is guarded by a conservative marker check, and every plain-string fast path preserves all non-Tera side effects such as shell-style env parsing on task dependencies.

All call sites that skip Tera do so only when none of {{, {%, or {# are present, which exactly matches Tera 1.20.1's block openers. The has_render_templates predicate in Task::render covers the same fields the render function actually writes to. The extraction of parse_shell_style_env into parse_plain_depends correctly reproduces the original dependency side-effect in the fast path. No issues were found that would cause incorrect output or missed rendering.

No files require special attention. The most complex change is in src/task/mod.rs (has_render_templates + render refactor), but the predicate is complete and the ordering of store_raw_render_inputs relative to dep rendering now correctly saves truly-unrendered dependency snapshots.

Important Files Changed

Filename Overview
src/tera.rs Adds contains_template_syntax, render_str, and render_str_if_template helpers; adds unit tests for all three including the previously-missing render-path case
src/task/mod.rs Adds has_render_templates() gate, extracts store_raw_render_inputs() and parse_plain_depends(), and guards each individual render site; depends_raw is now saved before rendering (correctly capturing truly unrendered deps for deferred usage-ref re-render)
src/task/task_dep.rs Extracts parse_shell_style_env from render() so the plain-dep fast-path in parse_plain_depends() can invoke it without Tera
src/task/task_script_parser.rs Adds early-exit fast paths in parse_spec_from_run_scripts and parse_task_run_scripts_for_execution when neither usage nor scripts contain template syntax
src/task/task_sources.rs Adds has_tera_template() and raw_templates_without_env() to TaskOutputs; render_with_env skips Tera setup when no output files contain template syntax
src/config/env_directive/mod.rs Defers Tera initialization and exec function registration to first template use via Option + get_or_insert_with; plain env values skip Tera entirely
src/deps/engine.rs Pre-scans cmd.env values to decide whether to build tera_state; the per-value expect() is logically guaranteed by the prior any() scan over the same map
src/hooks.rs Moves tera_ctx construction inside a contains_template_syntax(run) branch, avoiding the async tera_ctx fetch for plain hook scripts

Reviews (5): Last reviewed commit: "style(task): satisfy clippy for template..." | Re-trigger Greptile

Comment thread src/config/miserc.rs Outdated
Comment thread src/tera.rs
@risu729 risu729 marked this pull request as ready for review May 14, 2026 16:53
@jdx jdx merged commit 000f649 into jdx:main May 14, 2026
32 checks passed
@risu729 risu729 deleted the codex/tera-render-skip branch May 14, 2026 20:47
mise-en-dev added a commit that referenced this pull request May 15, 2026
### 🚀 Features

- **(config)** add shell to watch_files run by @risu729 in
[#9810](#9810)
- **(spm)** add artifact bundle support by @ikesyo in
[#9825](#9825)

### 🐛 Bug Fixes

- **(aqua)** reject registry-invalid latest tags by @risu729 in
[#9834](#9834)
- **(patrons)** point sponsor link to https://en.dev by @jdx in
[#9868](#9868)
- **(vfox)** respect default inline shell in cmd.exec by @risu729 in
[#9837](#9837)
- github oauth device flow paths by @jasisk in
[#9791](#9791)

### 📚 Documentation

- Update Walkthrough guide by @thernstig in
[#9853](#9853)

### ⚡ Performance

- **(config)** skip tera render for plain strings by @risu729 in
[#9833](#9833)

### 📦️ Dependency Updates

- update ghcr.io/jdx/mise:rpm docker digest to d2471f2 by @renovate[bot]
in [#9879](#9879)
- update rust docker digest to 5b1e348 by @renovate[bot] in
[#9880](#9880)
- update ghcr.io/jdx/mise:deb docker digest to 0cde829 by @renovate[bot]
in [#9878](#9878)
- update ubuntu docker tag to resolute-20260421 by @renovate[bot] in
[#9881](#9881)
- update ghcr.io/jdx/mise:alpine docker digest to 2d0ea74 by
@renovate[bot] in [#9877](#9877)
- update rust crate phf to 0.13 by @renovate[bot] in
[#9884](#9884)
- update rust crate phf_codegen to 0.13 by @renovate[bot] in
[#9883](#9883)

### 📦 Registry

- use aqua backend for npm by @risu729 in
[#9762](#9762)
- add aqua for buck2 prereleases by @risu729 in
[#9805](#9805)
- add SonarQube CLI
([aqua:SonarSource/sonarqube-cli](https://github.com/SonarSource/sonarqube-cli))
by @3PeatVR in [#9824](#9824)

### New Contributors

- @3PeatVR made their first contribution in
[#9824](#9824)
- @ikesyo made their first contribution in
[#9825](#9825)
- @thernstig made their first contribution in
[#9853](#9853)

## 📦 Aqua Registry Updates

### New Packages (4)

- [`SurgeDM/Surge`](https://github.com/SurgeDM/Surge)
- [`roie/ovw`](https://github.com/roie/ovw)
- [`so-dang-cool/sigi`](https://github.com/so-dang-cool/sigi)
- [`vjeantet/alerter`](https://github.com/vjeantet/alerter)

### Updated Packages (2)

-
[`alltuner/mise-completions-sync`](https://github.com/alltuner/mise-completions-sync)
-
[`str4d/age-plugin-yubikey`](https://github.com/str4d/age-plugin-yubikey)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants