mirror of
https://github.com/pezkuwichain/revive-differential-tests.git
synced 2026-06-13 17:31:02 +00:00
Cache the compiler versions
This commit is contained in:
@@ -47,7 +47,7 @@ pub trait SolidityCompiler {
|
||||
version: impl Into<VersionOrRequirement>,
|
||||
) -> impl Future<Output = anyhow::Result<PathBuf>>;
|
||||
|
||||
fn version(&self) -> anyhow::Result<Version>;
|
||||
fn version(&self) -> impl Future<Output = anyhow::Result<Version>>;
|
||||
|
||||
/// Does the compiler support the provided mode and version settings?
|
||||
fn supports_mode(
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
//! compiling contracts to PolkaVM (PVM) bytecode.
|
||||
|
||||
use std::{
|
||||
os::unix::process::CommandExt,
|
||||
path::PathBuf,
|
||||
process::{Command, Stdio},
|
||||
sync::LazyLock,
|
||||
};
|
||||
|
||||
use dashmap::DashMap;
|
||||
use revive_dt_common::types::VersionOrRequirement;
|
||||
use revive_dt_config::Arguments;
|
||||
use revive_solc_json_interface::{
|
||||
@@ -223,29 +224,39 @@ impl SolidityCompiler for Resolc {
|
||||
Ok(PathBuf::from("resolc"))
|
||||
}
|
||||
|
||||
fn version(&self) -> anyhow::Result<semver::Version> {
|
||||
// Logic for parsing the resolc version from the following string:
|
||||
// Solidity frontend for the revive compiler version 0.3.0+commit.b238913.llvm-18.1.8
|
||||
async fn version(&self) -> anyhow::Result<semver::Version> {
|
||||
/// This is a cache of the path of the compiler to the version number of the compiler. We
|
||||
/// choose to cache the version in this way rather than through a field on the struct since
|
||||
/// compiler objects are being created all the time from the path and the compiler object is
|
||||
/// not reused over time.
|
||||
static VERSION_CACHE: LazyLock<DashMap<PathBuf, Version>> = LazyLock::new(Default::default);
|
||||
|
||||
let output = unsafe {
|
||||
Command::new(self.resolc_path.as_path())
|
||||
.arg("--version")
|
||||
.stdout(Stdio::piped())
|
||||
.pre_exec(|| Ok(()))
|
||||
.spawn()?
|
||||
.wait_with_output()?
|
||||
.stdout
|
||||
};
|
||||
let output = String::from_utf8_lossy(&output);
|
||||
let version_string = output
|
||||
.split("version ")
|
||||
.nth(1)
|
||||
.context("Version parsing failed")?
|
||||
.split("+")
|
||||
.next()
|
||||
.context("Version parsing failed")?;
|
||||
match VERSION_CACHE.entry(self.resolc_path.clone()) {
|
||||
dashmap::Entry::Occupied(occupied_entry) => Ok(occupied_entry.get().clone()),
|
||||
dashmap::Entry::Vacant(vacant_entry) => {
|
||||
let output = Command::new(self.resolc_path.as_path())
|
||||
.arg("--version")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()?
|
||||
.wait_with_output()?
|
||||
.stdout;
|
||||
|
||||
Version::parse(version_string).map_err(Into::into)
|
||||
let output = String::from_utf8_lossy(&output);
|
||||
let version_string = output
|
||||
.split("version ")
|
||||
.nth(1)
|
||||
.context("Version parsing failed")?
|
||||
.split("+")
|
||||
.next()
|
||||
.context("Version parsing failed")?;
|
||||
|
||||
let version = Version::parse(version_string)?;
|
||||
|
||||
vacant_entry.insert(version.clone());
|
||||
|
||||
Ok(version)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn supports_mode(
|
||||
@@ -275,7 +286,7 @@ mod test {
|
||||
let compiler = Resolc::new(path);
|
||||
|
||||
// Act
|
||||
let version = compiler.version();
|
||||
let version = compiler.version().await;
|
||||
|
||||
// Assert
|
||||
let _ = version.expect("Failed to get version");
|
||||
|
||||
+46
-41
@@ -2,11 +2,12 @@
|
||||
//! compiling contracts to EVM bytecode.
|
||||
|
||||
use std::{
|
||||
os::unix::process::CommandExt,
|
||||
path::PathBuf,
|
||||
process::{Command, Stdio},
|
||||
sync::LazyLock,
|
||||
};
|
||||
|
||||
use dashmap::DashMap;
|
||||
use revive_dt_common::types::VersionOrRequirement;
|
||||
use revive_dt_config::Arguments;
|
||||
use revive_dt_solc_binaries::download_solc;
|
||||
@@ -48,7 +49,7 @@ impl SolidityCompiler for Solc {
|
||||
}: CompilerInput,
|
||||
_: Self::Options,
|
||||
) -> anyhow::Result<CompilerOutput> {
|
||||
let compiler_supports_via_ir = self.version()? >= SOLC_VERSION_SUPPORTING_VIA_YUL_IR;
|
||||
let compiler_supports_via_ir = self.version().await? >= SOLC_VERSION_SUPPORTING_VIA_YUL_IR;
|
||||
|
||||
// Be careful to entirely omit the viaIR field if the compiler does not support it,
|
||||
// as it will error if you provide fields it does not know about. Because
|
||||
@@ -115,14 +116,11 @@ impl SolidityCompiler for Solc {
|
||||
};
|
||||
|
||||
let mut command = AsyncCommand::new(&self.solc_path);
|
||||
unsafe {
|
||||
command
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.arg("--standard-json")
|
||||
.pre_exec(|| Ok(()))
|
||||
};
|
||||
command
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.arg("--standard-json");
|
||||
|
||||
if let Some(ref base_path) = base_path {
|
||||
command.arg("--base-path").arg(base_path);
|
||||
@@ -213,33 +211,44 @@ impl SolidityCompiler for Solc {
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
fn version(&self) -> anyhow::Result<semver::Version> {
|
||||
// The following is the parsing code for the version from the solc version strings which
|
||||
// look like the following:
|
||||
// ```
|
||||
// solc, the solidity compiler commandline interface
|
||||
// Version: 0.8.30+commit.73712a01.Darwin.appleclang
|
||||
// ```
|
||||
async fn version(&self) -> anyhow::Result<semver::Version> {
|
||||
/// This is a cache of the path of the compiler to the version number of the compiler. We
|
||||
/// choose to cache the version in this way rather than through a field on the struct since
|
||||
/// compiler objects are being created all the time from the path and the compiler object is
|
||||
/// not reused over time.
|
||||
static VERSION_CACHE: LazyLock<DashMap<PathBuf, Version>> = LazyLock::new(Default::default);
|
||||
|
||||
let child = unsafe {
|
||||
Command::new(self.solc_path.as_path())
|
||||
.arg("--version")
|
||||
.stdout(Stdio::piped())
|
||||
.pre_exec(|| Ok(()))
|
||||
.spawn()
|
||||
}?;
|
||||
let output = child.wait_with_output()?;
|
||||
let output = String::from_utf8_lossy(&output.stdout);
|
||||
let version_line = output
|
||||
.split("Version: ")
|
||||
.nth(1)
|
||||
.context("Version parsing failed")?;
|
||||
let version_string = version_line
|
||||
.split("+")
|
||||
.next()
|
||||
.context("Version parsing failed")?;
|
||||
match VERSION_CACHE.entry(self.solc_path.clone()) {
|
||||
dashmap::Entry::Occupied(occupied_entry) => Ok(occupied_entry.get().clone()),
|
||||
dashmap::Entry::Vacant(vacant_entry) => {
|
||||
// The following is the parsing code for the version from the solc version strings
|
||||
// which look like the following:
|
||||
// ```
|
||||
// solc, the solidity compiler commandline interface
|
||||
// Version: 0.8.30+commit.73712a01.Darwin.appleclang
|
||||
// ```
|
||||
let child = Command::new(self.solc_path.as_path())
|
||||
.arg("--version")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()?;
|
||||
let output = child.wait_with_output()?;
|
||||
let output = String::from_utf8_lossy(&output.stdout);
|
||||
let version_line = output
|
||||
.split("Version: ")
|
||||
.nth(1)
|
||||
.context("Version parsing failed")?;
|
||||
let version_string = version_line
|
||||
.split("+")
|
||||
.next()
|
||||
.context("Version parsing failed")?;
|
||||
|
||||
Version::parse(version_string).map_err(Into::into)
|
||||
let version = Version::parse(version_string)?;
|
||||
|
||||
vacant_entry.insert(version.clone());
|
||||
|
||||
Ok(version)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn supports_mode(
|
||||
@@ -263,15 +272,13 @@ mod test {
|
||||
async fn compiler_version_can_be_obtained() {
|
||||
// Arrange
|
||||
let args = Arguments::default();
|
||||
println!("Getting compiler path");
|
||||
let path = Solc::get_compiler_executable(&args, Version::new(0, 7, 6))
|
||||
.await
|
||||
.unwrap();
|
||||
println!("Got compiler path");
|
||||
let compiler = Solc::new(path);
|
||||
|
||||
// Act
|
||||
let version = compiler.version();
|
||||
let version = compiler.version().await;
|
||||
|
||||
// Assert
|
||||
assert_eq!(
|
||||
@@ -284,15 +291,13 @@ mod test {
|
||||
async fn compiler_version_can_be_obtained1() {
|
||||
// Arrange
|
||||
let args = Arguments::default();
|
||||
println!("Getting compiler path");
|
||||
let path = Solc::get_compiler_executable(&args, Version::new(0, 4, 21))
|
||||
.await
|
||||
.unwrap();
|
||||
println!("Got compiler path");
|
||||
let compiler = Solc::new(path);
|
||||
|
||||
// Act
|
||||
let version = compiler.version();
|
||||
let version = compiler.version().await;
|
||||
|
||||
// Assert
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user