fix(config): mise use writes to lowest precedence config file#7598
Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements a new .miserc.toml configuration file for early initialization settings and fixes the mise use command to write to the lowest precedence config file. The .miserc.toml file allows settings like MISE_ENV to be set in a config file rather than only via environment variables, enabling version-controlled environment configuration. The mise use command now prefers mise.toml over mise.local.toml when both exist, making local overrides less likely to be accidentally committed.
Key changes:
- Introduced
.miserc.tomlfor early-init settings (env, ceiling_paths, ignored_config_paths, override_config_filenames, override_tool_versions_filenames) - Modified
mise useto write to the lowest precedence config file (mise.toml) instead of highest precedence (mise.local.toml) - Added JSON schema generation for
.miserc.tomlconfiguration
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| xtasks/render/schema.ts | Adds schema generation for .miserc.toml with rc-enabled settings |
| src/env.rs | Integrates miserc settings as fallback for early-init environment variables |
| src/config/mod.rs | Updates config_file_from_dir to prefer lowest precedence files (mise.toml over mise.local.toml) |
| src/config/miserc.rs | New module implementing .miserc.toml loading and merging logic |
| src/cli/mod.rs | Initializes miserc early in CLI execution before other settings are accessed |
| settings.toml | Marks early-init settings with rc=true and adds documentation |
| schema/miserc.json | Generated JSON schema for .miserc.toml validation |
| schema/mise.json | Updated schema with new ceiling_paths setting and improved descriptions |
| schema/mise-settings.json | Adds rc field to settings schema |
| e2e/config/test_miserc | Test coverage for .miserc.toml functionality |
| e2e/cli/test_use | Test coverage for mise use writing to lowest precedence file |
| docs/configuration/environments.md | Documents .miserc.toml usage for setting MISE_ENV |
| build.rs | Generates MisercSettings struct from settings marked with rc=true |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| for (const key in doc) { | ||
| const props = doc[key]; | ||
| if (hasSubkeys(props) && props.rc === true) { |
There was a problem hiding this comment.
The condition props.rc === true can be simplified to props.rc since the value is already boolean. This is more idiomatic and consistent with the conditional check in build.rs line 433.
| if (hasSubkeys(props) && props.rc === true) { | |
| if (hasSubkeys(props) && props.rc) { |
| // unless it's the only config file. This ensures `mise use` writes to mise.toml | ||
| // instead of mise.local.toml when both exist. | ||
| // See: https://github.com/jdx/mise/discussions/6475 | ||
| let dominated = |p: &Path| p.ends_with(".tool-versions"); |
There was a problem hiding this comment.
The closure name dominated is unclear. Consider renaming to is_tool_versions_file or should_skip_unless_only to better convey that this identifies files to deprioritize during selection.
| // Use raw std::env to avoid depending on our lazy statics | ||
| if let Ok(cwd) = std::env::current_dir() { | ||
| // Walk up the directory tree, but stop at home or root | ||
| let home: &Path = &dirs::HOME; |
There was a problem hiding this comment.
The type annotation : &Path is unnecessary here as the type is clear from the right-hand side. Removing it would make the code more concise without losing clarity.
| let home: &Path = &dirs::HOME; | |
| let home = &dirs::HOME; |
703ad92 to
22320c0
Compare
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.1.0 x -- echo |
21.2 ± 1.0 | 19.8 | 30.7 | 1.00 |
mise x -- echo |
21.9 ± 0.5 | 20.6 | 24.4 | 1.03 ± 0.06 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.1.0 env |
20.7 ± 0.6 | 19.8 | 26.0 | 1.00 |
mise env |
21.2 ± 0.5 | 20.0 | 23.3 | 1.02 ± 0.04 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.1.0 hook-env |
20.5 ± 0.8 | 19.8 | 29.3 | 1.00 |
mise hook-env |
21.6 ± 0.8 | 20.4 | 30.6 | 1.05 ± 0.06 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.1.0 ls |
18.6 ± 0.6 | 17.8 | 26.2 | 1.00 |
mise ls |
19.3 ± 0.5 | 18.3 | 24.1 | 1.03 ± 0.04 |
xtasks/test/perf
| Command | mise-2026.1.0 | mise | Variance |
|---|---|---|---|
| install (cached) | 114ms | 115ms | +0% |
| ls (cached) | 69ms | 70ms | -1% |
| bin-paths (cached) | 74ms | 74ms | +0% |
| task-ls (cached) | 287ms | 286ms | +0% |
f8547dd to
2f72a83
Compare
When multiple config files exist in a directory, commands like `mise use`, `mise set`, `mise unuse`, `mise settings set --local`, and `mise tasks add` now write to the lowest precedence file instead of the highest. This means `mise use` writes to `mise.toml` instead of `mise.local.toml` when both exist. This is more intuitive since `mise.local.toml` is typically used for local overrides that shouldn't be committed to VCS. The logic is 'lowest precedence file in highest precedence dir': - Prefers `mise.toml` over `mise.local.toml` - Prefers `mise.toml` over `.tool-versions` (unless `.tool-versions` is the only file) - Falls back to whatever file exists if there's only one Closes #6475
2f72a83 to
ebe1e3b
Compare
When multiple config files exist in a directory, commands like
mise use,mise set,mise unuse,mise settings set --local, andmise tasks addnow write to the lowest precedence file instead of the highest.This means
mise usewrites tomise.tomlinstead ofmise.local.tomlwhen both exist. This is more intuitive sincemise.local.tomlis typically used for local overrides that shouldn't be committed to VCS.Behavior
mise.tomlmise.tomlmise.tomlmise.local.tomlmise.local.tomlmise.local.tomlmise.toml+mise.local.tomlmise.local.tomlmise.tomlmise.toml+mise.dev.tomlmise.dev.tomlmise.toml.tool-versions+mise.tomlmise.tomlmise.toml.tool-versions.tool-versions.tool-versionsChanges
first_config_file()helper to select lowest precedence file (skipping.tool-versionsunless it's the only option)config_file_from_dir()andlocal_toml_config_path()to use the new logicdocs/configuration.mdexplaining the target file selectionCloses #6475
Note
Aligns write targets across commands to consistently prefer shared configs.
first_config_file()(skips.tool-versionsunless only option); updateconfig_file_from_dir()andlocal_toml_config_path()to select the lowest-precedence filemise use,mise set,mise unuse,mise settings set --local, andmise tasks addnow write tomise.tomlwhen both it andmise.local.tomlexistconfiguration.mdwith "Target File for Write Operations" section and referencesuseandsetvalidating write-target selection (including coexistence with.tool-versions)Written by Cursor Bugbot for commit ebe1e3b. This will update automatically on new commits. Configure here.