Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: multiple MISE_ENV environments #3371

Merged
merged 2 commits into from
Dec 5, 2024
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
2 changes: 1 addition & 1 deletion docs/cli/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Shorthand for `mise task run <TASK>`.

Change directory before running command

### `-E --env <ENV>`
### `-E --env... <ENV>`

Set the environment for loading `mise.<ENV>.toml`

Expand Down
2 changes: 2 additions & 0 deletions docs/configuration/environments.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ Use `mise config` to see which files are being used.

The rules around which file is written are different because we ultimately need to choose one. See
the docs for [`mise use`](/cli/use.html) for more information.

Multiple environments can be specified, e.g. `MISE_ENV=ci,test` with the last one taking precedence.
11 changes: 11 additions & 0 deletions e2e/config/test_config_env
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash

echo "tools.dummy = '1'" >mise.toml
echo "tools.dummy = '2'" >mise.test.toml
echo "tools.dummy = '3'" >mise.ci.toml

assert "mise ls dummy" "dummy 1.1.0 (missing) ~/workdir/mise.toml 1"
MISE_ENV=test assert "mise ls dummy" "dummy 2.0.0 (missing) ~/workdir/mise.test.toml 2"
MISE_ENV=ci assert "mise ls dummy" "dummy 3 (missing) ~/workdir/mise.ci.toml 3"
MISE_ENV=ci,test assert "mise ls dummy" "dummy 2.0.0 (missing) ~/workdir/mise.test.toml 2"
MISE_ENV=test,ci assert "mise ls dummy" "dummy 3 (missing) ~/workdir/mise.ci.toml 3"
4 changes: 2 additions & 2 deletions mise.usage.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ flag "-C --cd" help="Change directory before running command" global=true {
}
flag "-n --dry-run" help="Dry run, don't actually do anything" hide=true global=true
flag "--debug" help="Sets log level to debug" hide=true global=true
flag "-E --env" help="Set the environment for loading `mise.<ENV>.toml`" global=true {
flag "-E --env" help="Set the environment for loading `mise.<ENV>.toml`" var=true global=true {
arg "<ENV>"
}
flag "-f --force" help="Force the operation" hide=true
Expand All @@ -31,7 +31,7 @@ flag "--log-level" hide=true global=true {
}
}
flag "-p --prefix" hide=true
flag "-P --profile" help="Set the profile (environment)" hide=true global=true {
flag "-P --profile" help="Set the profile (environment)" var=true hide=true global=true {
arg "<PROFILE>"
}
flag "-s --shell" hide=true {
Expand Down
6 changes: 5 additions & 1 deletion schema/mise.json
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,12 @@
}
},
"env": {
"default": [],
"description": "Env to use for mise.<MISE_ENV>.toml files.",
"type": "string"
"type": "array",
"items": {
"type": "string"
}
},
"env_file": {
"description": "Path to a file containing environment variables.",
Expand Down
8 changes: 6 additions & 2 deletions settings.toml
Original file line number Diff line number Diff line change
Expand Up @@ -222,15 +222,19 @@ description = "Tools defined in mise.toml that should be ignored"

[env]
env = "MISE_ENV"
type = "String"
type = "ListString"
default = []
parse_env = "list_by_comma"
description = "Env to use for mise.<MISE_ENV>.toml files."
optional = true
docs = """
Enables profile-specific config files such as `.mise.development.toml`.
Use this for different env vars or different tool versions in
development/staging/production environments. See
[Configuration Environments](/configuration/environments) for more on how
to use this feature.

Multiple envs can be set by separating them with a comma, e.g. `MISE_ENV=ci,test`.
They will be read in order, with the last one taking precedence.
"""

[env_file]
Expand Down
6 changes: 3 additions & 3 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ pub struct Cli {
pub debug: bool,
/// Set the environment for loading `mise.<ENV>.toml`
#[clap(short = 'E', long, global = true)]
pub env: Option<String>,
pub env: Option<Vec<String>>,
/// Force the operation
#[clap(long, short, hide = true)]
pub force: bool,
Expand All @@ -111,8 +111,8 @@ pub struct Cli {
#[clap(long, short, hide = true, overrides_with = "interleave")]
pub prefix: bool,
/// Set the profile (environment)
#[clap(short = 'P', long, global = true, hide = true)]
pub profile: Option<String>,
#[clap(short = 'P', long, global = true, hide = true, conflicts_with = "env")]
pub profile: Option<Vec<String>>,
#[clap(long, short, hide = true)]
pub shell: Option<String>,
/// Tool(s) to run in addition to what is in mise.toml files
Expand Down
3 changes: 2 additions & 1 deletion src/cli/use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ impl Use {

fn get_config_file(&self) -> Result<Box<dyn ConfigFile>> {
let cwd = env::current_dir()?;
let path = if let Some(env) = &*env::MISE_ENV {
let path = if !env::MISE_ENV.is_empty() {
let env = env::MISE_ENV.last().unwrap();
config_file_from_dir(&cwd.join(format!("mise.{env}.toml")))
} else if self.global || env::in_home_dir() {
MISE_GLOBAL_CONFIG_FILE.clone()
Expand Down
4 changes: 2 additions & 2 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ pub static DEFAULT_CONFIG_FILENAMES: Lazy<Vec<String>> = Lazy::new(|| {
.iter()
.map(|f| f.to_string())
.collect_vec();
if let Some(env) = &*env::MISE_ENV {
for env in &*env::MISE_ENV {
filenames.push(format!(".config/mise/config.{env}.toml"));
filenames.push(format!(".config/mise.{env}.toml"));
filenames.push(format!("mise/config.{env}.toml"));
Expand Down Expand Up @@ -815,7 +815,7 @@ pub fn global_config_files() -> IndexSet<PathBuf> {
config_files.insert(f);
}
}
if let Some(env) = &*env::MISE_ENV {
for env in &*env::MISE_ENV {
let global_profile_files = vec![
dirs::CONFIG.join(format!("config.{env}.toml")),
dirs::CONFIG.join(format!("config.{env}.local.toml")),
Expand Down
7 changes: 5 additions & 2 deletions src/config/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,11 @@ impl Settings {
if let Some(cd) = &cli.cd {
s.cd = Some(cd.clone());
}
if let Some(env) = cli.env.as_ref().or(cli.profile.as_ref()) {
s.env = Some(env.clone());
if cli.profile.is_some() {
s.env = cli.profile.clone();
}
if cli.env.is_some() {
s.env = cli.env.clone();
}
if cli.yes {
s.yes = Some(true);
Expand Down
11 changes: 8 additions & 3 deletions src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ pub static MISE_DEFAULT_CONFIG_FILENAME: Lazy<String> = Lazy::new(|| {
var("MISE_DEFAULT_CONFIG_FILENAME")
.ok()
.or(MISE_OVERRIDE_CONFIG_FILENAMES.first().cloned())
.or(MISE_ENV.as_ref().map(|env| format!("mise.{env}.toml")))
.or(MISE_ENV.last().map(|env| format!("mise.{env}.toml")))
.unwrap_or_else(|| "mise.toml".into())
});
pub static MISE_OVERRIDE_TOOL_VERSIONS_FILENAMES: Lazy<Option<IndexSet<String>>> =
Expand All @@ -108,7 +108,7 @@ pub static MISE_OVERRIDE_CONFIG_FILENAMES: Lazy<IndexSet<String>> =
Ok(v) => v.split(':').map(|s| s.to_string()).collect(),
Err(_) => Default::default(),
});
pub static MISE_ENV: Lazy<Option<String>> = Lazy::new(|| environment(&ARGS.read().unwrap()));
pub static MISE_ENV: Lazy<Vec<String>> = Lazy::new(|| environment(&ARGS.read().unwrap()));
pub static MISE_GLOBAL_CONFIG_FILE: Lazy<PathBuf> = Lazy::new(|| {
var_path("MISE_GLOBAL_CONFIG_FILE")
.or_else(|| var_path("MISE_CONFIG_FILE"))
Expand Down Expand Up @@ -410,7 +410,7 @@ fn prefer_stale(args: &[String]) -> bool {
.contains(&c.as_str())
}

fn environment(args: &[String]) -> Option<String> {
fn environment(args: &[String]) -> Vec<String> {
let arg_defs = HashSet::from([
format!("--{}", PROFILE_ARG.get_long().unwrap_or_default()),
format!("-{}", PROFILE_ARG.get_short().unwrap_or_default()),
Expand All @@ -429,6 +429,11 @@ fn environment(args: &[String]) -> Option<String> {
.or_else(|| var("MISE_ENV").ok())
.or_else(|| var("MISE_PROFILE").ok())
.or_else(|| var("MISE_ENVIRONMENT").ok())
.unwrap_or_default()
.split(',')
.filter(|s| !s.is_empty())
.map(String::from)
.collect()
}

fn log_file_level() -> Option<LevelFilter> {
Expand Down
2 changes: 1 addition & 1 deletion xtasks/fig/src/mise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3145,7 +3145,7 @@ const completionSpec: Fig.Spec = {
"--env"
],
"description": "Set the environment for loading `mise.<ENV>.toml`",
"isRepeatable": false,
"isRepeatable": true,
"args": {
"name": "env",
"isOptional": false,
Expand Down
Loading