From aa35e142da49017504246367a77a3624920de61e Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Wed, 18 Dec 2024 13:24:21 -0600 Subject: [PATCH] fix: retain "os" options in `mise up --bump` --- e2e/cli/test_upgrade | 10 +++ src/backend/asdf.rs | 2 +- src/cli/install.rs | 1 - src/cli/use.rs | 2 - src/config/config_file/mise_toml.rs | 70 ++++++++----------- src/config/config_file/mod.rs | 2 - ...fig_file__mise_toml__tests__fixture-3.snap | 36 +++++----- ...e__mise_toml__tests__replace_versions.snap | 8 +-- src/toolset/mod.rs | 6 +- src/toolset/outdated_info.rs | 9 ++- src/toolset/tool_request.rs | 35 ++-------- src/toolset/tool_version.rs | 2 - 12 files changed, 77 insertions(+), 106 deletions(-) diff --git a/e2e/cli/test_upgrade b/e2e/cli/test_upgrade index 449ab3169b..22009e934f 100644 --- a/e2e/cli/test_upgrade +++ b/e2e/cli/test_upgrade @@ -47,3 +47,13 @@ Would install dummy@2.0.0 Would bump dummy@prefix:2 in ~/workdir/mise.toml" mise up dummy --bump assert "mise ls dummy" "dummy 2.0.0 ~/workdir/mise.toml prefix:2" + +cat <mise.toml +[tools] +dummy = "latest" +EOF +assert "mise uninstall dummy --all" +assert "mise i dummy@1.0.0" +assert "mise up --bump" +assert "cat mise.toml" '[tools] +dummy = "latest"' diff --git a/src/backend/asdf.rs b/src/backend/asdf.rs index d72cf71da1..7aefbc4b73 100644 --- a/src/backend/asdf.rs +++ b/src/backend/asdf.rs @@ -165,7 +165,7 @@ impl AsdfBackend { let k = format!("MISE_TOOL_OPTS__{}", key.to_uppercase()); sm = sm.with_env(k, value.clone()); } - for (key, value) in tv.request.options().env { + for (key, value) in tv.request.options().install_env { sm = sm.with_env(key, value.clone()); } if let Some(project_root) = &config.project_root { diff --git a/src/cli/install.rs b/src/cli/install.rs index afba288586..784d7de4a8 100644 --- a/src/cli/install.rs +++ b/src/cli/install.rs @@ -111,7 +111,6 @@ impl Install { let tvr = ToolRequest::Version { backend: ta.ba.clone(), version: "latest".into(), - os: None, options: ta.ba.opts(), source: ToolSource::Argument, }; diff --git a/src/cli/use.rs b/src/cli/use.rs index 6e4aacdd44..61d14f2228 100644 --- a/src/cli/use.rs +++ b/src/cli/use.rs @@ -155,7 +155,6 @@ impl Use { if let ToolRequest::Version { version: _version, source, - os, options, backend, } = request @@ -163,7 +162,6 @@ impl Use { request = ToolRequest::Version { version: tv.version.clone(), source, - os, options, backend, }; diff --git a/src/config/config_file/mise_toml.rs b/src/config/config_file/mise_toml.rs index eb1bd26d78..6f9100939f 100644 --- a/src/config/config_file/mise_toml.rs +++ b/src/config/config_file/mise_toml.rs @@ -75,7 +75,6 @@ pub struct MiseTomlToolList(Vec); #[derive(Debug, Clone)] pub struct MiseTomlTool { pub tt: ToolVersionType, - pub os: Option>, pub options: Option, } @@ -329,6 +328,9 @@ impl ConfigFile for MiseToml { let is_tools_sorted = is_tools_sorted(&self.tools); // was it previously sorted (if so we'll keep it sorted) let existing = self.tools.entry(ba.clone()).or_default(); let output_empty_opts = |opts: &ToolVersionOptions| { + if opts.os.is_some() || !opts.install_env.is_empty() { + return false; + } if let Some(reg_ba) = REGISTRY.get(ba.short.as_str()).and_then(|b| b.ba()) { if reg_ba.opts.as_ref().is_some_and(|o| o == opts) { // in this case the options specified are the same as in the registry so output no options and rely on the defaults @@ -357,14 +359,29 @@ impl ConfigFile for MiseToml { } if versions.len() == 1 { - if output_empty_opts(&versions[0].options()) { + let options = versions[0].options(); + if output_empty_opts(&options) { tools.insert_formatted(&key, value(versions[0].version())); } else { let mut table = InlineTable::new(); table.insert("version", versions[0].version().into()); - for (k, v) in versions[0].options().opts { + for (k, v) in options.opts { table.insert(k, v.into()); } + if let Some(os) = options.os { + let mut arr = Array::new(); + for o in os { + arr.push(Value::from(o)); + } + table.insert("os", Value::Array(arr)); + } + if !options.install_env.is_empty() { + let mut env = InlineTable::new(); + for (k, v) in options.install_env { + env.insert(k, v.into()); + } + table.insert("install_env", env.into()); + } tools.insert_formatted(&key, table.into()); } } else { @@ -416,7 +433,7 @@ impl ConfigFile for MiseToml { for (ba, tvp) in &self.tools { for tool in &tvp.0 { let version = self.parse_template(&tool.tt.to_string())?; - let mut tvr = if let Some(mut options) = tool.options.clone() { + let tvr = if let Some(mut options) = tool.options.clone() { for v in options.opts.values_mut() { *v = self.parse_template(v)?; } @@ -424,7 +441,6 @@ impl ConfigFile for MiseToml { } else { ToolRequest::new(ba.clone(), &version, source.clone())? }; - tvr = tvr.with_os(tool.os.clone()); trs.add_version(tvr, &source); } } @@ -572,13 +588,11 @@ impl From for MiseTomlTool { match tr { ToolRequest::Version { version, - os, options, backend: _backend, source: _source, } => Self { tt: ToolVersionType::Version(version), - os, options: if options.is_empty() { None } else { @@ -587,13 +601,11 @@ impl From for MiseTomlTool { }, ToolRequest::Path { path, - os, options, backend: _backend, source: _source, } => Self { tt: ToolVersionType::Path(path), - os, options: if options.is_empty() { None } else { @@ -602,13 +614,11 @@ impl From for MiseTomlTool { }, ToolRequest::Prefix { prefix, - os, options, backend: _backend, source: _source, } => Self { tt: ToolVersionType::Prefix(prefix), - os, options: if options.is_empty() { None } else { @@ -618,13 +628,11 @@ impl From for MiseTomlTool { ToolRequest::Ref { ref_, ref_type, - os, options, backend: _backend, source: _source, } => Self { tt: ToolVersionType::Ref(ref_, ref_type), - os, options: if options.is_empty() { None } else { @@ -633,14 +641,12 @@ impl From for MiseTomlTool { }, ToolRequest::Sub { sub, - os, options, orig_version, backend: _backend, source: _source, } => Self { tt: ToolVersionType::Sub { sub, orig_version }, - os, options: if options.is_empty() { None } else { @@ -648,13 +654,11 @@ impl From for MiseTomlTool { }, }, ToolRequest::System { - os, options, backend: _backend, source: _source, } => Self { tt: ToolVersionType::System, - os, options: if options.is_empty() { None } else { @@ -1049,11 +1053,7 @@ impl<'de> de::Deserialize<'de> for MiseTomlToolList { let tt: ToolVersionType = v .parse() .map_err(|e| de::Error::custom(format!("invalid tool: {e}")))?; - Ok(MiseTomlToolList(vec![MiseTomlTool { - tt, - os: None, - options: None, - }])) + Ok(MiseTomlToolList(vec![MiseTomlTool { tt, options: None }])) } fn visit_seq(self, mut seq: S) -> std::result::Result @@ -1072,7 +1072,6 @@ impl<'de> de::Deserialize<'de> for MiseTomlToolList { M: de::MapAccess<'de>, { let mut options: ToolVersionOptions = Default::default(); - let mut os: Option> = None; let mut tt: Option = None; while let Some((k, v)) = map.next_entry::()? { match k.as_str() { @@ -1088,7 +1087,7 @@ impl<'de> de::Deserialize<'de> for MiseTomlToolList { } "os" => match v { toml::Value::Array(s) => { - os = Some( + options.os = Some( s.iter().map(|v| v.as_str().unwrap().to_string()).collect(), ); } @@ -1104,13 +1103,13 @@ impl<'de> de::Deserialize<'de> for MiseTomlToolList { for (k, v) in env { match v { toml::Value::Boolean(v) => { - options.env.insert(k, v.to_string()); + options.install_env.insert(k, v.to_string()); } toml::Value::Integer(v) => { - options.env.insert(k, v.to_string()); + options.install_env.insert(k, v.to_string()); } toml::Value::String(v) => { - options.env.insert(k, v); + options.install_env.insert(k, v); } _ => { return Err(de::Error::custom("invalid value type")); @@ -1141,7 +1140,6 @@ impl<'de> de::Deserialize<'de> for MiseTomlToolList { if let Some(tt) = tt { Ok(MiseTomlToolList(vec![MiseTomlTool { tt, - os, options: Some(options), }])) } else { @@ -1242,11 +1240,7 @@ impl<'de> de::Deserialize<'de> for MiseTomlTool { let tt: ToolVersionType = v .parse() .map_err(|e| de::Error::custom(format!("invalid tool: {e}")))?; - Ok(MiseTomlTool { - tt, - os: None, - options: None, - }) + Ok(MiseTomlTool { tt, options: None }) } fn visit_map(self, mut map: M) -> Result @@ -1254,7 +1248,6 @@ impl<'de> de::Deserialize<'de> for MiseTomlTool { M: de::MapAccess<'de>, { let mut options: ToolVersionOptions = Default::default(); - let mut os: Option> = None; let mut tt = ToolVersionType::System; while let Some((k, v)) = map.next_entry::()? { match k.as_str() { @@ -1268,7 +1261,7 @@ impl<'de> de::Deserialize<'de> for MiseTomlTool { } "os" => match v { toml::Value::Array(s) => { - os = Some( + options.os = Some( s.iter().map(|v| v.as_str().unwrap().to_string()).collect(), ); } @@ -1284,13 +1277,13 @@ impl<'de> de::Deserialize<'de> for MiseTomlTool { for (k, v) in env { match v { toml::Value::Boolean(v) => { - options.env.insert(k, v.to_string()); + options.install_env.insert(k, v.to_string()); } toml::Value::Integer(v) => { - options.env.insert(k, v.to_string()); + options.install_env.insert(k, v.to_string()); } toml::Value::String(v) => { - options.env.insert(k, v); + options.install_env.insert(k, v); } _ => { return Err(de::Error::custom("invalid value type")); @@ -1309,7 +1302,6 @@ impl<'de> de::Deserialize<'de> for MiseTomlTool { } Ok(MiseTomlTool { tt, - os, options: Some(options), }) } diff --git a/src/config/config_file/mod.rs b/src/config/config_file/mod.rs index f8d41f2c86..03babfd452 100644 --- a/src/config/config_file/mod.rs +++ b/src/config/config_file/mod.rs @@ -148,7 +148,6 @@ impl dyn ConfigFile { if let ToolRequest::Version { version: _version, source, - os, options, backend, } = tr @@ -156,7 +155,6 @@ impl dyn ConfigFile { tr = ToolRequest::Version { version: tv.version, source, - os, options, backend, }; diff --git a/src/config/config_file/snapshots/mise__config__config_file__mise_toml__tests__fixture-3.snap b/src/config/config_file/snapshots/mise__config__config_file__mise_toml__tests__fixture-3.snap index b4f362cba9..ad1fc32a1a 100644 --- a/src/config/config_file/snapshots/mise__config__config_file__mise_toml__tests__fixture-3.snap +++ b/src/config/config_file/snapshots/mise__config__config_file__mise_toml__tests__fixture-3.snap @@ -10,13 +10,13 @@ ToolRequestSet { backend: BackendArg(terraform), version: "1.0.0", options: ToolVersionOptions { - env: {}, + os: None, + install_env: {}, opts: {}, }, source: MiseToml( "~/fixtures/.mise.toml", ), - os: None, }, ], BackendArg(node): [ @@ -24,50 +24,50 @@ ToolRequestSet { backend: BackendArg(node), version: "18", options: ToolVersionOptions { - env: {}, + os: None, + install_env: {}, opts: {}, }, source: MiseToml( "~/fixtures/.mise.toml", ), - os: None, }, Prefix { backend: BackendArg(node), prefix: "20", options: ToolVersionOptions { - env: {}, + os: None, + install_env: {}, opts: {}, }, source: MiseToml( "~/fixtures/.mise.toml", ), - os: None, }, Ref { backend: BackendArg(node), ref_: "master", ref_type: "ref", options: ToolVersionOptions { - env: {}, + os: None, + install_env: {}, opts: {}, }, source: MiseToml( "~/fixtures/.mise.toml", ), - os: None, }, Path { backend: BackendArg(node), path: "~/.nodes/18", options: ToolVersionOptions { - env: {}, + os: None, + install_env: {}, opts: {}, }, source: MiseToml( "~/fixtures/.mise.toml", ), - os: None, }, ], BackendArg(jq): [ @@ -75,13 +75,13 @@ ToolRequestSet { backend: BackendArg(jq), prefix: "1.6", options: ToolVersionOptions { - env: {}, + os: None, + install_env: {}, opts: {}, }, source: MiseToml( "~/fixtures/.mise.toml", ), - os: None, }, ], BackendArg(shellcheck): [ @@ -89,13 +89,13 @@ ToolRequestSet { backend: BackendArg(shellcheck), version: "0.9.0", options: ToolVersionOptions { - env: {}, + os: None, + install_env: {}, opts: {}, }, source: MiseToml( "~/fixtures/.mise.toml", ), - os: None, }, ], BackendArg(python): [ @@ -103,7 +103,8 @@ ToolRequestSet { backend: BackendArg(python), version: "3.10.0", options: ToolVersionOptions { - env: {}, + os: None, + install_env: {}, opts: { "venv": ".venv", }, @@ -111,19 +112,18 @@ ToolRequestSet { source: MiseToml( "~/fixtures/.mise.toml", ), - os: None, }, Version { backend: BackendArg(python), version: "3.9.0", options: ToolVersionOptions { - env: {}, + os: None, + install_env: {}, opts: {}, }, source: MiseToml( "~/fixtures/.mise.toml", ), - os: None, }, ], }, diff --git a/src/config/config_file/snapshots/mise__config__config_file__mise_toml__tests__replace_versions.snap b/src/config/config_file/snapshots/mise__config__config_file__mise_toml__tests__replace_versions.snap index e73ad21704..a8f24d1747 100644 --- a/src/config/config_file/snapshots/mise__config__config_file__mise_toml__tests__replace_versions.snap +++ b/src/config/config_file/snapshots/mise__config__config_file__mise_toml__tests__replace_versions.snap @@ -13,25 +13,25 @@ Toolset { backend: BackendArg(node), version: "16.0.1", options: ToolVersionOptions { - env: {}, + os: None, + install_env: {}, opts: {}, }, source: MiseToml( "/tmp/.mise.toml", ), - os: None, }, Version { backend: BackendArg(node), version: "18.0.1", options: ToolVersionOptions { - env: {}, + os: None, + install_env: {}, opts: {}, }, source: MiseToml( "/tmp/.mise.toml", ), - os: None, }, ], source: MiseToml( diff --git a/src/toolset/mod.rs b/src/toolset/mod.rs index 9cbe6d8423..db925d766a 100644 --- a/src/toolset/mod.rs +++ b/src/toolset/mod.rs @@ -43,14 +43,15 @@ mod tool_version_list; #[derive(Debug, Default, Clone, Hash, PartialEq, Eq, serde::Deserialize, serde::Serialize)] pub struct ToolVersionOptions { - pub env: BTreeMap, + pub os: Option>, + pub install_env: BTreeMap, #[serde(flatten)] pub opts: BTreeMap, } impl ToolVersionOptions { pub fn is_empty(&self) -> bool { - self.env.is_empty() && self.opts.is_empty() + self.install_env.is_empty() && self.opts.is_empty() } pub fn get(&self, key: &str) -> Option<&String> { @@ -407,7 +408,6 @@ impl Toolset { backend: p.ba().clone(), ref_: r.to_string(), ref_type: ref_type.to_string(), - os: v.request.os().clone(), options: v.request.options().clone(), source: v.request.source().clone(), }; diff --git a/src/toolset/outdated_info.rs b/src/toolset/outdated_info.rs index 057ee7f851..3695eb01c2 100644 --- a/src/toolset/outdated_info.rs +++ b/src/toolset/outdated_info.rs @@ -89,14 +89,12 @@ impl OutdatedInfo { backend, options, source, - os, } => { oi.tool_request = ToolRequest::Version { backend, options, source, version: format!("{prefix}{bumped_version}"), - os, }; Some(oi.tool_request.version()) } @@ -105,14 +103,12 @@ impl OutdatedInfo { backend, options, source, - os, } => { oi.tool_request = ToolRequest::Prefix { backend, options, source, prefix: format!("{prefix}{bumped_version}"), - os, }; Some(oi.tool_request.version()) } @@ -165,6 +161,9 @@ impl Display for OutdatedInfo { /// used with `mise outdated --bump` to determine what new semver range to use /// given old: "20" and new: "21.2.3", return Some("21") fn check_semver_bump(old: &str, new: &str) -> Option { + if old == "latest" { + return Some("latest".to_string()); + } if let Some(("prefix", old_)) = old.split_once(':') { return check_semver_bump(old_, new); } @@ -295,7 +294,7 @@ mod tests { ); std::assert_eq!( check_semver_bump("latest", "20.0.0"), - Some("20.0.0".to_string()) + Some("latest".to_string()) ); } } diff --git a/src/toolset/tool_request.rs b/src/toolset/tool_request.rs index af036ac1fb..c5e765dfd5 100644 --- a/src/toolset/tool_request.rs +++ b/src/toolset/tool_request.rs @@ -20,14 +20,12 @@ pub enum ToolRequest { version: String, options: ToolVersionOptions, source: ToolSource, - os: Option>, }, Prefix { backend: BackendArg, prefix: String, options: ToolVersionOptions, source: ToolSource, - os: Option>, }, Ref { backend: BackendArg, @@ -35,7 +33,6 @@ pub enum ToolRequest { ref_type: String, options: ToolVersionOptions, source: ToolSource, - os: Option>, }, Sub { backend: BackendArg, @@ -43,20 +40,17 @@ pub enum ToolRequest { orig_version: String, options: ToolVersionOptions, source: ToolSource, - os: Option>, }, Path { backend: BackendArg, path: PathBuf, options: ToolVersionOptions, source: ToolSource, - os: Option>, }, System { backend: BackendArg, source: ToolSource, options: ToolVersionOptions, - os: Option>, }, } @@ -71,21 +65,18 @@ impl ToolRequest { ref_: r.to_string(), ref_type: ref_type.to_string(), options: backend.opts(), - os: None, backend, source, }, Some(("prefix", p)) => Self::Prefix { prefix: p.to_string(), options: backend.opts(), - os: None, backend, source, }, Some(("path", p)) => Self::Path { path: PathBuf::from(p), options: backend.opts(), - os: None, backend, source, }, @@ -93,7 +84,6 @@ impl ToolRequest { sub: p.split_once('-').unwrap().1.to_string(), options: backend.opts(), orig_version: v.to_string(), - os: None, backend, source, }, @@ -101,7 +91,6 @@ impl ToolRequest { if s == "system" { Self::System { options: backend.opts(), - os: None, backend, source, } @@ -109,7 +98,6 @@ impl ToolRequest { Self::Version { version: s, options: backend.opts(), - os: None, backend, source, } @@ -169,12 +157,12 @@ impl ToolRequest { } pub fn os(&self) -> &Option> { match self { - Self::Version { os, .. } - | Self::Prefix { os, .. } - | Self::Ref { os, .. } - | Self::Path { os, .. } - | Self::Sub { os, .. } - | Self::System { os, .. } => os, + Self::Version { options, .. } + | Self::Prefix { options, .. } + | Self::Ref { options, .. } + | Self::Path { options, .. } + | Self::Sub { options, .. } + | Self::System { options, .. } => &options.os, } } pub fn set_options(&mut self, options: ToolVersionOptions) -> &mut Self { @@ -188,17 +176,6 @@ impl ToolRequest { } self } - pub fn with_os(mut self, os: Option>) -> Self { - match &mut self { - Self::Version { os: o, .. } - | Self::Prefix { os: o, .. } - | Self::Ref { os: o, .. } - | Self::Path { os: o, .. } - | Self::Sub { os: o, .. } - | Self::System { os: o, .. } => *o = os, - } - self - } pub fn version(&self) -> String { match self { Self::Version { version: v, .. } => v.clone(), diff --git a/src/toolset/tool_version.rs b/src/toolset/tool_version.rs index d866c5c4ca..869810896c 100644 --- a/src/toolset/tool_version.rs +++ b/src/toolset/tool_version.rs @@ -250,7 +250,6 @@ impl ToolVersion { backend: tr.ba().clone(), ref_, ref_type, - os: None, options: opts.clone(), source: tr.source().clone(), }; @@ -264,7 +263,6 @@ impl ToolVersion { backend: tr.ba().clone(), path, source: tr.source().clone(), - os: None, options: tr.options().clone(), }; let version = request.version();