mirror of
https://github.com/pezkuwichain/revive-differential-tests.git
synced 2026-06-14 00:31:05 +00:00
the solc download per target helper
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
//! Helper for caching the solc binaries.
|
||||
|
||||
use std::{
|
||||
cell::OnceCell,
|
||||
collections::HashSet,
|
||||
fs::{File, create_dir_all},
|
||||
io::Write,
|
||||
path::{Path, PathBuf},
|
||||
sync::Mutex,
|
||||
};
|
||||
|
||||
use crate::download::GHDownloader;
|
||||
|
||||
pub const SOLC_CACHE_DIRECTORY: &str = "solc";
|
||||
pub const SOLC_CACHER: OnceCell<Mutex<SolcCacher>> = OnceCell::new();
|
||||
|
||||
pub fn get_or_download(
|
||||
working_directory: &Path,
|
||||
downloader: &GHDownloader,
|
||||
) -> anyhow::Result<PathBuf> {
|
||||
SOLC_CACHER
|
||||
.get_or_init(|| {
|
||||
Mutex::new(SolcCacher::new(
|
||||
working_directory.join(SOLC_CACHE_DIRECTORY),
|
||||
))
|
||||
})
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get_or_download(downloader)
|
||||
}
|
||||
|
||||
pub struct SolcCacher {
|
||||
cache_directory: PathBuf,
|
||||
cached_binaries: HashSet<PathBuf>,
|
||||
}
|
||||
|
||||
impl SolcCacher {
|
||||
fn new(cache_directory: PathBuf) -> Self {
|
||||
Self {
|
||||
cache_directory,
|
||||
cached_binaries: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_or_download(&mut self, downloader: &GHDownloader) -> anyhow::Result<PathBuf> {
|
||||
let directory = self.cache_directory.join(downloader.version.to_string());
|
||||
let file_path = directory.join(downloader.target);
|
||||
|
||||
if self.cached_binaries.contains(&file_path) {
|
||||
return Ok(file_path);
|
||||
}
|
||||
|
||||
if file_path.exists() {
|
||||
self.cached_binaries.insert(file_path.clone());
|
||||
return Ok(file_path);
|
||||
}
|
||||
|
||||
create_dir_all(directory)?;
|
||||
|
||||
let buf = downloader.download()?;
|
||||
File::create_new(&file_path)
|
||||
.expect("should not exist because of above early return")
|
||||
.write_all(&buf)?;
|
||||
|
||||
Ok(file_path)
|
||||
}
|
||||
}
|
||||
@@ -35,9 +35,9 @@ impl List {
|
||||
|
||||
/// Download solc binaries from GitHub releases (IPFS links aren't reliable).
|
||||
pub struct GHDownloader {
|
||||
version: Version,
|
||||
target: &'static str,
|
||||
list: &'static str,
|
||||
pub version: Version,
|
||||
pub target: &'static str,
|
||||
pub list: &'static str,
|
||||
}
|
||||
|
||||
impl GHDownloader {
|
||||
@@ -48,36 +48,33 @@ impl GHDownloader {
|
||||
pub const WINDOWS_NAME: &str = "solc-windows.exe";
|
||||
pub const WASM_NAME: &str = "soljson.js";
|
||||
|
||||
pub fn linux(version: Version) -> Self {
|
||||
fn new(version: Version, target: &'static str, list: &'static str) -> Self {
|
||||
Self {
|
||||
version,
|
||||
target: Self::LINUX_NAME,
|
||||
list: List::LINUX_URL,
|
||||
target,
|
||||
list,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn linux(version: Version) -> Self {
|
||||
Self::new(version, Self::LINUX_NAME, List::LINUX_URL)
|
||||
}
|
||||
|
||||
pub fn macosx(version: Version) -> Self {
|
||||
Self {
|
||||
version,
|
||||
target: Self::MACOSX_NAME,
|
||||
list: List::MACOSX_URL,
|
||||
}
|
||||
Self::new(version, Self::MACOSX_NAME, List::MACOSX_URL)
|
||||
}
|
||||
|
||||
pub fn windows(version: Version) -> Self {
|
||||
Self {
|
||||
version,
|
||||
target: Self::WINDOWS_NAME,
|
||||
list: List::WINDOWS_URL,
|
||||
}
|
||||
Self::new(version, Self::WINDOWS_NAME, List::WINDOWS_URL)
|
||||
}
|
||||
|
||||
pub fn wasm(version: Version) -> Self {
|
||||
Self {
|
||||
version,
|
||||
target: Self::WASM_NAME,
|
||||
list: List::WASM_URL,
|
||||
}
|
||||
Self::new(version, Self::WASM_NAME, List::WASM_URL)
|
||||
}
|
||||
|
||||
/// Returns the download link.
|
||||
pub fn url(&self) -> String {
|
||||
format!("{}/v{}/{}", Self::BASE_URL, &self.version, &self.target)
|
||||
}
|
||||
|
||||
/// Download the solc binary.
|
||||
@@ -92,8 +89,7 @@ impl GHDownloader {
|
||||
.ok_or_else(|| anyhow::anyhow!("solc v{} not found builds", self.version))
|
||||
.map(|b| b.sha256.strip_prefix("0x").unwrap_or(&b.sha256).to_string())?;
|
||||
|
||||
let url = format!("{}/v{}/{}", Self::BASE_URL, self.version, self.target);
|
||||
let file = reqwest::blocking::get(&url)?.bytes()?.to_vec();
|
||||
let file = reqwest::blocking::get(self.url())?.bytes()?.to_vec();
|
||||
|
||||
if hex::encode(Sha256::digest(&file)) != expected_digest {
|
||||
anyhow::bail!("sha256 mismatch for solc version {}", self.version);
|
||||
|
||||
@@ -1,8 +1,39 @@
|
||||
//! This crates provides serializable Rust type definitions for the [solc binary lists][0].
|
||||
//! The `download` feature enables helpers to download and cache solc binaries.
|
||||
//! This crates provides serializable Rust type definitions for the [solc binary lists][0]
|
||||
//! and download helpers.
|
||||
//!
|
||||
//! [0]: https://binaries.soliditylang.org
|
||||
|
||||
#[cfg(feature = "download")]
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use cache::get_or_download;
|
||||
use download::GHDownloader;
|
||||
use semver::Version;
|
||||
|
||||
pub mod cache;
|
||||
pub mod download;
|
||||
pub mod list;
|
||||
|
||||
/// Downloads the solc binary for Wasm is `wasm` is set, otherwise for
|
||||
/// the target platform.
|
||||
///
|
||||
/// Subsequent calls for the same version will use a cached artifact
|
||||
/// and not download it again.
|
||||
pub fn download_solc(
|
||||
working_directory: &Path,
|
||||
version: Version,
|
||||
wasm: bool,
|
||||
) -> anyhow::Result<PathBuf> {
|
||||
let downloader = if wasm {
|
||||
GHDownloader::wasm(version)
|
||||
} else if cfg!(target_os = "linux") {
|
||||
GHDownloader::linux(version)
|
||||
} else if cfg!(target_os = "macos") {
|
||||
GHDownloader::macosx(version)
|
||||
} else if cfg!(target_os = "windows") {
|
||||
GHDownloader::windows(version)
|
||||
} else {
|
||||
unimplemented!()
|
||||
};
|
||||
|
||||
get_or_download(working_directory, &downloader)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user