Skip to content

Commit

Permalink
feat: multiple MISE_ENV environments (#3371)
Browse files Browse the repository at this point in the history
* feat: multiple MISE_ENV environments

* feat: multiple MISE_ENV environments
  • Loading branch information
jdx authored Dec 5, 2024
1 parent 3222e48 commit d3519c3
Show file tree
Hide file tree
Showing 12 changed files with 48 additions and 18 deletions.
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

0 comments on commit d3519c3

Please sign in to comment.