feat: add solc svm find support (#547)

* feat: add solc svm find support

* feat: add svm install

* feat: add full feature

* make home non wasm32 only

* simplify features

* make compile with wasm target

* fix: doctests
This commit is contained in:
Matthias Seitz 2021-10-31 15:41:36 +01:00 committed by GitHub
parent f0dea75219
commit 1cb43a3df3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 253 additions and 1 deletions

184
Cargo.lock generated
View File

@ -435,6 +435,17 @@ dependencies = [
"generic-array 0.14.4",
]
[[package]]
name = "clap"
version = "2.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [
"bitflags",
"textwrap",
"unicode-width",
]
[[package]]
name = "cmac"
version = "0.6.0"
@ -536,6 +547,34 @@ dependencies = [
"winapi",
]
[[package]]
name = "console"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3993e6445baa160675931ec041a5e03ca84b9c6e32a056150d3aa2bdda0a1f45"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"regex",
"terminal_size",
"unicode-width",
"winapi",
]
[[package]]
name = "console"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31"
dependencies = [
"encode_unicode",
"libc",
"once_cell",
"terminal_size",
"winapi",
]
[[package]]
name = "const-oid"
version = "0.6.1"
@ -676,6 +715,18 @@ dependencies = [
"const-oid",
]
[[package]]
name = "dialoguer"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9dd058f8b65922819fabb4a41e7d1964e56344042c26efbccd465202c23fa0c"
dependencies = [
"console 0.14.1",
"lazy_static",
"tempfile",
"zeroize",
]
[[package]]
name = "digest"
version = "0.8.1"
@ -772,6 +823,12 @@ dependencies = [
"zeroize",
]
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "encoding_rs"
version = "0.8.28"
@ -1078,12 +1135,14 @@ dependencies = [
"ethers-core",
"futures-util",
"hex",
"home",
"md-5",
"once_cell",
"regex",
"semver 1.0.4",
"serde",
"serde_json",
"svm-rs",
"tempdir",
"thiserror",
"tokio",
@ -1352,6 +1411,15 @@ version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "heck"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
@ -1394,6 +1462,15 @@ dependencies = [
"digest 0.9.0",
]
[[package]]
name = "home"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"
dependencies = [
"winapi",
]
[[package]]
name = "http"
version = "0.2.5"
@ -1539,6 +1616,18 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "indicatif"
version = "0.16.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b"
dependencies = [
"console 0.15.0",
"lazy_static",
"number_prefix",
"regex",
]
[[package]]
name = "instant"
version = "0.1.12"
@ -1557,6 +1646,15 @@ version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9"
[[package]]
name = "itertools"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "0.4.8"
@ -1763,6 +1861,12 @@ dependencies = [
"libc",
]
[[package]]
name = "number_prefix"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "object"
version = "0.26.2"
@ -2797,12 +2901,61 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "structopt"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c"
dependencies = [
"clap",
"lazy_static",
"structopt-derive",
]
[[package]]
name = "structopt-derive"
version = "0.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "subtle"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]]
name = "svm-rs"
version = "0.1.2"
source = "git+https://github.com/roynalnaruto/svm-rs#5d353ec236a596dbfd2b37878ee5aee53ab6eadf"
dependencies = [
"anyhow",
"cfg-if 1.0.0",
"console 0.14.1",
"dialoguer",
"home",
"indicatif",
"itertools",
"once_cell",
"rand 0.8.4",
"reqwest",
"semver 1.0.4",
"serde",
"serde_json",
"structopt",
"tempfile",
"thiserror",
"tokio",
"url",
]
[[package]]
name = "syn"
version = "1.0.81"
@ -2856,6 +3009,25 @@ dependencies = [
"winapi",
]
[[package]]
name = "terminal_size"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "thiserror"
version = "1.0.30"
@ -3154,6 +3326,18 @@ dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-segmentation"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
[[package]]
name = "unicode-width"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
version = "0.2.2"

View File

@ -27,6 +27,10 @@ md-5 = "0.9.1"
thiserror = "1.0.30"
hex = "0.4.3"
colored = "2.0.0"
svm = { package = "svm-rs", git = "https://github.com/roynalnaruto/svm-rs", optional = true }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
home = "0.5.3"
[dev-dependencies]
tokio = { version = "1.12.0", features = ["full"] }
@ -34,3 +38,4 @@ tempdir = "0.3.7"
[features]
async = ["tokio", "futures-util"]
full = ["async", "svm"]

View File

@ -52,6 +52,63 @@ impl Solc {
Solc(path.into())
}
/// Returns the directory in which [svm](https://github.com/roynalnaruto/svm-rs) stores all versions
///
/// This will be `~/.svm` on unix
#[cfg(not(target_arch = "wasm32"))]
pub fn svm_home() -> Option<PathBuf> {
home::home_dir().map(|dir| dir.join(".svm"))
}
/// Returns the path for a [svm](https://github.com/roynalnaruto/svm-rs) installed version.
///
/// # Example
/// ```no_run
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// use ethers_solc::Solc;
/// let solc = Solc::find_svm_installed_version("0.8.9").unwrap();
/// assert_eq!(solc, Some(Solc::new("~/.svm/0.8.9/solc-0.8.9")));
/// # Ok(())
/// # }
/// ```
#[cfg(not(target_arch = "wasm32"))]
pub fn find_svm_installed_version(version: impl AsRef<str>) -> Result<Option<Self>> {
let version = version.as_ref();
let solc = walkdir::WalkDir::new(
Self::svm_home().ok_or_else(|| SolcError::solc("svm home dir not found"))?,
)
.max_depth(1)
.into_iter()
.filter_map(std::result::Result::ok)
.filter(|e| e.file_type().is_dir())
.find(|e| e.path().ends_with(version))
.map(|e| e.path().join(format!("solc-{}", version)))
.map(Solc::new);
Ok(solc)
}
/// Installs the provided version of Solc in the machine under the svm dir
/// # Example
/// ```no_run
/// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
/// use ethers_solc::{Solc, ISTANBUL_SOLC};
/// Solc::install(&ISTANBUL_SOLC).await.unwrap();
/// let solc = Solc::find_svm_installed_version(&ISTANBUL_SOLC.to_string());
/// # Ok(())
/// # }
/// ```
#[cfg(feature = "svm")]
pub async fn install(version: &Version) -> std::result::Result<(), svm::SolcVmError> {
svm::install(version).await
}
/// Blocking version of `Self::install`
#[cfg(all(feature = "svm", feature = "async"))]
pub fn blocking_install(version: &Version) -> std::result::Result<(), svm::SolcVmError> {
tokio::runtime::Runtime::new().unwrap().block_on(svm::install(version))?;
Ok(())
}
/// Convenience function for compiling all sources under the given path
pub fn compile_source(&self, path: impl AsRef<Path>) -> Result<CompilerOutput> {
self.compile(&CompilerInput::new(path)?)
@ -218,6 +275,12 @@ mod tests {
let _version = Version::from_str("0.6.6+commit.6c089d02.Linux.gcc").unwrap();
}
#[test]
#[ignore]
fn can_find_solc() {
let _solc = Solc::find_svm_installed_version("0.8.9").unwrap();
}
#[cfg(feature = "async")]
#[tokio::test]
async fn async_solc_version_works() {

View File

@ -8,7 +8,7 @@ use std::collections::btree_map::Entry;
pub mod cache;
mod compile;
pub use compile::Solc;
pub use compile::*;
mod config;
pub use config::{ArtifactOutput, ProjectPathsConfig, SolcConfig};