Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/environments/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,13 @@ from a file). Since nested environment variables do not make sense,
we make use of this fact by creating a key named "\_" which is a
TOML table for the configuration of these directives.

::: warning
The `value` and `values` keys in built-in `file`, `path`, and `source` directive objects under
`env._` or `vars._` are deprecated. Use `path`, which accepts either a single string or an array of
strings. They will be removed in mise 2026.12.0. This does not affect `value` in ordinary environment
variable objects or options for plugin-provided directives.
:::

### `env._.file`

In `mise.toml`: `env._.file` can be used to specify a [dotenv](https://dotenv.org) file to load.
Expand Down
9 changes: 9 additions & 0 deletions e2e/env/test_env_file
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,17 @@ cat <<EOF >mise.toml
_.file = { value = 'b.json' }
EOF
echo '{"B": 2}' >b.json
assert_contains "mise env 2>&1" "deprecated [config.directive.value]"
assert "mise env | grep -v PATH" "export B=2"

cat <<EOF >mise.toml
[env]
_.file = { values = ['a', 'b.json'] }
EOF
assert_contains "mise env 2>&1" "deprecated [config.directive.values]"
assert "mise env | grep -v PATH" "export A=1
export B=2"
Comment thread
risu729 marked this conversation as resolved.
Resolved

cat <<EOF >mise.toml
[env]
_.file = 'c.toml'
Expand Down
8 changes: 8 additions & 0 deletions e2e/env/test_env_path
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ _.path = { path = ["a"], tools = true }
EOF
assert "mise dr path" "$PWD/a"

cat <<'EOF' >mise.toml
[env]
_.path = { paths = ["a", "b"], tools = true }
EOF
assert_not_contains "mise dr path 2>&1" "deprecated [config.directive"
assert "mise dr path" "$PWD/a
$PWD/b"

cat <<'EOF' >mise.toml
[env]
_.path = [{ path = "a", tools = true }, "b"]
Expand Down
65 changes: 53 additions & 12 deletions src/config/config_file/mise_toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1508,28 +1508,69 @@ impl<'de> de::Deserialize<'de> for EnvList {
"_" | "mise" => {
#[derive(Deserialize)]
#[serde(untagged)]
enum MiseTomlEnvDirective {
enum MiseTomlEnvDirectiveValue {
Single {
#[serde(alias = "path")]
value: String,
#[serde(alias = "value")]
path: String,
#[serde(flatten)]
options: EnvDirectiveOptions,
},
Multiple {
#[serde(alias = "value", alias = "path", alias = "paths")]
values: Vec<String>,
#[serde(alias = "value", alias = "values", alias = "paths")]
path: Vec<String>,
#[serde(flatten)]
options: EnvDirectiveOptions,
},
}

struct MiseTomlEnvDirective(MiseTomlEnvDirectiveValue);

impl<'de> Deserialize<'de> for MiseTomlEnvDirective {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let value = toml::Value::deserialize(deserializer)?;
let (uses_value, uses_values) = value
.as_table()
.map(|table| {
(
table.contains_key("value"),
table.contains_key("values"),
)
})
.unwrap_or_default();
let directive = MiseTomlEnvDirectiveValue::deserialize(value)
.map_err(de::Error::custom)?;

if uses_value {
deprecated_at!(
"2026.7.0",
"2026.12.0",
"config.directive.value",
"`value` in built-in `file`, `path`, and `source` directive objects is deprecated. Use `path` instead."
);
}
if uses_values {
deprecated_at!(
"2026.7.0",
"2026.12.0",
"config.directive.values",
"`values` in built-in `file`, `path`, and `source` directive objects is deprecated. Use `path` instead."
);
}

Ok(MiseTomlEnvDirective(directive))
}
}

impl FromStr for MiseTomlEnvDirective {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(MiseTomlEnvDirective::Single {
value: s.to_string(),
Ok(MiseTomlEnvDirective(MiseTomlEnvDirectiveValue::Single {
path: s.to_string(),
options: Default::default(),
})
}))
}
}

Expand Down Expand Up @@ -1658,11 +1699,11 @@ impl<'de> de::Deserialize<'de> for EnvList {
where
F: Fn(String, EnvDirectiveOptions) -> EnvDirective + 'static,
{
directives.into_iter().flat_map(move |d| match d {
MiseTomlEnvDirective::Single { value, options } => {
vec![constructor(value, options)]
directives.into_iter().flat_map(move |d| match d.0 {
MiseTomlEnvDirectiveValue::Single { path, options } => {
vec![constructor(path, options)]
}
MiseTomlEnvDirective::Multiple { values, options } => values
MiseTomlEnvDirectiveValue::Multiple { path, options } => path
.into_iter()
.map(|v| constructor(v, options.clone()))
.collect(),
Expand Down