Skip to content

Commit

Permalink
feat: added os option to mise.toml
Browse files Browse the repository at this point in the history
  • Loading branch information
jdx committed Nov 16, 2024
1 parent 0ea3156 commit 7992074
Show file tree
Hide file tree
Showing 12 changed files with 169 additions and 75 deletions.
1 change: 0 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ jobs:
- run: cargo test
continue-on-error: true
- run: mise install
continue-on-error: true
- run: mise test-tool --all
continue-on-error: true
windows-e2e:
Expand Down
4 changes: 2 additions & 2 deletions mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ shellcheck = "0.10"
shfmt = "3"
jq = "latest"
cargo-binstall = "latest"
"cargo:cargo-edit" = "latest"
"cargo:cargo-show" = "latest"
"cargo:cargo-edit" = {version = "latest", os=["linux", "macos"]}
"cargo:cargo-show" = {version = "latest", os=["linux", "macos"]}
"cargo:cargo-insta" = "latest"
"cargo:git-cliff" = "latest"
"npm:markdownlint-cli" = "latest"
Expand Down
8 changes: 4 additions & 4 deletions src/backend/asdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ impl AsdfBackend {

fn fetch_bin_paths(&self, tv: &ToolVersion) -> Result<Vec<String>> {
let list_bin_paths = self.plugin_path.join("bin/list-bin-paths");
let bin_paths = if matches!(tv.request, ToolRequest::System(..)) {
let bin_paths = if matches!(tv.request, ToolRequest::System{..}) {
Vec::new()
} else if list_bin_paths.exists() {
let sm = self.script_man_for_tv(tv)?;
Expand Down Expand Up @@ -184,9 +184,9 @@ impl AsdfBackend {
let install_type = match &tv.request {
ToolRequest::Version { .. } | ToolRequest::Prefix { .. } => "version",
ToolRequest::Ref { .. } => "ref",
ToolRequest::Path(..) => "path",
ToolRequest::Path{ .. } => "path",
ToolRequest::Sub { .. } => "sub",
ToolRequest::System(..) => {
ToolRequest::System{ .. } => {
panic!("should not be called for system tool")
}
};
Expand Down Expand Up @@ -384,7 +384,7 @@ impl Backend for AsdfBackend {
ts: &Toolset,
tv: &ToolVersion,
) -> eyre::Result<BTreeMap<String, String>> {
if matches!(tv.request, ToolRequest::System(..)) {
if matches!(tv.request, ToolRequest::System{ .. }) {
return Ok(BTreeMap::new());
}
if !self.plugin.script_man.script_exists(&ExecEnv) || *env::__MISE_SCRIPT {
Expand Down
17 changes: 9 additions & 8 deletions src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ pub trait Backend: Debug + Send + Sync {
.collect::<Vec<ABackend>>();
for dep in dep_backends {
// TODO: pass the right tvr
let tvr = ToolRequest::System(dep.id().into(), ToolSource::Unknown);
let tvr = ToolRequest::System{ backend: dep.id().into(), source: ToolSource::Unknown, os: None };
deps.extend(dep.get_all_dependencies(&tvr)?);
}
Ok(deps.into_iter().collect())
Expand Down Expand Up @@ -242,7 +242,7 @@ pub trait Backend: Debug + Send + Sync {
}
fn is_version_installed(&self, tv: &ToolVersion, check_symlink: bool) -> bool {
match tv.request {
ToolRequest::System(..) => true,
ToolRequest::System{ .. } => true,
_ => {
let check_path = |install_path: &Path| {
let is_installed = install_path.exists();
Expand Down Expand Up @@ -338,7 +338,7 @@ pub trait Backend: Debug + Send + Sync {

fn ensure_dependencies_installed(&self) -> eyre::Result<()> {
let deps = self
.get_all_dependencies(&ToolRequest::System(self.id().into(), ToolSource::Unknown))?
.get_all_dependencies(&ToolRequest::System{ backend: self.id().into(), source: ToolSource::Unknown, os: None })?
.into_iter()
.collect::<HashSet<_>>();
if !deps.is_empty() {
Expand Down Expand Up @@ -474,7 +474,7 @@ pub trait Backend: Debug + Send + Sync {
}
fn list_bin_paths(&self, tv: &ToolVersion) -> eyre::Result<Vec<PathBuf>> {
match tv.request {
ToolRequest::System(..) => Ok(vec![]),
ToolRequest::System{..} => Ok(vec![]),
_ => Ok(vec![tv.install_path().join("bin")]),
}
}
Expand Down Expand Up @@ -531,10 +531,11 @@ pub trait Backend: Debug + Send + Sync {
fn dependency_toolset(&self) -> eyre::Result<Toolset> {
let config = Config::get();
let dependencies = self
.get_all_dependencies(&ToolRequest::System(
self.name().into(),
ToolSource::Unknown,
))?
.get_all_dependencies(&ToolRequest::System{
backend: self.name().into(),
source: ToolSource::Unknown,
os: None,
})?
.into_iter()
.collect();
let mut ts: Toolset = config
Expand Down
1 change: 1 addition & 0 deletions src/cli/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ impl Install {
let tvr = ToolRequest::Version {
backend: ta.ba.clone(),
version: "latest".into(),
os: None,
options: ta.opts.clone().unwrap_or(Default::default()),
source: ToolSource::Argument,
};
Expand Down
98 changes: 68 additions & 30 deletions src/config/config_file/mise_toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ pub struct MiseTomlToolList(Vec<MiseTomlTool>);
#[derive(Debug, Clone)]
pub struct MiseTomlTool {
pub tt: ToolVersionType,
pub os: Option<Vec<String>>,
pub options: Option<ToolVersionOptions>,
}

Expand Down Expand Up @@ -313,6 +314,7 @@ impl ConfigFile for MiseToml {
.iter()
.map(|(v, opts)| MiseTomlTool {
tt: ToolVersionType::Version(v.clone()),
os: None, // TODO: use existing os
options: if !output_empty_opts(opts) {
Some(opts.clone())
} else {
Expand Down Expand Up @@ -391,16 +393,16 @@ impl ConfigFile for MiseToml {
trust_check(&self.path)?;
}
let version = self.parse_template(&tool.tt.to_string())?;
if let Some(mut options) = tool.options.clone() {
let mut tvr = if let Some(mut options) = tool.options.clone() {
for v in options.values_mut() {
*v = self.parse_template(v)?;
}
let tvr = ToolRequest::new_opts(fa.clone(), &version, options, source.clone())?;
trs.add_version(tvr, &source);
ToolRequest::new_opts(fa.clone(), &version, options, source.clone())?
} else {
let tvr = ToolRequest::new(fa.clone(), &version, source.clone())?;
trs.add_version(tvr, &source);
}
ToolRequest::new(fa.clone(), &version, source.clone())?
};
tvr = tvr.with_os(tool.os.clone());
trs.add_version(tvr, &source);
}
}
Ok(trs)
Expand Down Expand Up @@ -759,7 +761,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, options: None }]))
Ok(MiseTomlToolList(vec![MiseTomlTool { tt, os: None, options: None }]))
}

fn visit_seq<S>(self, mut seq: S) -> std::result::Result<Self::Value, S::Error>
Expand All @@ -773,22 +775,40 @@ impl<'de> de::Deserialize<'de> for MiseTomlToolList {
Ok(MiseTomlToolList(tools))
}

fn visit_map<M>(self, map: M) -> std::result::Result<Self::Value, M::Error>
fn visit_map<M>(self, mut map: M) -> std::result::Result<Self::Value, M::Error>
where
M: de::MapAccess<'de>,
{
let mut options: BTreeMap<String, String> =
de::Deserialize::deserialize(de::value::MapAccessDeserializer::new(map))?;
let tt: ToolVersionType = options
.remove("version")
.or_else(|| options.remove("path").map(|p| format!("path:{p}")))
.or_else(|| options.remove("prefix").map(|p| format!("prefix:{p}")))
.or_else(|| options.remove("ref").map(|p| format!("ref:{p}")))
.ok_or_else(|| de::Error::custom("missing version"))?
.parse()
.map_err(de::Error::custom)?;
let mut options: BTreeMap<String, String> = Default::default();
let mut os: Option<Vec<String>> = None;
let mut tt = ToolVersionType::System;
while let Some((k, v)) = map.next_entry::<String, toml::Value>()? {
match k.as_str() {
"version" => {
tt = v.as_str().unwrap().parse().map_err(de::Error::custom)?;
},
"path" | "prefix" | "ref" => {
tt = format!("{k}:{}", v.as_str().unwrap()).parse().map_err(de::Error::custom)?;
},
"os" => match v {
toml::Value::Array(s) => {
os = Some(s.iter().map(|v| v.as_str().unwrap().to_string()).collect());
}
toml::Value::String(s) => {
options.insert(k, s);
}
_ => {
return Err(de::Error::custom("os must be a string or array"));
}
},
_ => {
options.insert(k, v.to_string());
}
}
}
Ok(MiseTomlToolList(vec![MiseTomlTool {
tt,
os,
options: Some(options),
}]))
}
Expand Down Expand Up @@ -818,25 +838,43 @@ 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, options: None })
Ok(MiseTomlTool { tt, os: None, options: None })
}

fn visit_map<M>(self, map: M) -> Result<Self::Value, M::Error>
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
where
M: de::MapAccess<'de>,
{
let mut options: BTreeMap<String, String> =
de::Deserialize::deserialize(de::value::MapAccessDeserializer::new(map))?;
let tt: ToolVersionType = options
.remove("version")
.or_else(|| options.remove("path").map(|p| format!("path:{p}")))
.or_else(|| options.remove("prefix").map(|p| format!("prefix:{p}")))
.or_else(|| options.remove("ref").map(|p| format!("ref:{p}")))
.ok_or_else(|| de::Error::custom("missing version"))?
.parse()
.map_err(de::Error::custom)?;
let mut options: BTreeMap<String, String> = Default::default();
let mut os: Option<Vec<String>> = None;
let mut tt = ToolVersionType::System;
while let Some((k, v)) = map.next_entry::<String, toml::Value>()? {
match k.as_str() {
"version" => {
tt = v.as_str().unwrap().parse().map_err(de::Error::custom)?;
},
"path" | "prefix" | "ref" => {
tt = format!("{k}:{}", v.as_str().unwrap()).parse().map_err(de::Error::custom)?;
},
"os" => match v {
toml::Value::Array(s) => {
os = Some(s.iter().map(|v| v.as_str().unwrap().to_string()).collect());
}
toml::Value::String(s) => {
options.insert(k, s);
}
_ => {
return Err(de::Error::custom("os must be a string or array"));
}
},
_ => {
options.insert(k, v.to_string());
}
}
}
Ok(MiseTomlTool {
tt,
os,
options: Some(options),
})
}
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/core/deno.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ impl Backend for DenoPlugin {
}

fn list_bin_paths(&self, tv: &ToolVersion) -> Result<Vec<PathBuf>> {
if let ToolRequest::System(..) = tv.request {
if let ToolRequest::System{ .. } = tv.request {
return Ok(vec![]);
}
let bin_paths = vec![
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/core/go.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ impl Backend for GoPlugin {
}

fn list_bin_paths(&self, tv: &ToolVersion) -> eyre::Result<Vec<PathBuf>> {
if let ToolRequest::System(..) = tv.request {
if let ToolRequest::System{ .. } = tv.request {
return Ok(vec![]);
}
// goroot/bin must always be included, irrespective of MISE_GO_SET_GOROOT
Expand Down
21 changes: 16 additions & 5 deletions src/toolset/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,9 @@ impl Toolset {

pub fn list_missing_plugins(&self) -> Vec<String> {
self.versions
.keys()
.filter(|ba| ba.is_os_supported())
.iter()
.filter(|(_, tvl)| tvl.versions.first().map(|tv| tv.request.is_os_supported()).unwrap_or_default())
.map(|(ba, _)| ba)
.flat_map(|ba| ba.backend())
.filter(|b| b.plugin().is_some_and(|p| !p.is_installed()))
.map(|p| p.id().into())
Expand Down Expand Up @@ -289,7 +290,14 @@ impl Toolset {
pub fn list_missing_versions(&self) -> Vec<ToolVersion> {
self.list_current_versions()
.into_iter()
.filter(|(p, tv)| tv.ba().is_os_supported() && !p.is_version_installed(tv, true))
.filter(|(p, tv)| {
if let Some(os) = tv.request.os() {
if !os.contains(&crate::cli::version::OS) {
return false;
}
}
tv.request.is_os_supported() && !p.is_version_installed(tv, true)
})
.map(|(_, tv)| tv)
.collect()
}
Expand Down Expand Up @@ -349,6 +357,7 @@ 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(),
};
Expand Down Expand Up @@ -425,12 +434,14 @@ impl Toolset {
version: _version,
options,
source,
os,
} => {
out.tool_request = ToolRequest::Version {
backend,
options,
source,
version: out.bump.clone().unwrap(),
os,
};
}
_ => {
Expand Down Expand Up @@ -473,7 +484,7 @@ impl Toolset {
let entries = self
.list_current_installed_versions()
.into_par_iter()
.filter(|(_, tv)| !matches!(tv.request, ToolRequest::System(..)))
.filter(|(_, tv)| !matches!(tv.request, ToolRequest::System{ .. }))
.flat_map(|(p, tv)| match p.exec_env(config, self, &tv) {
Ok(env) => env.into_iter().collect(),
Err(e) => {
Expand Down Expand Up @@ -506,7 +517,7 @@ impl Toolset {
pub fn list_paths(&self) -> Vec<PathBuf> {
self.list_current_installed_versions()
.into_par_iter()
.filter(|(_, tv)| !matches!(tv.request, ToolRequest::System(..)))
.filter(|(_, tv)| !matches!(tv.request, ToolRequest::System{ .. }))
.flat_map(|(p, tv)| {
p.list_bin_paths(&tv).unwrap_or_else(|e| {
warn!("Error listing bin paths for {tv}: {e:#}");
Expand Down
Loading

0 comments on commit 7992074

Please sign in to comment.