Skip to content

feat(template): add read_file() function#6400

Merged
jdx merged 4 commits intomainfrom
feat/template-read-file
Sep 24, 2025
Merged

feat(template): add read_file() function#6400
jdx merged 4 commits intomainfrom
feat/template-read-file

Conversation

@jdx
Copy link
Owner

@jdx jdx commented Sep 24, 2025

Summary

  • Add a new template function read_file(path) that reads file contents relative to config_root
  • Files are read relative to the directory containing the mise.toml file, not the current working directory
  • Returns raw file contents as a string that can be processed with filters

Use Case

This allows configuration files to dynamically include content from external files during template rendering. For example:

  • Reading version numbers from a VERSION file
  • Including configuration from separate files
  • Loading environment-specific settings

Example Usage

[env]
VERSION = "{{ read_file(path='VERSION') | trim }}"
CONFIG = "{{ read_file(path='config/production.txt') | trim }}"

Test Plan

  • Added unit test for the new function
  • Added comprehensive e2e tests covering:
    • Basic file reading
    • Relative paths
    • Multi-line content
    • Path resolution relative to config_root (not CWD)
    • Nested configurations with their own relative paths

🤖 Generated with Claude Code

Add a new template function `read_file(path)` that reads the contents of a file
relative to the config_root. This allows config files to include content from
external files during template rendering.

- Paths are resolved relative to the directory containing the mise.toml file
- Returns the raw file contents as a string
- Can be combined with filters like trim, replace, etc.

Example usage:
```toml
[env]
VERSION = "{{ read_file(path='VERSION') | trim }}"
```

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings September 24, 2025 20:07
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds a new template function read_file() that allows reading file contents during template rendering in mise configuration files. The function reads files relative to the directory containing the mise.toml file, enabling dynamic inclusion of external content.

Key changes:

  • Added tera_read_file() function that reads file contents and returns them as a string
  • Modified get_tera() to register the new function alongside the existing exec function
  • Added comprehensive test coverage for various use cases including relative paths and nested configurations

Reviewed Changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/tera.rs Implements the read_file() template function and registers it with the Tera engine
e2e/env/test_env_template_read_file Comprehensive end-to-end tests covering various read_file scenarios
docs/templates.md Documents the new read_file function with usage examples

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +392 to +397
match std::fs::read_to_string(&path) {
Ok(contents) => Ok(Value::String(contents)),
Err(e) => {
Err(format!("Failed to read file '{}': {}", path.display(), e).into())
}
}
Copy link

Copilot AI Sep 24, 2025

Choose a reason for hiding this comment

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

The read_file function allows reading arbitrary files from the filesystem without any path validation or security checks. Consider adding validation to prevent directory traversal attacks (e.g., paths containing ../ or absolute paths) and restrict file access to only files within the configuration directory tree.

Copilot uses AI. Check for mistakes.
Comment on lines +388 to +389
// Use path as-is if no directory context
PathBuf::from(path_str)
Copy link

Copilot AI Sep 24, 2025

Choose a reason for hiding this comment

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

When no directory context is provided, the function uses the path as-is, which could allow reading files from anywhere on the filesystem. Consider either requiring a base directory or defaulting to a safe directory like the current working directory to prevent unintended file access.

Suggested change
// Use path as-is if no directory context
PathBuf::from(path_str)
// Default to current working directory if no directory context
match std::env::current_dir() {
Ok(cwd) => cwd.join(path_str),
Err(e) => {
return Err(format!("Failed to get current directory: {}", e).into());
}
}

Copilot uses AI. Check for mistakes.
cursor[bot]

This comment was marked as outdated.

@github-actions
Copy link

github-actions bot commented Sep 24, 2025

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2025.9.17 x -- echo 20.1 ± 0.5 19.3 25.0 1.00
mise x -- echo 20.6 ± 0.7 19.5 25.3 1.03 ± 0.04

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2025.9.17 env 19.6 ± 0.6 18.7 23.3 1.00
mise env 19.8 ± 0.5 18.9 23.6 1.01 ± 0.04

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2025.9.17 hook-env 19.1 ± 0.4 18.4 21.1 1.00
mise hook-env 19.5 ± 0.6 18.5 21.9 1.02 ± 0.04

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2025.9.17 ls 17.0 ± 0.4 16.3 18.7 1.00
mise ls 18.0 ± 0.9 16.5 22.1 1.06 ± 0.06

xtasks/test/perf

Command mise-2025.9.17 mise Variance
install (cached) 173ms ✅ 106ms +63%
ls (cached) 65ms 64ms +1%
bin-paths (cached) 72ms 71ms +1%
task-ls (cached) 484ms 492ms -1%

✅ Performance improvement: install cached is 63%

jdx added 3 commits September 24, 2025 15:26
The test now properly verifies that read_file() resolves paths relative
to each config file's directory, not the current working directory. It
tests with nested config files at different levels, each reading their
own local files, and confirms that parent env vars are accessible from
subdirectories.
The test was using a hardcoded path that doesn't exist. Fixed by
creating a temp directory and test file to properly verify the
read_file function works correctly.
@jdx jdx merged commit f426a22 into main Sep 24, 2025
19 checks passed
@jdx jdx deleted the feat/template-read-file branch September 24, 2025 22:29
@jdx jdx mentioned this pull request Sep 24, 2025
jdx added a commit that referenced this pull request Sep 25, 2025
### 📦 Registry

- replace amplify-cli github backend with ubi by @eggplants in
[#6396](#6396)

### 🚀 Features

- **(template)** add read_file() function by @jdx in
[#6400](#6400)

### 🐛 Bug Fixes

- **(aqua)** support github_artifact_attestations.enabled by @risu729 in
[#6372](#6372)
- use /c instead of -c on windows in postinstall hook by @risu729 in
[#6397](#6397)

### 🧪 Testing

- **(test-tool)** uninstall all versions and clear cache before
installation by @jdx in [#6393](#6393)

### New Contributors

- @eggplants made their first contribution in
[#6396](#6396)

Co-authored-by: mise-en-dev <release@mise.jdx.dev>
@jdx jdx mentioned this pull request Sep 25, 2025
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Sep 25, 2025
## [2025.9.18](https://github.com/jdx/mise/compare/v2025.9.17..v2025.9.18) - 2025-09-24

### 📦 Registry

- replace amplify-cli github backend with ubi by @eggplants in [#6396](jdx/mise#6396)

### 🚀 Features

- **(template)** add read_file() function by @jdx in [#6400](jdx/mise#6400)

### 🐛 Bug Fixes

- **(aqua)** support github_artifact_attestations.enabled by @risu729 in [#6372](jdx/mise#6372)
- use /c instead of -c on windows in postinstall hook by @risu729 in [#6397](jdx/mise#6397)

### 🧪 Testing

- **(test-tool)** uninstall all versions and clear cache before installation by @jdx in [#6393](jdx/mise#6393)

### New Contributors

- @eggplants made their first contribution in [#6396](jdx/mise#6396)

## [2025.9.17](https://github.com/jdx/mise/compare/v2025.9.16..v2025.9.17) - 2025-09-24

### 🚀 Features

- **(java)** add support for Liberica NIK releases by @roele in [#6382](jdx/mise#6382)

### 🐛 Bug Fixes

- **(toolset)** handle underflow in version_sub function by @koh-sh in [#6389](jdx/mise#6389)

### 📚 Documentation

- document MISE_ENV behavior for global/system configs by @jdx in [#6385](jdx/mise#6385)

### New Contributors

- @jc00ke made their first contribution in [#6386](jdx/mise#6386)
- @koh-sh made their first contribution in [#6389](jdx/mise#6389)
riastradh pushed a commit to riastradh/pkgsrc-test20250901 that referenced this pull request Feb 8, 2026
## [2025.9.18](https://github.com/jdx/mise/compare/v2025.9.17..v2025.9.18) - 2025-09-24

### 📦 Registry

- replace amplify-cli github backend with ubi by @eggplants in [#6396](jdx/mise#6396)

### 🚀 Features

- **(template)** add read_file() function by @jdx in [#6400](jdx/mise#6400)

### 🐛 Bug Fixes

- **(aqua)** support github_artifact_attestations.enabled by @risu729 in [#6372](jdx/mise#6372)
- use /c instead of -c on windows in postinstall hook by @risu729 in [#6397](jdx/mise#6397)

### 🧪 Testing

- **(test-tool)** uninstall all versions and clear cache before installation by @jdx in [#6393](jdx/mise#6393)

### New Contributors

- @eggplants made their first contribution in [#6396](jdx/mise#6396)

## [2025.9.17](https://github.com/jdx/mise/compare/v2025.9.16..v2025.9.17) - 2025-09-24

### 🚀 Features

- **(java)** add support for Liberica NIK releases by @roele in [#6382](jdx/mise#6382)

### 🐛 Bug Fixes

- **(toolset)** handle underflow in version_sub function by @koh-sh in [#6389](jdx/mise#6389)

### 📚 Documentation

- document MISE_ENV behavior for global/system configs by @jdx in [#6385](jdx/mise#6385)

### New Contributors

- @jc00ke made their first contribution in [#6386](jdx/mise#6386)
- @koh-sh made their first contribution in [#6389](jdx/mise#6389)
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