diff --git a/e2e/cli/test_env_dotenv b/e2e/env/test_env_dotenv similarity index 100% rename from e2e/cli/test_env_dotenv rename to e2e/env/test_env_dotenv diff --git a/e2e/cli/test_env_file b/e2e/env/test_env_file similarity index 51% rename from e2e/cli/test_env_file rename to e2e/env/test_env_file index 0cf8e15b96..8f280d48de 100644 --- a/e2e/cli/test_env_file +++ b/e2e/env/test_env_file @@ -1,6 +1,6 @@ #!/usr/bin/env bash -cat <<'EOF' >.mise.toml +cat <<'EOF' >mise.toml [env] mise.file = ['.test-env'] EOF @@ -10,3 +10,18 @@ echo TEST_ENV2=foo >.test-env2 assert "mise x -- env | grep FOO_FROM_FILE" "FOO_FROM_FILE=foo_from_file" assert "MISE_ENV_FILE=.test-env2 mise x -- env | grep TEST_ENV2" "TEST_ENV2=foo" + +cat <<'EOF' >mise.toml +[env] +_.file = 'not_present' +EOF +assert "mise env" # does not error + +cat <<'EOF' >mise.toml +[env] +_.file = ['a', 'b.json'] +EOF +echo 'export A=1' >a +echo '{"B": 2}' >b.json +assert "mise env | grep -v PATH" "export A=1 +export B=2" diff --git a/e2e/cli/test_env_file_glob b/e2e/env/test_env_file_glob similarity index 100% rename from e2e/cli/test_env_file_glob rename to e2e/env/test_env_file_glob diff --git a/e2e/cli/test_env_json b/e2e/env/test_env_json similarity index 100% rename from e2e/cli/test_env_json rename to e2e/env/test_env_json diff --git a/e2e/cli/test_env_path b/e2e/env/test_env_path similarity index 76% rename from e2e/cli/test_env_path rename to e2e/env/test_env_path index 3b66e6d8dc..d13cb326a0 100644 --- a/e2e/cli/test_env_path +++ b/e2e/env/test_env_path @@ -7,3 +7,10 @@ mise use dummy@2.0.0 assert_contains "mise env -s bash | grep PATH" "/installs/dummy/2.0.0/bin" assert_contains "mise env -s bash dummy@1.0.1 | grep PATH" "/installs/dummy/1.0.1/bin" + +cat <<'EOF' >mise.toml +[env] +_.path = ['a', 'b'] +EOF +assert "mise dr path" "$PWD/a +$PWD/b" diff --git a/e2e/cli/test_env_source b/e2e/env/test_env_source similarity index 100% rename from e2e/cli/test_env_source rename to e2e/env/test_env_source diff --git a/e2e/cli/test_env_source_glob b/e2e/env/test_env_source_glob similarity index 100% rename from e2e/cli/test_env_source_glob rename to e2e/env/test_env_source_glob diff --git a/e2e/cli/test_env_template b/e2e/env/test_env_template similarity index 100% rename from e2e/cli/test_env_template rename to e2e/env/test_env_template diff --git a/e2e/env/test_source b/e2e/env/test_source deleted file mode 100644 index 4f9e4e71d2..0000000000 --- a/e2e/env/test_source +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -cat <<'EOF' >.mise.toml -[env] -_.file = 'not_present' -EOF - -assert "mise env" # does not error diff --git a/schema/mise.json b/schema/mise.json index 9574339d8b..6ac5d2ca2a 100644 --- a/schema/mise.json +++ b/schema/mise.json @@ -992,6 +992,47 @@ "vars": { "description": "variables to set", "type": "object", + "properties": { + "_": { + "description": "vars modules", + "additionalProperties": true, + "properties": { + "file": { + "oneOf": [ + { + "description": "dotenv file to load", + "type": "string" + }, + { + "description": "dotenv files to load", + "items": { + "description": "dotenv file to load", + "type": "string" + }, + "type": "array" + } + ] + }, + "source": { + "oneOf": [ + { + "description": "bash script to load", + "type": "string" + }, + { + "description": "bash scripts to load", + "items": { + "description": "bash script to load", + "type": "string" + }, + "type": "array" + } + ] + } + }, + "type": "object" + } + }, "additionalProperties": { "description": "value of variable", "type": "string" diff --git a/src/config/env_directive/file.rs b/src/config/env_directive/file.rs index 736c5ea2ed..f81a1c0118 100644 --- a/src/config/env_directive/file.rs +++ b/src/config/env_directive/file.rs @@ -1,7 +1,7 @@ use crate::config::env_directive::EnvResults; use crate::file::display_path; use crate::{file, sops, Result}; -use eyre::{eyre, WrapErr}; +use eyre::{bail, eyre, WrapErr}; use indexmap::IndexMap; use rops::file::format::{JsonFileFormat, YamlFileFormat}; use std::path::{Path, PathBuf}; @@ -14,7 +14,7 @@ struct Env { #[serde(default)] sops: IndexMap, #[serde(flatten)] - env: EnvMap, + env: IndexMap, } impl EnvResults { @@ -38,6 +38,7 @@ impl EnvResults { let new_vars = match ext.as_str() { "json" => Self::json(&p, parse_template)?, "yaml" => Self::yaml(&p, parse_template)?, + "toml" => unimplemented!("toml"), _ => Self::dotenv(&p)?, }; for (k, v) in new_vars { @@ -59,7 +60,20 @@ impl EnvResults { let raw = sops::decrypt::<_, JsonFileFormat>(&raw, parse_template)?; f = serde_json::from_str(&raw).wrap_err_with(errfn)?; } - Ok(f.env) + f.env + .into_iter() + .map(|(k, v)| { + Ok(( + k, + match v { + serde_json::Value::String(s) => s, + serde_json::Value::Number(n) => n.to_string(), + serde_json::Value::Bool(b) => b.to_string(), + _ => bail!("unsupported json value: {v:?}"), + }, + )) + }) + .collect() } else { Ok(EnvMap::new()) } @@ -76,7 +90,20 @@ impl EnvResults { let raw = sops::decrypt::<_, YamlFileFormat>(&raw, parse_template)?; f = serde_yaml::from_str(&raw).wrap_err_with(errfn)?; } - Ok(f.env) + f.env + .into_iter() + .map(|(k, v)| { + Ok(( + k, + match v { + serde_yaml::Value::String(s) => s, + serde_yaml::Value::Number(n) => n.to_string(), + serde_yaml::Value::Bool(b) => b.to_string(), + _ => bail!("unsupported yaml value: {v:?}"), + }, + )) + }) + .collect() } else { Ok(EnvMap::new()) }