diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index b9aa4fc48..89d7c1f1a 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -19,6 +19,7 @@ env: MISE_EXPERIMENTAL: 1 RUST_BACKTRACE: 1 NPM_CONFIG_FUND: false + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} jobs: autofix: diff --git a/docs/registry.md b/docs/registry.md index 27a89084a..e57fed38b 100644 --- a/docs/registry.md +++ b/docs/registry.md @@ -608,10 +608,10 @@ editLink: false | restic | [asdf:xataz/asdf-restic](https://github.com/xataz/asdf-restic) | | restish | [ubi:danielgtaylor/restish](https://github.com/danielgtaylor/restish) [go:github.com/danielgtaylor/restish](https://pkg.go.dev/github.com/danielgtaylor/restish) | | revive | [aqua:mgechev/revive](https://github.com/mgechev/revive) [asdf:bjw-s/asdf-revive](https://github.com/bjw-s/asdf-revive) | -| rg | [ubi:BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep) [aqua:BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep) [asdf:https://gitlab.com/wt0f/asdf-ripgrep](https://gitlab.com/wt0f/asdf-ripgrep) | +| rg | [aqua:BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep) [ubi:BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep) [asdf:https://gitlab.com/wt0f/asdf-ripgrep](https://gitlab.com/wt0f/asdf-ripgrep) | | richgo | [aqua:kyoh86/richgo](https://github.com/kyoh86/richgo) [asdf:paxosglobal/asdf-richgo](https://github.com/paxosglobal/asdf-richgo) | | riff | [asdf:abinet/asdf-riff](https://github.com/abinet/asdf-riff) | -| ripgrep | [ubi:BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep) [aqua:BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep) [asdf:https://gitlab.com/wt0f/asdf-ripgrep](https://gitlab.com/wt0f/asdf-ripgrep) | +| ripgrep | [aqua:BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep) [ubi:BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep) [asdf:https://gitlab.com/wt0f/asdf-ripgrep](https://gitlab.com/wt0f/asdf-ripgrep) | | rke | [aqua:rancher/rke](https://github.com/rancher/rke) [asdf:particledecay/asdf-rke](https://github.com/particledecay/asdf-rke) | | rlwrap | [asdf:asdf-community/asdf-rlwrap](https://github.com/asdf-community/asdf-rlwrap) | | rome | [asdf:kichiemon/asdf-rome](https://github.com/kichiemon/asdf-rome) | @@ -682,7 +682,7 @@ editLink: false | step | [asdf:log2/asdf-step](https://github.com/log2/asdf-step) | | stern | [aqua:stern/stern](https://github.com/stern/stern) [asdf:looztra/asdf-stern](https://github.com/looztra/asdf-stern) | | stripe-cli | [aqua:stripe/stripe-cli](https://github.com/stripe/stripe-cli) [asdf:offbyone/asdf-stripe](https://github.com/offbyone/asdf-stripe) | -| stylua | [asdf:jc00ke/asdf-stylua](https://github.com/jc00ke/asdf-stylua) | +| stylua | [aqua:JohnnyMorganz/StyLua](https://github.com/JohnnyMorganz/StyLua) [asdf:jc00ke/asdf-stylua](https://github.com/jc00ke/asdf-stylua) | | sui | [asdf:placeholder-soft/asdf-sui](https://github.com/placeholder-soft/asdf-sui) | | sver | [aqua:mitoma/sver](https://github.com/mitoma/sver) [asdf:robzr/asdf-sver](https://github.com/robzr/asdf-sver) | | svu | [aqua:caarlos0/svu](https://github.com/caarlos0/svu) [asdf:asdf-community/asdf-svu](https://github.com/asdf-community/asdf-svu) | diff --git a/e2e/backend/test_ubi b/e2e/backend/test_ubi index eaf6825f9..0be975c6b 100644 --- a/e2e/backend/test_ubi +++ b/e2e/backend/test_ubi @@ -4,3 +4,12 @@ assert "mise x ubi:goreleaser/goreleaser@v1.25.0 -- goreleaser -v | grep -o 1.25 mise use ubi:kellyjonbrazil/jc@1.25.3 assert_contains "$MISE_DATA_DIR/shims/jc --version" "jc version: 1.25.3" + +cat <mise.toml +[tools] +"ubi:cilium/cilium-cli" = { version = "latest", exe = "cilium" } +EOF +# re-uses tool options +mise use ubi:cilium/cilium-cli +assert "cat mise.toml" '[tools] +"ubi:cilium/cilium-cli" = { version = "latest", exe = "cilium" }' diff --git a/e2e/tools/test_tools_alias b/e2e/config/test_config_alias similarity index 100% rename from e2e/tools/test_tools_alias rename to e2e/config/test_config_alias diff --git a/registry.toml b/registry.toml index ebb873b06..e821d8a81 100644 --- a/registry.toml +++ b/registry.toml @@ -625,7 +625,7 @@ revive.backends = ["aqua:mgechev/revive", "asdf:bjw-s/asdf-revive"] richgo.backends = ["aqua:kyoh86/richgo", "asdf:paxosglobal/asdf-richgo"] riff.backends = ["asdf:abinet/asdf-riff"] ripgrep.aliases = ["rg"] -ripgrep.backends = ["ubi:BurntSushi/ripgrep[exe=rg]", "aqua:BurntSushi/ripgrep", "asdf:https://gitlab.com/wt0f/asdf-ripgrep"] +ripgrep.backends = ["aqua:BurntSushi/ripgrep", "ubi:BurntSushi/ripgrep[exe=rg]", "asdf:https://gitlab.com/wt0f/asdf-ripgrep"] ripgrep.test = ["rg --version", "ripgrep {{version}}"] rke.backends = ["aqua:rancher/rke", "asdf:particledecay/asdf-rke"] rlwrap.backends = ["asdf:asdf-community/asdf-rlwrap"] @@ -699,7 +699,8 @@ steampipe.backends = ["aqua:turbot/steampipe", "asdf:carnei-ro/asdf-steampipe"] step.backends = ["asdf:log2/asdf-step"] stern.backends = ["aqua:stern/stern", "asdf:looztra/asdf-stern"] stripe-cli.backends = ["aqua:stripe/stripe-cli", "asdf:offbyone/asdf-stripe"] -stylua.backends = ["asdf:jc00ke/asdf-stylua"] +stylua.backends = ["aqua:JohnnyMorganz/StyLua", "asdf:jc00ke/asdf-stylua"] +stylua.test = ["stylua --version", "stylua {{version}}"] sui.backends = ["asdf:placeholder-soft/asdf-sui"] sver.backends = ["aqua:mitoma/sver", "asdf:robzr/asdf-sver"] svu.backends = ["aqua:caarlos0/svu", "asdf:asdf-community/asdf-svu"] diff --git a/src/backend/cargo.rs b/src/backend/cargo.rs index b65d376f8..85eaa15ee 100644 --- a/src/backend/cargo.rs +++ b/src/backend/cargo.rs @@ -47,7 +47,7 @@ impl Backend for CargoBackend { } self.remote_version_cache .get_or_try_init(|| { - let raw = HTTP_FETCH.get_text(get_crate_url(self.name())?)?; + let raw = HTTP_FETCH.get_text(get_crate_url(&self.tool_name())?)?; let stream = Deserializer::from_str(&raw).into_iter::(); let mut versions = vec![]; for v in stream { @@ -63,7 +63,7 @@ impl Backend for CargoBackend { fn install_version_impl(&self, ctx: &InstallContext) -> eyre::Result<()> { let config = Config::try_get()?; - let install_arg = format!("{}@{}", self.name(), ctx.tv.version); + let install_arg = format!("{}@{}", self.tool_name(), ctx.tv.version); let cmd = CmdLineRunner::new("cargo").arg("install"); let mut cmd = if let Some(url) = self.git_url() { @@ -150,9 +150,9 @@ impl CargoBackend { /// if the name is a git repo, return the git url fn git_url(&self) -> Option { - if let Ok(url) = Url::parse(self.name()) { + if let Ok(url) = Url::parse(&self.tool_name()) { Some(url) - } else if let Some((user, repo)) = self.name().split_once('/') { + } else if let Some((user, repo)) = self.tool_name().split_once('/') { format!("https://github.com/{user}/{repo}.git").parse().ok() } else { None diff --git a/src/backend/go.rs b/src/backend/go.rs index e749473f8..e1ab495a5 100644 --- a/src/backend/go.rs +++ b/src/backend/go.rs @@ -31,10 +31,10 @@ impl Backend for GoBackend { fn _list_remote_versions(&self) -> eyre::Result> { self.remote_version_cache .get_or_try_init(|| { - let mut mod_path = Some(self.name()); + let mut mod_path = Some(self.tool_name()); while let Some(cur_mod_path) = mod_path { - let res = cmd!("go", "list", "-m", "-versions", "-json", cur_mod_path) + let res = cmd!("go", "list", "-m", "-versions", "-json", &cur_mod_path) .full_env(self.dependency_env()?) .read(); if let Ok(raw) = res { @@ -72,7 +72,7 @@ impl Backend for GoBackend { let install = |v| { CmdLineRunner::new("go") .arg("install") - .arg(format!("{}@{v}", self.name())) + .arg(format!("{}@{v}", self.tool_name())) .with_pr(ctx.pr.as_ref()) .envs(self.dependency_env()?) .env("GOBIN", ctx.tv.install_path().join("bin")) @@ -101,11 +101,8 @@ impl GoBackend { } } -fn trim_after_last_slash(s: &str) -> Option<&str> { - match s.rsplit_once('/') { - Some((new_path, _)) => Some(new_path), - None => None, - } +fn trim_after_last_slash(s: String) -> Option { + s.rsplit_once('/').map(|(new_path, _)| new_path.to_string()) } #[derive(Debug, serde::Deserialize)] diff --git a/src/backend/mod.rs b/src/backend/mod.rs index b4ae54c56..8f1f02dbd 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -132,8 +132,8 @@ pub trait Backend: Debug + Send + Sync { fn id(&self) -> &str { &self.ba().short } - fn name(&self) -> &str { - &self.ba().tool_name + fn tool_name(&self) -> String { + self.ba().tool_name() } fn get_type(&self) -> BackendType { BackendType::Core @@ -159,6 +159,7 @@ pub trait Backend: Debug + Send + Sync { let tvr = ToolRequest::System { backend: ba.clone(), source: ToolSource::Unknown, + options: Default::default(), os: None, }; if let Ok(backend) = ba.backend() { @@ -310,6 +311,7 @@ pub trait Backend: Debug + Send + Sync { .get_all_dependencies(&ToolRequest::System { backend: self.id().into(), source: ToolSource::Unknown, + options: Default::default(), os: None, })? .into_iter() @@ -515,8 +517,9 @@ pub trait Backend: Debug + Send + Sync { let config = Config::get(); let dependencies = self .get_all_dependencies(&ToolRequest::System { - backend: self.name().into(), + backend: self.tool_name().into(), source: ToolSource::Unknown, + options: Default::default(), os: None, })? .into_iter() diff --git a/src/backend/npm.rs b/src/backend/npm.rs index 5c85ba0cf..e2b93ca8a 100644 --- a/src/backend/npm.rs +++ b/src/backend/npm.rs @@ -35,7 +35,7 @@ impl Backend for NPMBackend { fn _list_remote_versions(&self) -> eyre::Result> { self.remote_version_cache .get_or_try_init(|| { - let raw = cmd!(NPM_PROGRAM, "view", self.name(), "versions", "--json") + let raw = cmd!(NPM_PROGRAM, "view", self.tool_name(), "versions", "--json") .full_env(self.dependency_env()?) .read()?; let versions: Vec = serde_json::from_str(&raw)?; @@ -47,7 +47,7 @@ impl Backend for NPMBackend { fn latest_stable_version(&self) -> eyre::Result> { self.latest_version_cache .get_or_try_init(|| { - let raw = cmd!(NPM_PROGRAM, "view", self.name(), "dist-tags", "--json") + let raw = cmd!(NPM_PROGRAM, "view", self.tool_name(), "dist-tags", "--json") .full_env(self.dependency_env()?) .read()?; let dist_tags: Value = serde_json::from_str(&raw)?; @@ -66,7 +66,7 @@ impl Backend for NPMBackend { if SETTINGS.npm.bun { CmdLineRunner::new("bun") .arg("install") - .arg(format!("{}@{}", self.name(), ctx.tv.version)) + .arg(format!("{}@{}", self.tool_name(), ctx.tv.version)) .arg("--cwd") .arg(ctx.tv.install_path()) .arg("--global") @@ -82,7 +82,7 @@ impl Backend for NPMBackend { CmdLineRunner::new(NPM_PROGRAM) .arg("install") .arg("-g") - .arg(format!("{}@{}", self.name(), ctx.tv.version)) + .arg(format!("{}@{}", self.tool_name(), ctx.tv.version)) .arg("--prefix") .arg(ctx.tv.install_path()) .with_pr(ctx.pr.as_ref()) diff --git a/src/backend/pipx.rs b/src/backend/pipx.rs index aa77eb514..32287724b 100644 --- a/src/backend/pipx.rs +++ b/src/backend/pipx.rs @@ -41,7 +41,7 @@ impl Backend for PIPXBackend { */ fn _list_remote_versions(&self) -> eyre::Result> { self.remote_version_cache - .get_or_try_init(|| match self.name().parse()? { + .get_or_try_init(|| match self.tool_name().parse()? { PipxRequest::Pypi(package) => { let url = format!("https://pypi.org/pypi/{}/json", package); let data: PypiPackage = HTTP_FETCH.json(url)?; @@ -65,7 +65,7 @@ impl Backend for PIPXBackend { fn latest_stable_version(&self) -> eyre::Result> { self.latest_version_cache - .get_or_try_init(|| match self.name().parse()? { + .get_or_try_init(|| match self.tool_name().parse()? { PipxRequest::Pypi(package) => { let url = format!("https://pypi.org/pypi/{}/json", package); let pkg: PypiPackage = HTTP_FETCH.json(url)?; @@ -80,7 +80,7 @@ impl Backend for PIPXBackend { let config = Config::try_get()?; SETTINGS.ensure_experimental("pipx backend")?; let pipx_request = self - .name() + .tool_name() .parse::()? .pipx_request(&ctx.tv.version, &ctx.tv.request.options()); diff --git a/src/backend/spm.rs b/src/backend/spm.rs index 69a2f4449..cfe6512cb 100644 --- a/src/backend/spm.rs +++ b/src/backend/spm.rs @@ -40,7 +40,7 @@ impl Backend for SPMBackend { } fn _list_remote_versions(&self) -> eyre::Result> { - let repo = SwiftPackageRepo::new(self.name())?; + let repo = SwiftPackageRepo::new(&self.tool_name())?; self.remote_version_cache .get_or_try_init(|| { Ok(github::list_releases(repo.shorthand.as_str())? @@ -56,7 +56,7 @@ impl Backend for SPMBackend { let settings = Settings::get(); settings.ensure_experimental("spm backend")?; - let repo = SwiftPackageRepo::new(self.name())?; + let repo = SwiftPackageRepo::new(&self.tool_name())?; let revision = if ctx.tv.version == "latest" { self.latest_stable_version()? .ok_or_else(|| eyre::eyre!("No stable versions found"))? diff --git a/src/backend/ubi.rs b/src/backend/ubi.rs index 61724f4e9..61fa3429a 100644 --- a/src/backend/ubi.rs +++ b/src/backend/ubi.rs @@ -7,6 +7,7 @@ use crate::env::GITHUB_TOKEN; use crate::github; use crate::install_context::InstallContext; use crate::plugins::VERSION_REGEX; +use crate::tokio::RUNTIME; use eyre::bail; use regex::Regex; use std::fmt::Debug; @@ -31,14 +32,14 @@ impl Backend for UbiBackend { } fn _list_remote_versions(&self) -> eyre::Result> { - if name_is_url(self.name()) { + if name_is_url(&self.tool_name()) { Ok(vec!["latest".to_string()]) } else { self.remote_version_cache .get_or_try_init(|| { let opts = self.ba.opts.clone().unwrap_or_default(); let tag_regex = OnceLock::new(); - Ok(github::list_releases(self.name())? + Ok(github::list_releases(&self.tool_name())? .into_iter() .map(|r| r.tag_name) // trim 'v' prefixes if they exist @@ -64,7 +65,7 @@ impl Backend for UbiBackend { fn install_version_impl(&self, ctx: &InstallContext) -> eyre::Result<()> { let mut v = ctx.tv.version.to_string(); - if let Err(err) = github::get_release(self.name(), &ctx.tv.version) { + if let Err(err) = github::get_release(&self.tool_name(), &ctx.tv.version) { // this can fail with a rate limit error or 404, either way, try prefixing and if it fails, try without the prefix // if http::error_code(&err) == Some(404) { debug!( @@ -79,10 +80,9 @@ impl Backend for UbiBackend { let opts = ctx.tv.request.options(); // Workaround because of not knowing how to pull out the value correctly without quoting let path_with_bin = ctx.tv.install_path().join("bin"); + let name = self.tool_name(); - let mut builder = UbiBuilder::new() - .project(self.name()) - .install_dir(path_with_bin); + let mut builder = UbiBuilder::new().project(&name).install_dir(path_with_bin); if let Some(token) = &*GITHUB_TOKEN { builder = builder.github_token(token); @@ -101,12 +101,7 @@ impl Backend for UbiBackend { let mut ubi = builder.build()?; - let rt = tokio::runtime::Builder::new_current_thread() - .enable_io() - .enable_time() - .build()?; - - rt.block_on(ubi.install_binary()) + RUNTIME.block_on(ubi.install_binary()) }; if let Err(err) = install(&v) { diff --git a/src/backend/vfox.rs b/src/backend/vfox.rs index 8173ed80a..07431186f 100644 --- a/src/backend/vfox.rs +++ b/src/backend/vfox.rs @@ -15,6 +15,7 @@ use crate::dirs; use crate::install_context::InstallContext; use crate::plugins::vfox_plugin::VfoxPlugin; use crate::plugins::{Plugin, PluginType}; +use crate::tokio::RUNTIME; use crate::toolset::{ToolRequest, ToolVersion, Toolset}; use crate::ui::multi_progress_report::MultiProgressReport; @@ -45,10 +46,7 @@ impl Backend for VfoxBackend { .get_or_try_init(|| { let (vfox, _log_rx) = self.plugin.vfox(); self.ensure_plugin_installed()?; - let versions = self - .plugin - .runtime()? - .block_on(vfox.list_available_versions(&self.pathname))?; + let versions = RUNTIME.block_on(vfox.list_available_versions(&self.pathname))?; Ok(versions .into_iter() .rev() @@ -67,11 +65,7 @@ impl Backend for VfoxBackend { info!("{}", line); } }); - self.plugin.runtime()?.block_on(vfox.install( - &self.pathname, - &ctx.tv.version, - ctx.tv.install_path(), - ))?; + RUNTIME.block_on(vfox.install(&self.pathname, &ctx.tv.version, ctx.tv.install_path()))?; Ok(()) } @@ -149,9 +143,7 @@ impl VfoxBackend { .get_or_try_init(|| { self.ensure_plugin_installed()?; let (vfox, _log_rx) = self.plugin.vfox(); - Ok(self - .plugin - .runtime()? + Ok(RUNTIME .block_on(vfox.env_keys(&self.pathname, &tv.version))? .into_iter() .fold(BTreeMap::new(), |mut acc, env_key| { diff --git a/src/cli/args/backend_arg.rs b/src/cli/args/backend_arg.rs index 3e697171e..ea37325ef 100644 --- a/src/cli/args/backend_arg.rs +++ b/src/cli/args/backend_arg.rs @@ -151,6 +151,13 @@ impl BackendArg { unalias_backend(&self.short).to_string() } + pub fn tool_name(&self) -> String { + let full = self.full(); + let (_backend, tool_name) = full.split_once(':').unwrap_or(("", &full)); + let tool_name = regex!(r#"\[.+\]$"#).replace_all(tool_name, "").to_string(); + tool_name.to_string() + } + /// maps something like cargo:cargo-binstall to cargo-binstall and ubi:cargo-binstall, etc pub fn all_fulls(&self) -> HashSet { let full = self.full(); diff --git a/src/cli/test_tool.rs b/src/cli/test_tool.rs index 00c392c76..d29799ddc 100644 --- a/src/cli/test_tool.rs +++ b/src/cli/test_tool.rs @@ -57,7 +57,7 @@ impl TestTool { } let (cmd, expected) = if let Some(test) = &rt.test { (test.0.to_string(), test.1) - } else if self.include_non_defined { + } else if self.include_non_defined || self.tool.is_some() { (format!("{} --version", tool.short), "__TODO__") } else { continue; diff --git a/src/config/config_file/mise_toml.rs b/src/config/config_file/mise_toml.rs index 044c1e6bb..cbc5d78c4 100644 --- a/src/config/config_file/mise_toml.rs +++ b/src/config/config_file/mise_toml.rs @@ -513,12 +513,17 @@ impl From for MiseTomlTool { ToolRequest::Path { path, os, + options, backend: _backend, source: _source, } => Self { tt: ToolVersionType::Path(path), os, - options: None, + options: if options.is_empty() { + None + } else { + Some(options) + }, }, ToolRequest::Prefix { prefix, @@ -554,22 +559,32 @@ impl From for MiseTomlTool { ToolRequest::Sub { sub, os, + options, orig_version, backend: _backend, source: _source, } => Self { tt: ToolVersionType::Sub { sub, orig_version }, os, - options: None, + options: if options.is_empty() { + None + } else { + Some(options) + }, }, ToolRequest::System { os, + options, backend: _backend, source: _source, } => Self { tt: ToolVersionType::System, os, - options: None, + options: if options.is_empty() { + None + } else { + Some(options) + }, }, } } @@ -858,16 +873,18 @@ impl<'de> de::Deserialize<'de> for MiseTomlToolList { { let mut options: BTreeMap = Default::default(); let mut os: Option> = None; - let mut tt = ToolVersionType::System; + let mut tt: Option = None; while let Some((k, v)) = map.next_entry::()? { match k.as_str() { "version" => { - tt = v.as_str().unwrap().parse().map_err(de::Error::custom)?; + tt = Some(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)?; + tt = Some( + format!("{k}:{}", v.as_str().unwrap()) + .parse() + .map_err(de::Error::custom)?, + ); } "os" => match v { toml::Value::Array(s) => { @@ -887,11 +904,15 @@ impl<'de> de::Deserialize<'de> for MiseTomlToolList { } } } - Ok(MiseTomlToolList(vec![MiseTomlTool { - tt, - os, - options: Some(options), - }])) + if let Some(tt) = tt { + Ok(MiseTomlToolList(vec![MiseTomlTool { + tt, + os, + options: Some(options), + }])) + } else { + Err(de::Error::custom("missing version")) + } } } 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 16270762b..97546efb3 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 @@ -48,6 +48,7 @@ ToolRequestSet { Path { backend: BackendArg("node" -> "core:node"), path: "~/.nodes/18", + options: {}, source: MiseToml( "~/fixtures/.mise.toml", ), diff --git a/src/http.rs b/src/http.rs index 513cddc63..329b5d619 100644 --- a/src/http.rs +++ b/src/http.rs @@ -7,12 +7,12 @@ use eyre::{bail, Report, Result}; use once_cell::sync::Lazy; use reqwest::header::HeaderMap; use reqwest::{ClientBuilder, IntoUrl, Response}; -use tokio::runtime::Runtime; use url::Url; use crate::cli::version; use crate::config::SETTINGS; use crate::file::display_path; +use crate::tokio::RUNTIME; use crate::ui::progress_report::SingleReport; use crate::{env, file}; @@ -84,8 +84,7 @@ impl Client { pub fn head(&self, url: U) -> Result { let url = url.into_url().unwrap(); - let rt = self.runtime()?; - rt.block_on(self.head_async(url)) + RUNTIME.block_on(self.head_async(url)) } pub async fn head_async(&self, url: U) -> Result { @@ -119,8 +118,7 @@ impl Client { pub fn get_text(&self, url: U) -> Result { let mut url = url.into_url().unwrap(); - let rt = self.runtime()?; - let text = rt.block_on(async { + let text = RUNTIME.block_on(async { let resp = self.get(url.clone()).await?; Ok::(resp.text().await?) })?; @@ -140,8 +138,7 @@ impl Client { T: serde::de::DeserializeOwned, { let url = url.into_url().unwrap(); - let rt = self.runtime()?; - let (json, headers) = rt.block_on(async { + let (json, headers) = RUNTIME.block_on(async { let resp = self.get(url).await?; let headers = resp.headers().clone(); Ok::<(T, HeaderMap), eyre::Error>((resp.json().await?, headers)) @@ -165,8 +162,7 @@ impl Client { let url = url.into_url()?; debug!("GET Downloading {} to {}", &url, display_path(path)); - let rt = self.runtime()?; - rt.block_on(async { + RUNTIME.block_on(async { let mut resp = self.get(url).await?; if let Some(length) = resp.content_length() { if let Some(pr) = pr { @@ -186,14 +182,6 @@ impl Client { })?; Ok(()) } - - fn runtime(&self) -> Result { - let rt = tokio::runtime::Builder::new_current_thread() - .enable_time() - .enable_io() - .build()?; - Ok(rt) - } } pub fn error_code(e: &Report) -> Option { diff --git a/src/main.rs b/src/main.rs index eecfbe9aa..a3aa6c547 100644 --- a/src/main.rs +++ b/src/main.rs @@ -60,6 +60,7 @@ mod shorthands; pub(crate) mod task; pub(crate) mod tera; pub(crate) mod timeout; +mod tokio; mod toml; mod toolset; mod ui; diff --git a/src/plugins/core/erlang.rs b/src/plugins/core/erlang.rs index 371ea4ed9..e255416ea 100644 --- a/src/plugins/core/erlang.rs +++ b/src/plugins/core/erlang.rs @@ -51,6 +51,7 @@ impl ErlangPlugin { self.install_kerl()?; cmd!(self.kerl_path(), "update", "releases") .env("KERL_BASE_DIR", self.kerl_base_dir()) + .stdout_to_stderr() .run()?; Ok(()) } @@ -104,6 +105,7 @@ impl Backend for ErlangPlugin { ctx.tv.install_path() ) .env("KERL_BASE_DIR", self.ba.cache_path.join("kerl")) + .stdout_to_stderr() .run()?; } } diff --git a/src/plugins/vfox_plugin.rs b/src/plugins/vfox_plugin.rs index daa877452..ea4ad02ad 100644 --- a/src/plugins/vfox_plugin.rs +++ b/src/plugins/vfox_plugin.rs @@ -2,16 +2,16 @@ use crate::file::{display_path, remove_all}; use crate::git::Git; use crate::plugins::{Plugin, PluginType}; use crate::result::Result; +use crate::tokio::RUNTIME; use crate::ui::multi_progress_report::MultiProgressReport; use crate::ui::progress_report::SingleReport; use crate::{dirs, registry}; use console::style; use contracts::requires; -use eyre::{eyre, Context, Report}; +use eyre::{eyre, Context}; use indexmap::{indexmap, IndexMap}; use std::path::{Path, PathBuf}; use std::sync::{mpsc, Mutex, MutexGuard}; -use tokio::runtime::Runtime; use url::Url; use vfox::Vfox; use xx::regex; @@ -53,7 +53,7 @@ impl VfoxPlugin { pub fn mise_env(&self, opts: &toml::Value) -> Result>> { let (vfox, _) = self.vfox(); let mut out = indexmap!(); - let results = self.runtime()?.block_on(vfox.mise_env(&self.name, opts))?; + let results = RUNTIME.block_on(vfox.mise_env(&self.name, opts))?; for env in results { out.insert(env.key, env.value); } @@ -63,7 +63,7 @@ impl VfoxPlugin { pub fn mise_path(&self, opts: &toml::Value) -> Result>> { let (vfox, _) = self.vfox(); let mut out = vec![]; - let results = self.runtime()?.block_on(vfox.mise_path(&self.name, opts))?; + let results = RUNTIME.block_on(vfox.mise_path(&self.name, opts))?; for env in results { out.push(env); } @@ -79,14 +79,6 @@ impl VfoxPlugin { let rx = vfox.log_subscribe(); (vfox, rx) } - - pub fn runtime(&self) -> eyre::Result { - let rt = tokio::runtime::Builder::new_current_thread() - .enable_time() - .enable_io() - .build()?; - Ok(rt) - } } impl Plugin for VfoxPlugin { diff --git a/src/tokio.rs b/src/tokio.rs new file mode 100644 index 000000000..146d42012 --- /dev/null +++ b/src/tokio.rs @@ -0,0 +1,10 @@ +use once_cell::sync::Lazy; + +pub static RUNTIME: Lazy = Lazy::new(|| { + tokio::runtime::Builder::new_multi_thread() + .worker_threads(4) + .enable_io() + .enable_time() + .build() + .unwrap() +}); diff --git a/src/toolset/mod.rs b/src/toolset/mod.rs index 4db0346e9..6783c094e 100644 --- a/src/toolset/mod.rs +++ b/src/toolset/mod.rs @@ -166,16 +166,39 @@ impl Toolset { .collect() } + /// sets the options on incoming requests to install to whatever is already in the toolset + /// this handles the use-case where you run `mise use ubi:cilium/cilium-cli` (without CLi options) + /// but this tool has options inside mise.toml + fn init_request_options(&self, requests: &mut Vec) { + for tr in requests { + // TODO: tr.options() probably should be Option + // to differentiate between no options and empty options + // without that it might not be possible to unset the options if they are set + if !tr.options().is_empty() { + continue; + } + if let Some(tvl) = self.versions.get(tr.ba()) { + if tvl.requests.len() != 1 { + // TODO: handle this case with multiple versions + continue; + } + let options = tvl.requests[0].options(); + tr.set_options(options); + } + } + } + pub fn install_versions( &mut self, config: &Config, - versions: Vec, + mut versions: Vec, mpr: &MultiProgressReport, opts: &InstallOptions, ) -> Result> { if versions.is_empty() { return Ok(vec![]); } + self.init_request_options(&mut versions); show_python_install_hint(&versions); let leaf_deps = get_leaf_dependencies(&versions)?; if leaf_deps.len() < versions.len() { diff --git a/src/toolset/tool_request.rs b/src/toolset/tool_request.rs index f95c714c6..66d216e74 100644 --- a/src/toolset/tool_request.rs +++ b/src/toolset/tool_request.rs @@ -40,18 +40,21 @@ pub enum ToolRequest { backend: BackendArg, sub: String, 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>, }, } @@ -79,13 +82,15 @@ impl ToolRequest { source, }, Some(("path", p)) => Self::Path { - backend, path: PathBuf::from(p), - source, + options: backend.opts.clone().unwrap_or_default(), os: None, + backend, + source, }, Some((p, v)) if p.starts_with("sub-") => Self::Sub { sub: p.split_once('-').unwrap().1.to_string(), + options: backend.opts.clone().unwrap_or_default(), orig_version: v.to_string(), os: None, backend, @@ -94,15 +99,16 @@ impl ToolRequest { None => { if s == "system" { Self::System { + options: backend.opts.clone().unwrap_or_default(), + os: None, backend, source, - os: None, } } else { Self::Version { version: s, - os: None, options: backend.opts.clone().unwrap_or_default(), + os: None, backend, source, } @@ -170,6 +176,17 @@ impl ToolRequest { | Self::System { os, .. } => os, } } + pub fn set_options(&mut self, options: ToolVersionOptions) -> &mut Self { + match self { + Self::Version { options: o, .. } + | Self::Prefix { options: o, .. } + | Self::Ref { options: o, .. } + | Self::Sub { options: o, .. } + | Self::Path { options: o, .. } + | Self::System { options: o, .. } => *o = options, + } + self + } pub fn with_os(mut self, os: Option>) -> Self { match &mut self { Self::Version { os: o, .. } @@ -204,8 +221,10 @@ impl ToolRequest { match self { Self::Version { options: o, .. } | Self::Prefix { options: o, .. } - | Self::Ref { options: o, .. } => o.clone(), - _ => Default::default(), + | Self::Ref { options: o, .. } + | Self::Sub { options: o, .. } + | Self::Path { options: o, .. } + | Self::System { options: o, .. } => o.clone(), } } diff --git a/src/toolset/tool_version.rs b/src/toolset/tool_version.rs index d11bf7294..b2b61d798 100644 --- a/src/toolset/tool_version.rs +++ b/src/toolset/tool_version.rs @@ -247,6 +247,7 @@ impl ToolVersion { path, source: tr.source().clone(), os: None, + options: tr.options().clone(), }; let version = request.version(); Ok(Self::new(request, version))