From 29a6c995226d3ca91c2d479412f9b4026f486dc6 Mon Sep 17 00:00:00 2001 From: Risu <79110363+risu729@users.noreply.github.com> Date: Mon, 30 Jun 2025 15:27:59 +1000 Subject: [PATCH 1/4] fix(aqua): try input version before prepending v --- e2e/backend/test_aqua | 1 + src/backend/aqua.rs | 29 ++++++++++++----------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/e2e/backend/test_aqua b/e2e/backend/test_aqua index 60c555a553..f3c520fd25 100644 --- a/e2e/backend/test_aqua +++ b/e2e/backend/test_aqua @@ -11,6 +11,7 @@ test age@1.2.0 "age --version" "v1.2.0" test aqua:helm/helm@3.16.3 "helm version" "v3.16.3" test aqua:crate-ci/typos@1.27.3 "typos --version" "typos-cli 1.27.3" test aqua:biomejs/biome@2.0.0 "biome --version" "Version: 2.0.0" +test aqua:biomejs/biome@@biomejs/biome@2.0.0 "biome --version" "Version: 2.0.0" assert_contains "MISE_USE_VERSIONS_HOST=0 mise ls-remote aqua:sharkdp/hyperfine" "1.9.0 1.10.0" diff --git a/src/backend/aqua.rs b/src/backend/aqua.rs index b89dfccc0b..05eea513dc 100644 --- a/src/backend/aqua.rs +++ b/src/backend/aqua.rs @@ -77,25 +77,18 @@ impl Backend for AquaBackend { ctx: &InstallContext, mut tv: ToolVersion, ) -> Result { - let mut v; - let pkg; - match self + let tag = self .get_version_tags() .await? .iter() .find(|(version, _)| version == &tv.version) + .map(|(_, tag)| tag); + let mut v = tag.unwrap_or(&tv.version).to_string(); + let pkg = AQUA_REGISTRY.package_with_version(&self.id, &v).await?; + if let Some(prefix) = &pkg.version_prefix + && !v.starts_with(prefix) { - Some((_, tag)) => { - v = tag.clone(); - pkg = AQUA_REGISTRY.package_with_version(&self.id, &v).await?; - } - None => { - v = format!("v{}", tv.version); - pkg = AQUA_REGISTRY.package_with_version(&self.id, &v).await?; - if let Some(prefix) = &pkg.version_prefix { - v = format!("{prefix}{v}"); - } - } + v = format!("{prefix}{v}"); } if pkg.no_asset { bail!("no asset released"); @@ -107,10 +100,12 @@ impl Backend for AquaBackend { let url = match self.fetch_url(&pkg, &v).await { Ok(url) => url, Err(err) => { + if tag.is_some() || tv.version.starts_with("v") { + return Err(err); + } + v = format!("v{}", tv.version); if let Some(prefix) = &pkg.version_prefix { - v = format!("{}{}", prefix, tv.version); - } else { - v = tv.version.to_string(); + v = format!("{prefix}{v}"); } self.fetch_url(&pkg, &v) .await From 0410ad2a37c566c8ee1d57d07e4cc1cbe0c17ae4 Mon Sep 17 00:00:00 2001 From: Risu <79110363+risu729@users.noreply.github.com> Date: Mon, 30 Jun 2025 15:42:44 +1000 Subject: [PATCH 2/4] refactor: remove new syntax --- src/backend/aqua.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/aqua.rs b/src/backend/aqua.rs index 05eea513dc..c2e5763656 100644 --- a/src/backend/aqua.rs +++ b/src/backend/aqua.rs @@ -85,10 +85,10 @@ impl Backend for AquaBackend { .map(|(_, tag)| tag); let mut v = tag.unwrap_or(&tv.version).to_string(); let pkg = AQUA_REGISTRY.package_with_version(&self.id, &v).await?; - if let Some(prefix) = &pkg.version_prefix - && !v.starts_with(prefix) - { - v = format!("{prefix}{v}"); + if let Some(prefix) = &pkg.version_prefix { + if !v.starts_with(prefix) { + v = format!("{prefix}{v}"); + } } if pkg.no_asset { bail!("no asset released"); From 67590edce5ac1065304182fad67af7604f874256 Mon Sep 17 00:00:00 2001 From: Risu <79110363+risu729@users.noreply.github.com> Date: Mon, 30 Jun 2025 22:02:31 +1000 Subject: [PATCH 3/4] fix(aqua): use first matching version_override --- src/aqua/aqua_registry.rs | 29 +++++++++++++++++------------ src/backend/aqua.rs | 36 ++++++++++++++++++++++-------------- 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/src/aqua/aqua_registry.rs b/src/aqua/aqua_registry.rs index 3093b42225..9682c5b340 100644 --- a/src/aqua/aqua_registry.rs +++ b/src/aqua/aqua_registry.rs @@ -225,8 +225,8 @@ impl AquaRegistry { Ok(pkg) } - pub async fn package_with_version(&self, id: &str, v: &str) -> Result { - Ok(self.package(id).await?.with_version(v)) + pub async fn package_with_version(&self, id: &str, versions: &[&str]) -> Result { + Ok(self.package(id).await?.with_version(versions)) } async fn fetch_package_yaml( @@ -281,8 +281,8 @@ fn fetch_latest_repo(repo: &Git) -> Result<()> { } impl AquaPackage { - pub fn with_version(mut self, v: &str) -> AquaPackage { - self = apply_override(self.clone(), self.version_override(v)); + pub fn with_version(mut self, versions: &[&str]) -> AquaPackage { + self = apply_override(self.clone(), self.version_override(versions)); if let Some(avo) = self.overrides.clone().into_iter().find(|o| { if let (Some(goos), Some(goarch)) = (&o.goos, &o.goarch) { goos == aqua::os() && goarch == aqua::arch() @@ -299,9 +299,12 @@ impl AquaPackage { self } - fn version_override(&self, v: &str) -> &AquaPackage { - let expr = self.expr_parser(v); - let ctx = self.expr_ctx(v); + // all versions must refer to the same logical version. e.g. ["v1.2.3", "1.2.3"] + fn version_override(&self, versions: &[&str]) -> &AquaPackage { + let expressions = versions + .iter() + .map(|v| (self.expr_parser(v), self.expr_ctx(v))) + .collect_vec(); vec![self] .into_iter() .chain(self.version_overrides.iter()) @@ -309,11 +312,13 @@ impl AquaPackage { if vo.version_constraint.is_empty() { true } else { - expr.eval(&vo.version_constraint, &ctx) - .map_err(|e| debug!("error parsing {}: {e}", vo.version_constraint)) - .unwrap_or(false.into()) - .as_bool() - .unwrap() + expressions.iter().any(|(expr, ctx)| { + expr.eval(&vo.version_constraint, &ctx) + .map_err(|e| debug!("error parsing {}: {e}", vo.version_constraint)) + .unwrap_or(false.into()) + .as_bool() + .unwrap() + }) } }) .unwrap_or(self) diff --git a/src/backend/aqua.rs b/src/backend/aqua.rs index c2e5763656..4c9d8187a6 100644 --- a/src/backend/aqua.rs +++ b/src/backend/aqua.rs @@ -62,7 +62,7 @@ impl Backend for AquaBackend { let mut versions = Vec::new(); for (v, tag) in version_tags.iter() { let pkg = AQUA_REGISTRY - .package_with_version(&self.id, tag) + .package_with_version(&self.id, &[tag]) .await .unwrap_or_default(); if !pkg.no_asset && pkg.error_message.is_none() { @@ -83,11 +83,20 @@ impl Backend for AquaBackend { .iter() .find(|(version, _)| version == &tv.version) .map(|(_, tag)| tag); - let mut v = tag.unwrap_or(&tv.version).to_string(); - let pkg = AQUA_REGISTRY.package_with_version(&self.id, &v).await?; + let mut v = tag.cloned().unwrap_or_else(|| tv.version.clone()); + let mut v_prefixed = + (!tag.is_some() && !tv.version.starts_with('v')).then(|| format!("v{v}")); + let versions = match &v_prefixed { + Some(v_prefixed) => vec![v.as_str(), v_prefixed.as_str()], + None => vec![v.as_str()], + }; + let pkg = AQUA_REGISTRY + .package_with_version(&self.id, &versions) + .await?; if let Some(prefix) = &pkg.version_prefix { if !v.starts_with(prefix) { v = format!("{prefix}{v}"); + v_prefixed = v_prefixed.map(|v| format!("{prefix}{v}")); } } if pkg.no_asset { @@ -97,20 +106,18 @@ impl Backend for AquaBackend { bail!(pkg.error_message.unwrap()); } validate(&pkg)?; - let url = match self.fetch_url(&pkg, &v).await { + // try v-prefixed version first because most aqua packages use v-prefixed versions + let url = match self + .fetch_url(&pkg, v_prefixed.as_ref().unwrap_or(&v)) + .await + { Ok(url) => url, - Err(err) => { - if tag.is_some() || tv.version.starts_with("v") { - return Err(err); - } - v = format!("v{}", tv.version); - if let Some(prefix) = &pkg.version_prefix { - v = format!("{prefix}{v}"); - } + Err(err) if v_prefixed.is_some() => { self.fetch_url(&pkg, &v) .await .map_err(|e| err.wrap_err(e))? } + Err(err) => return Err(err), }; let filename = url.split('/').next_back().unwrap(); self.download(ctx, &tv, &url, filename).await?; @@ -137,8 +144,9 @@ impl Backend for AquaBackend { let install_path = tv.install_path(); let paths = cache .get_or_try_init_async(async || { + // TODO: align this logic with the one in `install_version_` let pkg = AQUA_REGISTRY - .package_with_version(&self.id, &tv.version) + .package_with_version(&self.id, &[&tv.version]) .await?; let srcs = self.srcs(&pkg, tv)?; @@ -227,7 +235,7 @@ impl AquaBackend { continue; } } - let pkg = pkg.clone().with_version(version); + let pkg = pkg.clone().with_version(&[version]); if let Some(prefix) = &pkg.version_prefix { if let Some(_v) = version.strip_prefix(prefix) { version = _v; From 21452ddd17e01268f6cb500549460517d61667d4 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 12:15:56 +0000 Subject: [PATCH 4/4] [autofix.ci] apply automated fixes --- src/aqua/aqua_registry.rs | 2 +- src/backend/aqua.rs | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/aqua/aqua_registry.rs b/src/aqua/aqua_registry.rs index 9682c5b340..b6ae22d9ef 100644 --- a/src/aqua/aqua_registry.rs +++ b/src/aqua/aqua_registry.rs @@ -313,7 +313,7 @@ impl AquaPackage { true } else { expressions.iter().any(|(expr, ctx)| { - expr.eval(&vo.version_constraint, &ctx) + expr.eval(&vo.version_constraint, ctx) .map_err(|e| debug!("error parsing {}: {e}", vo.version_constraint)) .unwrap_or(false.into()) .as_bool() diff --git a/src/backend/aqua.rs b/src/backend/aqua.rs index 4c9d8187a6..918bee8ef5 100644 --- a/src/backend/aqua.rs +++ b/src/backend/aqua.rs @@ -85,7 +85,7 @@ impl Backend for AquaBackend { .map(|(_, tag)| tag); let mut v = tag.cloned().unwrap_or_else(|| tv.version.clone()); let mut v_prefixed = - (!tag.is_some() && !tv.version.starts_with('v')).then(|| format!("v{v}")); + (tag.is_none() && !tv.version.starts_with('v')).then(|| format!("v{v}")); let versions = match &v_prefixed { Some(v_prefixed) => vec![v.as_str(), v_prefixed.as_str()], None => vec![v.as_str()], @@ -112,11 +112,10 @@ impl Backend for AquaBackend { .await { Ok(url) => url, - Err(err) if v_prefixed.is_some() => { - self.fetch_url(&pkg, &v) - .await - .map_err(|e| err.wrap_err(e))? - } + Err(err) if v_prefixed.is_some() => self + .fetch_url(&pkg, &v) + .await + .map_err(|e| err.wrap_err(e))?, Err(err) => return Err(err), }; let filename = url.split('/').next_back().unwrap();