Skip to content

feat(config): Add Tera template support to miserc.toml#8867

Merged
jdx merged 14 commits intojdx:mainfrom
richardthe3rd:claude/explore-miserc-templates-3CK2i
Apr 6, 2026
Merged

feat(config): Add Tera template support to miserc.toml#8867
jdx merged 14 commits intojdx:mainfrom
richardthe3rd:claude/explore-miserc-templates-3CK2i

Conversation

@richardthe3rd
Copy link
Copy Markdown
Contributor

This pull request adds support for Tera templating in .miserc.toml files, allowing users to use environment variables and other OS-level context in their configuration. The implementation ensures templates are rendered safely during early initialization, and provides documentation, tests, and end-to-end validation for this feature.

Template support in .miserc.toml:

  • Added Tera template rendering to .miserc.toml files, enabling use of environment variables and other OS-level context in configuration values. The context includes env, config_root, cwd, XDG directories, and basic functions/filters, but excludes settings-dependent or self-referential values. [1] [2] [3]
  • Updated documentation in docs/configuration/environments.md and docs/templates.md to describe template support, available context, usage examples, and caveats for .miserc.toml. [1] [2] [3]

Testing and validation:

  • Added unit tests for template rendering in .miserc.toml, covering environment variable expansion, function calls, context injection, and fallback behavior on errors.
  • Added end-to-end tests to verify that template expansion works as expected in real .miserc.toml scenarios.

Internal changes:

  • Refactored code to lazily initialize Tera only when template syntax is detected, optimizing performance and avoiding unnecessary initialization. [1] [2]
  • Exposed a dedicated Tera instance for miserc loading via get_miserc_tera, ensuring correct function/filter registration for early config parsing.

@richardthe3rd richardthe3rd changed the title Add Tera template support to miserc.toml feat(config): Add Tera template support to miserc.toml Apr 3, 2026
Copy link
Copy Markdown
Contributor

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

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 Tera template support for .miserc.toml configuration files, allowing for dynamic settings based on environment variables, XDG paths, and OS-level context. The implementation includes a lazy-loaded Tera instance with a restricted context to prevent circular dependencies during early initialization. Documentation and tests have been updated to reflect these changes. Feedback suggests adding a warning log if the current working directory cannot be retrieved during template rendering to improve debuggability.

Comment thread src/config/miserc.rs Outdated
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 3, 2026

Greptile Summary

This PR introduces Tera template support for .miserc.toml files, enabling early-init configuration values (such as ceiling_paths and ignored_config_paths) to reference OS-level context like {{ env.HOME }}, {{ xdg_config_home }}, and {{ os() }}.

The implementation is clean and well-considered: Tera is lazily initialized only when template markers ({{, {%, {#) are detected, the context is appropriately restricted to what is safe before mise.toml is loaded, and the previously flagged issue with hash_file/file_size/last_modified polluting TERA_ACCESSED_FILES is correctly addressed by draining the list via take_tera_accessed_files() in both init() and get(). All three prior review concerns have been resolved in this revision.

Key changes:

  • src/config/miserc.rs: New render_miserc_template() with lazy Tera init and accurate doc; take_tera_accessed_files() called after loading in both init paths
  • src/tera.rs: New get_miserc_tera() returning a TERA.clone() with an accurate doc comment distinguishing it from get_tera()
  • e2e/config/test_miserc: Two new template test scenarios (neither test effectively verifies that rendering occurred — see inline comment)
  • docs/templates.md + docs/configuration/environments.md: Clear documentation with examples, available/unavailable context, fallback tip, and raw-block warning

Confidence Score: 5/5

Safe to merge; all prior P1 concerns are resolved and only a P2 test coverage gap remains

All three previously flagged issues (misleading get_miserc_tera doc comment, TERA_ACCESSED_FILES pollution, test using wrong env source) have been correctly addressed. The remaining finding is a P2 test quality issue — the e2e tests don't assert that rendering actually happened, but the feature itself is functionally correct and well-guarded by the unit tests in miserc.rs. No logic, data-integrity, or security issues found.

e2e/config/test_miserc — the two new template test scenarios do not strongly verify that Tera rendering occurred; a false regression in render_miserc_template could go undetected

Important Files Changed

Filename Overview
src/config/miserc.rs Adds render_miserc_template() with lazy Tera init, accurate context (env/config_root/cwd/XDG), proper error fallback, and correct take_tera_accessed_files() drain in both init() and get()
src/tera.rs Adds get_miserc_tera() returning a plain TERA.clone(); doc comment accurately explains that exec/read_file are absent because they live only in get_tera(), not TERA itself
e2e/config/test_miserc Two new template e2e tests added; neither scenario verifies rendering actually occurred — both assertions pass equally if rendering silently falls back to raw content
docs/templates.md Adds #miserc-template-support section with available/unavailable context table, conditional block example, fallback tip, and raw-block warning
docs/configuration/environments.md Adds brief Templates subsection with ceiling_paths/ignored_config_paths examples and cross-link to the full template docs

Sequence Diagram

sequenceDiagram
    participant main as mise init
    participant miserc as miserc::init()
    participant load as load_miserc_settings()
    participant render as render_miserc_template()
    participant tera as Tera (TERA static)
    participant toml as TOML parser

    main->>miserc: init()
    miserc->>load: load_miserc_settings()
    load->>load: find_miserc_files()
    loop for each miserc file (reversed precedence)
        load->>render: &mut tera, content, config_root
        alt content contains {{ or {% or {#
            render->>tera: get_or_insert_with(get_miserc_tera)
            tera-->>render: TERA.clone()
            render->>render: build Context (env/config_root/cwd/xdg_*)
            render->>tera: render_str(content, context)
            alt render OK
                tera-->>render: rendered string
            else render Err
                tera-->>render: error
                render->>render: warn! + return raw content
            end
        else no template syntax detected
            render-->>render: return content unchanged (fast path)
        end
        render-->>load: final content string
        load->>toml: from_str::<MisercSettings>(&content)
        toml-->>load: Ok(settings) or warn on Err
        load->>load: merge_settings()
    end
    load-->>miserc: MisercSettings
    miserc->>miserc: MISERC.set(settings)
    miserc->>miserc: take_tera_accessed_files() — discard file-tracking artifacts
    miserc-->>main: Ok(())
Loading

Reviews (11): Last reviewed commit: "test(config): fix e2e dummy version asse..." | Re-trigger Greptile

Comment thread src/tera.rs
Comment thread src/config/miserc.rs
Comment thread src/config/miserc.rs
claude added 6 commits April 4, 2026 08:44
Render Tera templates in .miserc.toml before TOML parsing, enabling
expressions like `ceiling_paths = ["{{ env.HOME }}"]`. Uses a minimal
context (env, cwd, config_root, xdg_*, arch/os functions) safe for
early initialization — before Settings or main config are loaded.

Unavailable: mise_env (circular), exec()/read_file() (need Settings).
Falls back to raw content with a warning on render failure.

https://claude.ai/code/session_01525Mu3hgS2M2rKtDUv6CpT
- Remove useless format!() macro in test (clippy::useless_format)
- Fix duplicate ceiling_paths key in docs example (invalid TOML)
- Replace misleading e2e test that used uname instead of os() template

https://claude.ai/code/session_01525Mu3hgS2M2rKtDUv6CpT
- Avoid redundant TERA clones: create Tera instance once before the
  file loop instead of once per file (render_str requires &mut Tera)
- Fix incorrect docs claim that read_file() requires Settings — it
  does not; it is excluded to keep early-init context minimal
- Document {% raw %} escape for users with literal {{ in miserc values

https://claude.ai/code/session_01525Mu3hgS2M2rKtDUv6CpT
The previous refactor unintentionally cloned TERA unconditionally on
every startup, even when no miserc files exist or none contain template
syntax. Switch to Option<Tera> so the clone only occurs when a file
with template syntax is actually encountered.

Also fix the inline docstring which still incorrectly stated that
read_file() depends on Settings (it does not).

https://claude.ai/code/session_01525Mu3hgS2M2rKtDUv6CpT
The docstring incorrectly stated read_file depends on Settings.
Only exec() depends on Settings; read_file() is excluded because
it needs per-file directory context not available at this stage.

https://claude.ai/code/session_01525Mu3hgS2M2rKtDUv6CpT
- Clear TERA_ACCESSED_FILES after miserc loading so hash_file/file_size/
  last_modified filters don't silently pollute hook-env's file-watch list
- Fix get_miserc_tera() docstring: exec/read_file are absent because they
  are only registered in get_tera(), not in the TERA static itself
- Fix test_render_miserc_template_env_var to read HOME from PRISTINE_ENV
  (same source as the template context) rather than std::env::var
- Log current_dir() failures at debug level so the missing `cwd` context
  is diagnosable with MISE_DEBUG=1

https://claude.ai/code/session_01525Mu3hgS2M2rKtDUv6CpT
@richardthe3rd richardthe3rd force-pushed the claude/explore-miserc-templates-3CK2i branch from 563fd7c to 62fedc2 Compare April 4, 2026 07:44
claude and others added 4 commits April 4, 2026 07:55
- Also clear TERA_ACCESSED_FILES in miserc::get() fallback path, not
  just miserc::init(), so the cleanup is consistent regardless of which
  path triggers loading
- Break long debug!() line for rustfmt compliance
- Wrap miserc template examples in <div v-pre> to prevent VitePress/Vue
  from interpreting {{ }} as interpolation (fixes docs build CI failure)

https://claude.ai/code/session_01525Mu3hgS2M2rKtDUv6CpT
- Wrap {{ }} and {% %} in <div v-pre> and <span v-pre> to prevent
  VitePress/Vue from treating them as interpolation (fixes CI build)
- Add explicit {#miserc-template-support} anchor to heading with dots
  to avoid ambiguous GFM anchor generation (fixes MD051)
- Rename duplicate '### Examples' heading to '### miserc.toml Examples'
  (fixes MD024)
- Update cross-references to use the explicit anchor ID

https://claude.ai/code/session_01525Mu3hgS2M2rKtDUv6CpT
@jdx jdx enabled auto-merge (squash) April 4, 2026 13:23
@jdx jdx disabled auto-merge April 4, 2026 15:37
@jdx jdx marked this pull request as draft April 4, 2026 15:37
@richardthe3rd richardthe3rd marked this pull request as ready for review April 6, 2026 09:26
@jdx jdx merged commit 7cc7b4e into jdx:main Apr 6, 2026
35 checks passed
mise-en-dev added a commit that referenced this pull request Apr 7, 2026
### 🚀 Features

- **(config)** Add Tera template support to miserc.toml by
@richardthe3rd in [#8867](#8867)

### 🐛 Bug Fixes

- **(env)** include tools-only redactions in `mise env --redacted` by
@jakedgy in [#8956](#8956)
- **(env)** pass dependency env to vfox backend plugin hooks by
@cprecioso in [#8952](#8952)
- **(shim)** fix race condition when removing in make_shim, when
multiple plugins provide the same shim by @brander-john in
[#8947](#8947)
- **(spm)** derive API URL from host for self-hosted instances by
@ThomasDutartre in [#8955](#8955)
- **(task)** resolve env vars in usage tera templates when flags are
provided by @jdx in [#8957](#8957)

### 📚 Documentation

- **(python)** clarify attestation settings must be under [settings] in
mise.toml by @fru1tworld in
[#8939](#8939)

### 📦 Registry

- added sing-box by @tony-sol in
[#8944](#8944)

### Chore

- **(ci)** remove auto-draft PR workflow by @jdx in
[#8945](#8945)

### New Contributors

- @ThomasDutartre made their first contribution in
[#8955](#8955)
- @jakedgy made their first contribution in
[#8956](#8956)
- @brander-john made their first contribution in
[#8947](#8947)
- @fru1tworld made their first contribution in
[#8939](#8939)
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.

3 participants