From 50a0543a00f5d87da056456ae9fce3b45326d4df Mon Sep 17 00:00:00 2001 From: grandizzy Date: Wed, 19 Nov 2025 07:08:09 +0200 Subject: [PATCH] feat: support prereleases --- crates/svm-rs/src/install.rs | 3 +-- crates/svm-rs/src/releases.rs | 43 ++++++++++++++++++++++++++++------- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/crates/svm-rs/src/install.rs b/crates/svm-rs/src/install.rs index 4ec810d..90362eb 100644 --- a/crates/svm-rs/src/install.rs +++ b/crates/svm-rs/src/install.rs @@ -77,8 +77,7 @@ pub async fn install(version: &Version) -> Result { let artifacts = all_releases(platform::platform()).await?; let artifact = artifacts - .releases - .get(version) + .get_artifact(version) .ok_or_else(|| SvmError::UnknownVersion(version.clone()))?; let download_url = artifact_url(platform::platform(), version, artifact.to_string().as_str())?; diff --git a/crates/svm-rs/src/releases.rs b/crates/svm-rs/src/releases.rs index 1f8e22f..329f4a4 100644 --- a/crates/svm-rs/src/releases.rs +++ b/crates/svm-rs/src/releases.rs @@ -76,18 +76,43 @@ pub struct Releases { impl Releases { /// Get the checksum of a solc version's binary if it exists. + /// Checks for exact version match or for prerelease. pub fn get_checksum(&self, v: &Version) -> Option> { - for build in self.builds.iter() { - if build.version.eq(v) { - return Some(build.sha256.clone()); - } - } - None + let matches = |build_info: &BuildInfo| { + let matched_release = build_info.version == *v; + + let matched_prelease = !v.pre.is_empty() + && build_info.version == Version::new(v.major, v.minor, v.patch) + && build_info.prerelease.as_deref() == Some(v.pre.as_str()); + + matched_release || matched_prelease + }; + + self.builds + .iter() + .find(|build_info| matches(build_info)) + .map(|build_info| build_info.sha256.clone()) } - /// Returns the artifact of the version if any + /// Returns the artifact of the version if any, by looking it up in releases or in builds (if + /// a prerelease). pub fn get_artifact(&self, version: &Version) -> Option<&String> { - self.releases.get(version) + // Check version artifact in releases. + if let Some(artifact) = self.releases.get(version) { + return Some(artifact); + } + + // If we didn't find any artifact under releases, look up builds for prerelease. + if !version.pre.is_empty() + && let Some(build_info) = self.builds.iter().find(|b| { + b.version == Version::new(version.major, version.minor, version.patch) + && b.prerelease == Some(version.pre.to_string()) + }) + { + return build_info.path.as_ref(); + } + + None } /// Returns a sorted list of all versions @@ -104,6 +129,8 @@ pub struct BuildInfo { pub version: Version, #[serde(with = "hex_string")] pub sha256: Vec, + pub path: Option, + pub prerelease: Option, } /// Helper serde module to serialize and deserialize bytes as hex.