diff --git a/build.rs b/build.rs index 2bea5bbd87..940aa50950 100644 --- a/build.rs +++ b/build.rs @@ -1,6 +1,5 @@ use heck::ToUpperCamelCase; use indexmap::IndexMap; -use std::collections::HashSet; use std::path::{Path, PathBuf}; use std::{env, fs}; @@ -29,7 +28,6 @@ fn codegen_registry() { .unwrap(); let tools = registry.get("tools").unwrap().as_table().unwrap(); - let mut trusted_ids = HashSet::new(); for (short, info) in tools { let info = info.as_table().unwrap(); let aliases = info @@ -48,20 +46,41 @@ fn codegen_registry() { t[1].as_str().unwrap().to_string(), ) }); - let backends = info.get("backends").unwrap().as_array().unwrap(); - let mut fulls = vec![]; - for backend in backends { + let mut backends = vec![]; + for backend in info.get("backends").unwrap().as_array().unwrap() { match backend { toml::Value::String(backend) => { - fulls.push(backend.to_string()); + backends.push(format!( + r##"RegistryBackend{{ + full: r#"{backend}"#, + platforms: &[], + }}"##, + backend = backend + )); } toml::Value::Table(backend) => { - fulls.push(backend.get("full").unwrap().as_str().unwrap().to_string()); - if let Some(trust) = backend.get("trust") { - if trust.as_bool().unwrap() { - trusted_ids.insert(short); - } - } + let full = backend.get("full").unwrap().as_str().unwrap(); + let platforms = backend + .get("platforms") + .map(|p| { + p.as_array() + .unwrap() + .iter() + .map(|p| p.as_str().unwrap().to_string()) + .collect::>() + }) + .unwrap_or_default(); + backends.push(format!( + r##"RegistryBackend{{ + full: r#"{full}"#, + platforms: &[{platforms}], + }}"##, + platforms = platforms + .into_iter() + .map(|p| format!("\"{p}\"")) + .collect::>() + .join(", ") + )); } _ => panic!("Unknown backend type"), } @@ -105,11 +124,11 @@ fn codegen_registry() { }) .unwrap_or_default(); let rt = format!( - r#"RegistryTool{{short: "{short}", description: {description}, backends: vec!["{backends}"], aliases: &[{aliases}], test: &{test}, os: &[{os}], depends: &[{depends}], idiomatic_files: &[{idiomatic_files}]}}"#, + r#"RegistryTool{{short: "{short}", description: {description}, backends: &[{backends}], aliases: &[{aliases}], test: &{test}, os: &[{os}], depends: &[{depends}], idiomatic_files: &[{idiomatic_files}]}}"#, description = description .map(|d| format!("Some(r###\"{}\"###)", d)) .unwrap_or("None".to_string()), - backends = fulls.join("\", \""), + backends = backends.into_iter().collect::>().join(", "), aliases = aliases .iter() .map(|a| format!("\"{a}\"")) diff --git a/docs/registry.md b/docs/registry.md index afe442cf8f..e403200df6 100644 --- a/docs/registry.md +++ b/docs/registry.md @@ -74,7 +74,7 @@ You can also specify the full name for a tool using `mise use aqua:1password/cli | balena | [ubi:balena-io/balena-cli](https://github.com/balena-io/balena-cli) [asdf:boatkit-io/asdf-balena-cli](https://github.com/boatkit-io/asdf-balena-cli) | | bashbot | [aqua:mathew-fleisch/bashbot](https://github.com/mathew-fleisch/bashbot) [asdf:mathew-fleisch/asdf-bashbot](https://github.com/mathew-fleisch/asdf-bashbot) | | bashly | [asdf:pcrockett/asdf-bashly](https://github.com/pcrockett/asdf-bashly) | -| bat | [ubi:sharkdp/bat](https://github.com/sharkdp/bat) [asdf:https://gitlab.com/wt0f/asdf-bat](https://gitlab.com/wt0f/asdf-bat) | +| bat | [ubi:sharkdp/bat](https://github.com/sharkdp/bat) [cargo:bat](https://crates.io/crates/bat) [asdf:https://gitlab.com/wt0f/asdf-bat](https://gitlab.com/wt0f/asdf-bat) | | bat-extras | [asdf:vhdirk/asdf-bat-extras](https://github.com/vhdirk/asdf-bat-extras) | | bats | [aqua:bats-core/bats-core](https://github.com/bats-core/bats-core) [asdf:timgluz/asdf-bats](https://github.com/timgluz/asdf-bats) | | bazel | [ubi:bazelbuild/bazel](https://github.com/bazelbuild/bazel) [asdf:rajatvig/asdf-bazel](https://github.com/rajatvig/asdf-bazel) | diff --git a/registry.toml b/registry.toml index bc0f39233d..cef7616738 100644 --- a/registry.toml +++ b/registry.toml @@ -159,7 +159,15 @@ bashbot.backends = [ ] bashly.backends = ["asdf:pcrockett/asdf-bashly"] # aqua is available but uses cargo -bat.backends = ["ubi:sharkdp/bat", "asdf:https://gitlab.com/wt0f/asdf-bat"] +bat.backends = [ + {full = "ubi:sharkdp/bat", platforms = [ + "linux", + "macos", + "windows" + ]}, + "cargo:bat", + "asdf:https://gitlab.com/wt0f/asdf-bat" +] bat.test = ["bat --version", "bat {{version}}"] bat-extras.backends = ["asdf:vhdirk/asdf-bat-extras"] bats.backends = ["aqua:bats-core/bats-core", "asdf:timgluz/asdf-bats"] diff --git a/src/backend/aqua.rs b/src/backend/aqua.rs index 5430a15a10..68c9952b4e 100644 --- a/src/backend/aqua.rs +++ b/src/backend/aqua.rs @@ -158,7 +158,7 @@ impl AquaBackend { if !id.contains("/") { id = REGISTRY .get(id) - .and_then(|t| t.backends.iter().find_map(|s| s.strip_prefix("aqua:"))) + .and_then(|t| t.backends.iter().find_map(|s| s.full.strip_prefix("aqua:"))) .unwrap_or_else(|| { warn!("invalid aqua tool: {}", id); id diff --git a/src/plugins/vfox_plugin.rs b/src/plugins/vfox_plugin.rs index 27692486bd..acf81b1ba4 100644 --- a/src/plugins/vfox_plugin.rs +++ b/src/plugins/vfox_plugin.rs @@ -227,8 +227,8 @@ fn vfox_to_url(name: &str) -> eyre::Result { let name = name.strip_prefix("vfox:").unwrap_or(name); if let Some(rt) = registry::REGISTRY.get(name.trim_start_matches("vfox-")) { // bun -> version-fox/vfox-bun - if let Some(full) = rt.backends.iter().find(|f| f.starts_with("vfox:")) { - return vfox_to_url(full.split_once(':').unwrap().1); + if let Some((_, tool_name)) = rt.backends.iter().find_map(|f| f.full.split_once("vfox:")) { + return vfox_to_url(tool_name); } } let res = if let Some(caps) = regex!(r#"^([^/]+)/([^/]+)$"#).captures(name) { diff --git a/src/registry.rs b/src/registry.rs index 88ab7c87d0..9e60517f5a 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -3,7 +3,7 @@ use crate::cli::args::BackendArg; use crate::config::SETTINGS; use once_cell::sync::Lazy; use std::collections::{BTreeMap, HashMap, HashSet}; -use std::env::consts::OS; +use std::env::consts::{ARCH, OS}; use std::fmt::Display; use std::iter::Iterator; use strum::IntoEnumIterator; @@ -17,7 +17,7 @@ pub static REGISTRY: Lazy> = pub struct RegistryTool { pub short: &'static str, pub description: Option<&'static str>, - pub backends: Vec<&'static str>, + pub backends: &'static [RegistryBackend], #[allow(unused)] pub aliases: &'static [&'static str], pub test: &'static Option<(&'static str, &'static str)>, @@ -26,6 +26,12 @@ pub struct RegistryTool { pub idiomatic_files: &'static [&'static str], } +#[derive(Debug, Clone)] +pub struct RegistryBackend { + pub full: &'static str, + pub platforms: &'static [&'static str], +} + impl RegistryTool { pub fn backends(&self) -> Vec<&'static str> { static BACKEND_TYPES: Lazy> = Lazy::new(|| { @@ -42,14 +48,21 @@ impl RegistryTool { } backend_types }); + let platform = format!("{OS}-{ARCH}"); self.backends .iter() + .filter(|rb| { + rb.platforms.is_empty() + || rb.platforms.contains(&OS) + || rb.platforms.contains(&ARCH) + || rb.platforms.contains(&&*platform) + }) + .map(|rb| rb.full) .filter(|full| { full.split(':') .next() .is_some_and(|b| BACKEND_TYPES.contains(b)) }) - .copied() .collect() }