Repository: alloy-rs/svm-rs (language: rust)

Issue:
svm-rs cannot be built offline
svm-rs cannot be built offline because the `build.rs` requires internet connection to fetch the json with the versions. It makes it impossible to e.g. package anything that depends on svm-rs in nix, as the builder won't allow the outgoing http connections.

Please provide an alternative mechanism for allowing to pass the list offline. Currently, there's the `_offline` feature, but it will just result in an empty list. I suggest there's an environment variable that points to a pre-downloaded list (that's potentially checked into the version control elsewhere), and svm-builds should use it first (if the variable is set), falling back to fetching it online otherwise.


Discussion / hints:
agree this would be ideal
We just haven't gotten around to add this. I guess an easy solution would be to write a test that generates all files and the build script uses that as fallback

Do you want to take this on?

Fix patch:
diff --git a/crates/svm-builds/build.rs b/crates/svm-builds/build.rs
index 1762163..932ea6c 100644
--- a/crates/svm-builds/build.rs
+++ b/crates/svm-builds/build.rs
@@ -1,5 +1,7 @@
 #![allow(dead_code)]
 
+use std::fs::File;
+
 use semver::Version;
 use svm::Releases;
 
@@ -14,6 +16,15 @@ use svm::Releases;
 /// - "windows-amd64"
 pub const SVM_TARGET_PLATFORM: &str = "SVM_TARGET_PLATFORM";
 
+/// The path to the releases JSON file, that was pre-fetched manually. If this
+/// variable is defined, svm-builds won't attempt to deduce anything about the
+/// platfrom or perform network calls, and will instead treat the file as the
+/// source of truth.
+///
+/// Must follow the same format as the upstream `list.json`, e.g.
+/// [this one](https://raw.githubusercontent.com/nikitastupin/solc/af2fce8988e41753ab4f726e0273ea8244de5dba/linux/aarch64/list.json)
+pub const SVM_RELEASES_LIST_JSON: &str = "SVM_RELEASES_LIST_JSON";
+
 /// Returns the platform to generate the constants for
 ///
 /// if the `SVM_TARGET_PLATFORM` var is set, this will return the matching [svm::Platform],
@@ -110,7 +121,24 @@ pub const TARGET_PLATFORM: &str = "{}";
 
 fn generate() {
     let platform = get_platform();
-    let releases = svm::blocking_all_releases(platform).expect("Failed to fetch releases");
+
+    let releases: Releases = if let Ok(file_path) = std::env::var(SVM_RELEASES_LIST_JSON) {
+        let file = File::open(file_path).unwrap_or_else(|_| {
+            panic!(
+                "{:?} defined, but cannot read the file referenced",
+                SVM_RELEASES_LIST_JSON
+            )
+        });
+
+        serde_json::from_reader(file).unwrap_or_else(|_| {
+            panic!(
+                "Failed to parse the JSON from {:?} file",
+                SVM_RELEASES_LIST_JSON
+            )
+        })
+    } else {
+        svm::blocking_all_releases(platform).expect("Failed to fetch releases")
+    };
 
     let mut writer = build_const::ConstWriter::for_build("builds")
         .unwrap()


Test patch: