mirror of
https://github.com/pezkuwichain/revive-differential-tests.git
synced 2026-06-17 01:51:05 +00:00
check the supported solc version
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
This commit is contained in:
Generated
+1
-1
@@ -2937,7 +2937,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"hex",
|
"hex",
|
||||||
"once_cell",
|
"log",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"semver 1.0.26",
|
"semver 1.0.26",
|
||||||
"serde",
|
"serde",
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ use revive_dt_format::{
|
|||||||
use revive_dt_node::Node;
|
use revive_dt_node::Node;
|
||||||
use revive_dt_solc_binaries::download_solc;
|
use revive_dt_solc_binaries::download_solc;
|
||||||
use revive_solc_json_interface::SolcStandardJsonOutput;
|
use revive_solc_json_interface::SolcStandardJsonOutput;
|
||||||
use semver::Version;
|
|
||||||
|
|
||||||
use crate::Platform;
|
use crate::Platform;
|
||||||
|
|
||||||
@@ -41,19 +40,22 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_contracts(&mut self, mode: &SolcMode, metadata: &Metadata) -> anyhow::Result<()> {
|
pub fn build_contracts(&mut self, mode: &SolcMode, metadata: &Metadata) -> anyhow::Result<()> {
|
||||||
|
let Some(version) = mode.last_patch_version(&self.config.solc) else {
|
||||||
|
anyhow::bail!("unsupported solc version: {:?}", mode.solc_version);
|
||||||
|
};
|
||||||
|
|
||||||
let sources = metadata.contract_sources()?;
|
let sources = metadata.contract_sources()?;
|
||||||
let base_path = metadata.directory()?.display().to_string();
|
let base_path = metadata.directory()?.display().to_string();
|
||||||
|
|
||||||
let mut compiler = Compiler::<T::Compiler>::new().base_path(base_path.clone());
|
let mut compiler = Compiler::<T::Compiler>::new().base_path(base_path.clone());
|
||||||
for (file, _contract) in sources.values() {
|
for (file, _contract) in sources.values() {
|
||||||
compiler = compiler.with_source(file)?;
|
compiler = compiler.with_source(file)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let version = Version::new(0, 8, 29);
|
|
||||||
let solc_path = download_solc(self.config.directory(), version, self.config.wasm)?;
|
let solc_path = download_solc(self.config.directory(), version, self.config.wasm)?;
|
||||||
let output = compiler
|
let output = compiler
|
||||||
.solc_optimizer(mode.solc_optimize())
|
.solc_optimizer(mode.solc_optimize())
|
||||||
.try_build(solc_path)?;
|
.try_build(solc_path)?;
|
||||||
|
|
||||||
self.contracts.insert(output.input, output.output);
|
self.contracts.insert(output.input, output.output);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use semver::Version;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::de::Deserializer;
|
use serde::de::Deserializer;
|
||||||
|
|
||||||
@@ -57,6 +58,26 @@ impl SolcMode {
|
|||||||
pub fn solc_optimize(&self) -> bool {
|
pub fn solc_optimize(&self) -> bool {
|
||||||
self.solc_optimize.unwrap_or(true)
|
self.solc_optimize.unwrap_or(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculate the latest matching solc patch version. Returns:
|
||||||
|
/// - `latest_supported` if no version request was specified.
|
||||||
|
/// - A matching version with the same minor version as `latest_supported`, if any.
|
||||||
|
/// - `None` if no minor version of the `latest_supported` version matches.
|
||||||
|
pub fn last_patch_version(&self, latest_supported: &Version) -> Option<Version> {
|
||||||
|
let Some(version_req) = self.solc_version.as_ref() else {
|
||||||
|
return Some(latest_supported.to_owned());
|
||||||
|
};
|
||||||
|
|
||||||
|
// lgtm
|
||||||
|
for patch in (0..latest_supported.patch + 1).rev() {
|
||||||
|
let version = Version::new(0, latest_supported.minor, patch);
|
||||||
|
if version_req.matches(&version) {
|
||||||
|
return Some(version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for Mode {
|
impl<'de> Deserialize<'de> for Mode {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ rust-version.workspace = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
hex = { workspace = true }
|
hex = { workspace = true }
|
||||||
once_cell = { workspace = true }
|
log = { workspace = true }
|
||||||
reqwest = { workspace = true }
|
reqwest = { workspace = true }
|
||||||
semver = { workspace = true }
|
semver = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
|
|||||||
@@ -1,84 +1,70 @@
|
|||||||
//! Helper for caching the solc binaries.
|
//! Helper for caching the solc binaries.
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
cell::OnceCell,
|
|
||||||
collections::HashSet,
|
collections::HashSet,
|
||||||
fs::{File, create_dir_all},
|
fs::{File, create_dir_all},
|
||||||
io::Write,
|
io::{BufWriter, Write},
|
||||||
os::unix::fs::PermissionsExt,
|
os::unix::fs::PermissionsExt,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::Mutex,
|
sync::{LazyLock, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::download::GHDownloader;
|
use crate::download::GHDownloader;
|
||||||
|
|
||||||
pub const SOLC_CACHE_DIRECTORY: &str = "solc";
|
pub const SOLC_CACHE_DIRECTORY: &str = "solc";
|
||||||
pub const SOLC_CACHER: OnceCell<Mutex<SolcCacher>> = OnceCell::new();
|
pub(crate) static SOLC_CACHER: LazyLock<Mutex<HashSet<PathBuf>>> = LazyLock::new(Default::default);
|
||||||
|
|
||||||
pub fn get_or_download(
|
pub(crate) fn get_or_download(
|
||||||
working_directory: &Path,
|
working_directory: &Path,
|
||||||
downloader: &GHDownloader,
|
downloader: &GHDownloader,
|
||||||
) -> anyhow::Result<PathBuf> {
|
) -> anyhow::Result<PathBuf> {
|
||||||
SOLC_CACHER
|
let target_directory = working_directory
|
||||||
.get_or_init(|| {
|
.join(SOLC_CACHE_DIRECTORY)
|
||||||
Mutex::new(SolcCacher::new(
|
.join(downloader.version.to_string());
|
||||||
working_directory.join(SOLC_CACHE_DIRECTORY),
|
let target_file = target_directory.join(downloader.target);
|
||||||
))
|
|
||||||
})
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_or_download(downloader)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SolcCacher {
|
let mut cache = SOLC_CACHER.lock().unwrap();
|
||||||
cache_directory: PathBuf,
|
if cache.contains(&target_file) {
|
||||||
cached_binaries: HashSet<PathBuf>,
|
return Ok(target_file);
|
||||||
}
|
|
||||||
|
|
||||||
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> {
|
create_dir_all(target_directory)?;
|
||||||
let directory = self.cache_directory.join(downloader.version.to_string());
|
download_to_file(&target_file, downloader)?;
|
||||||
let file_path = directory.join(downloader.target);
|
cache.insert(target_file.clone());
|
||||||
|
|
||||||
if self.cached_binaries.contains(&file_path) {
|
Ok(target_file)
|
||||||
return Ok(file_path);
|
}
|
||||||
}
|
|
||||||
|
fn download_to_file(path: &Path, downloader: &GHDownloader) -> anyhow::Result<()> {
|
||||||
create_dir_all(directory)?;
|
log::info!("caching file: {}", path.display());
|
||||||
|
|
||||||
let Ok(mut file) = File::create_new(&file_path) else {
|
let Ok(file) = File::create_new(path) else {
|
||||||
self.cached_binaries.insert(file_path.clone());
|
log::warn!("cache file already exists: {}", path.display());
|
||||||
return Ok(file_path);
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
|
||||||
file.write_all(&downloader.download()?)?;
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
#[cfg(unix)]
|
let mut permissions = file.metadata()?.permissions();
|
||||||
{
|
permissions.set_mode(permissions.mode() | 0o111);
|
||||||
let mut permissions = file.metadata()?.permissions();
|
file.set_permissions(permissions)?;
|
||||||
let mode = permissions.mode() | 0o111;
|
}
|
||||||
permissions.set_mode(mode);
|
|
||||||
file.set_permissions(permissions)?;
|
let mut file = BufWriter::new(file);
|
||||||
}
|
file.write_all(&downloader.download()?)?;
|
||||||
|
file.flush()?;
|
||||||
#[cfg(target_os = "macos")]
|
drop(file);
|
||||||
std::process::Command::new("xattr")
|
|
||||||
.arg("-d")
|
#[cfg(target_os = "macos")]
|
||||||
.arg("com.apple.quarantine")
|
std::process::Command::new("xattr")
|
||||||
.arg(&file_path)
|
.arg("-d")
|
||||||
.stderr(std::process::Stdio::null())
|
.arg("com.apple.quarantine")
|
||||||
.stdout(std::process::Stdio::null())
|
.arg(&path)
|
||||||
.stdout(std::process::Stdio::null())
|
.stderr(std::process::Stdio::null())
|
||||||
.spawn()?
|
.stdout(std::process::Stdio::null())
|
||||||
.wait()?;
|
.stdout(std::process::Stdio::null())
|
||||||
|
.spawn()?
|
||||||
Ok(file_path)
|
.wait()?;
|
||||||
}
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
//! This module downloads solc binaries.
|
//! This module downloads solc binaries.
|
||||||
|
|
||||||
use std::{collections::HashMap, sync::Mutex};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
sync::{LazyLock, Mutex},
|
||||||
|
};
|
||||||
|
|
||||||
use once_cell::sync::Lazy;
|
|
||||||
use semver::Version;
|
use semver::Version;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
|
||||||
use crate::list::List;
|
use crate::list::List;
|
||||||
|
|
||||||
pub static LIST_CACHE: Lazy<Mutex<HashMap<&'static str, List>>> = Lazy::new(Default::default);
|
pub static LIST_CACHE: LazyLock<Mutex<HashMap<&'static str, List>>> =
|
||||||
|
LazyLock::new(Default::default);
|
||||||
|
|
||||||
impl List {
|
impl List {
|
||||||
pub const LINUX_URL: &str = "https://binaries.soliditylang.org/linux-amd64/list.json";
|
pub const LINUX_URL: &str = "https://binaries.soliditylang.org/linux-amd64/list.json";
|
||||||
@@ -34,6 +37,7 @@ impl List {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Download solc binaries from GitHub releases (IPFS links aren't reliable).
|
/// Download solc binaries from GitHub releases (IPFS links aren't reliable).
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
pub struct GHDownloader {
|
pub struct GHDownloader {
|
||||||
pub version: Version,
|
pub version: Version,
|
||||||
pub target: &'static str,
|
pub target: &'static str,
|
||||||
@@ -82,6 +86,7 @@ impl GHDownloader {
|
|||||||
/// Errors out if the download fails or the digest of the downloaded file
|
/// Errors out if the download fails or the digest of the downloaded file
|
||||||
/// mismatches the expected digest from the release [List].
|
/// mismatches the expected digest from the release [List].
|
||||||
pub fn download(&self) -> anyhow::Result<Vec<u8>> {
|
pub fn download(&self) -> anyhow::Result<Vec<u8>> {
|
||||||
|
log::info!("downloading solc: {self:?}");
|
||||||
let expected_digest = List::download(self.list)?
|
let expected_digest = List::download(self.list)?
|
||||||
.builds
|
.builds
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pub mod list;
|
|||||||
/// Subsequent calls for the same version will use a cached artifact
|
/// Subsequent calls for the same version will use a cached artifact
|
||||||
/// and not download it again.
|
/// and not download it again.
|
||||||
pub fn download_solc(
|
pub fn download_solc(
|
||||||
working_directory: &Path,
|
cache_directory: &Path,
|
||||||
version: Version,
|
version: Version,
|
||||||
wasm: bool,
|
wasm: bool,
|
||||||
) -> anyhow::Result<PathBuf> {
|
) -> anyhow::Result<PathBuf> {
|
||||||
@@ -35,5 +35,5 @@ pub fn download_solc(
|
|||||||
unimplemented!()
|
unimplemented!()
|
||||||
};
|
};
|
||||||
|
|
||||||
get_or_download(working_directory, &downloader)
|
get_or_download(cache_directory, &downloader)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user