From e0b6f653592b11d5dd145910c2a257ecac26c6a8 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 10 Jan 2022 20:43:34 +0100 Subject: [PATCH] refactor(solc): more temp project features (#778) * chore: replace tempdir with tempfile crate * update tempproject constructors * make clippy happy * add default impl --- Cargo.lock | 55 +-------------------------------- ethers-solc/Cargo.toml | 6 ++-- ethers-solc/benches/read_all.rs | 2 +- ethers-solc/src/cache.rs | 6 ++++ ethers-solc/src/config.rs | 6 ++-- ethers-solc/src/lib.rs | 4 +-- ethers-solc/src/project_util.rs | 45 +++++++++++++++++++++------ ethers-solc/src/remappings.rs | 11 ++++--- ethers-solc/src/utils.rs | 12 +++++-- ethers-solc/tests/project.rs | 4 +-- 10 files changed, 67 insertions(+), 84 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4642c59f..ac501c20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1352,7 +1352,7 @@ dependencies = [ "sha2 0.9.9", "solang-parser", "svm-rs", - "tempdir", + "tempfile", "thiserror", "tiny-keccak", "tokio", @@ -1448,12 +1448,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - [[package]] name = "funty" version = "1.1.0" @@ -2631,19 +2625,6 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" -[[package]] -name = "rand" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -dependencies = [ - "fuchsia-cprng", - "libc", - "rand_core 0.3.1", - "rdrand", - "winapi", -] - [[package]] name = "rand" version = "0.7.3" @@ -2689,21 +2670,6 @@ dependencies = [ "rand_core 0.6.3", ] -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - [[package]] name = "rand_core" version = "0.5.1" @@ -2765,15 +2731,6 @@ dependencies = [ "num_cpus", ] -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - [[package]] name = "redox_syscall" version = "0.2.10" @@ -3534,16 +3491,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" -[[package]] -name = "tempdir" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" -dependencies = [ - "rand 0.4.6", - "remove_dir_all", -] - [[package]] name = "tempfile" version = "3.2.0" diff --git a/ethers-solc/Cargo.toml b/ethers-solc/Cargo.toml index f70a4bac..7daef9b7 100644 --- a/ethers-solc/Cargo.toml +++ b/ethers-solc/Cargo.toml @@ -31,7 +31,7 @@ glob = "0.3.0" tracing = "0.1.29" num_cpus = "1.13.1" tiny-keccak = { version = "2.0.2", default-features = false } -tempdir = { version = "0.3.7", optional = true } +tempfile = { version = "3.2.0", optional = true } fs_extra = { version = "1.2.0", optional = true } sha2 = { version = "0.9.8", default-features = false } dunce = "1.0.2" @@ -51,7 +51,7 @@ getrandom = { version = "0.2", features = ["js"] } [dev-dependencies] criterion = { version = "0.3", features = ["async_tokio"] } pretty_assertions = "1.0.0" -tempdir = "0.3.7" +tempfile = "3.2.0" tokio = { version = "1.15.0", features = ["full"] } [[bench]] @@ -72,7 +72,7 @@ default = ["rustls"] async = ["tokio", "futures-util"] full = ["async", "svm"] # Utilities for creating and testing project workspaces -project-util = ["tempdir", "fs_extra"] +project-util = ["tempfile", "fs_extra"] tests = [] openssl = ["svm/openssl"] rustls = ["svm/rustls"] diff --git a/ethers-solc/benches/read_all.rs b/ethers-solc/benches/read_all.rs index 6c87c620..3baccbb0 100644 --- a/ethers-solc/benches/read_all.rs +++ b/ethers-solc/benches/read_all.rs @@ -13,7 +13,7 @@ use std::{ }; fn read_all_benchmark(c: &mut Criterion) { - let root = tempdir::TempDir::new("bench_read_many").unwrap(); + let root = tempfile::tempdir().unwrap(); let inputs = prepare_contracts(root.path(), 8); let mut group = c.benchmark_group("read many"); diff --git a/ethers-solc/src/cache.rs b/ethers-solc/src/cache.rs index 6dd241e6..aa6a3dd1 100644 --- a/ethers-solc/src/cache.rs +++ b/ethers-solc/src/cache.rs @@ -227,6 +227,12 @@ impl SolFilesCache { } } +impl Default for SolFilesCache { + fn default() -> Self { + SolFilesCache { format: ETHERS_FORMAT_VERSION.to_string(), files: Default::default() } + } +} + #[derive(Debug, Clone, Default)] pub struct SolFilesCacheBuilder { format: Option, diff --git a/ethers-solc/src/config.rs b/ethers-solc/src/config.rs index 50d91518..e2a69da2 100644 --- a/ethers-solc/src/config.rs +++ b/ethers-solc/src/config.rs @@ -591,7 +591,7 @@ mod tests { #[test] fn can_autodetect_dirs() { - let root = tempdir::TempDir::new("root").unwrap(); + let root = crate::utils::tempdir("root").unwrap(); let out = root.path().join("out"); let artifacts = root.path().join("artifacts"); let contracts = root.path().join("contracts"); @@ -633,13 +633,13 @@ mod tests { assert_eq!(ProjectPathsConfig::find_libs(root), vec![node_modules.clone()],); assert_eq!( ProjectPathsConfig::builder().build_with_root(&root).libraries, - vec![canonicalized(node_modules.clone())], + vec![canonicalized(node_modules)], ); std::fs::File::create(&lib).unwrap(); assert_eq!(ProjectPathsConfig::find_libs(root), vec![lib.clone()],); assert_eq!( ProjectPathsConfig::builder().build_with_root(&root).libraries, - vec![canonicalized(lib.clone())], + vec![canonicalized(lib)], ); } } diff --git a/ethers-solc/src/lib.rs b/ethers-solc/src/lib.rs index 5d6c784d..058d3479 100644 --- a/ethers-solc/src/lib.rs +++ b/ethers-solc/src/lib.rs @@ -19,8 +19,8 @@ pub use compile::*; mod config; pub use config::{ - AllowedLibPaths, Artifact, ArtifactOutput, MinimalCombinedArtifacts, ProjectPathsConfig, - SolcConfig, + AllowedLibPaths, Artifact, ArtifactOutput, MinimalCombinedArtifacts, PathStyle, + ProjectPathsConfig, SolcConfig, }; pub mod remappings; diff --git a/ethers-solc/src/project_util.rs b/ethers-solc/src/project_util.rs index e2839fd5..34c31412 100644 --- a/ethers-solc/src/project_util.rs +++ b/ethers-solc/src/project_util.rs @@ -3,14 +3,18 @@ use crate::{ config::ProjectPathsConfigBuilder, error::{Result, SolcError}, hh::HardhatArtifacts, - ArtifactOutput, MinimalCombinedArtifacts, Project, ProjectCompileOutput, ProjectPathsConfig, - SolcIoError, + utils::tempdir, + ArtifactOutput, MinimalCombinedArtifacts, PathStyle, Project, ProjectCompileOutput, + ProjectPathsConfig, SolcIoError, }; use fs_extra::{dir, file}; -use std::path::{Path, PathBuf}; -use tempdir::TempDir; +use std::{ + fmt, + path::{Path, PathBuf}, +}; +use tempfile::TempDir; -pub struct TempProject { +pub struct TempProject { /// temporary workspace root _root: TempDir, /// actual project workspace with the `root` tempdir as its root @@ -19,19 +23,34 @@ pub struct TempProject { impl TempProject { /// Makes sure all resources are created - fn create_new(root: TempDir, inner: Project) -> std::result::Result { + pub fn create_new(root: TempDir, inner: Project) -> std::result::Result { let project = Self { _root: root, inner }; project.paths().create_all()?; Ok(project) } - pub fn new(paths: ProjectPathsConfigBuilder) -> Result { - let tmp_dir = TempDir::new("root").map_err(|err| SolcError::io(err, "root"))?; + /// Creates a new temp project inside a tempdir with a prefixed directory + pub fn prefixed(prefix: &str, paths: ProjectPathsConfigBuilder) -> Result { + let tmp_dir = tempdir(prefix)?; let paths = paths.build_with_root(tmp_dir.path()); let inner = Project::builder().artifacts().paths(paths).build()?; Ok(Self::create_new(tmp_dir, inner)?) } + /// Creates a new temp project for the given `PathStyle` + pub fn with_style(prefix: &str, style: PathStyle) -> Result { + let tmp_dir = tempdir(prefix)?; + let paths = style.paths(tmp_dir.path())?; + let inner = Project::builder().artifacts().paths(paths).build()?; + Ok(Self::create_new(tmp_dir, inner)?) + } + + /// Creates a new temp project using the provided paths and setting the project root to a temp + /// dir + pub fn new(paths: ProjectPathsConfigBuilder) -> Result { + Self::prefixed("temp-project", paths) + } + pub fn project(&self) -> &Project { &self.inner } @@ -117,6 +136,12 @@ impl TempProject { } } +impl fmt::Debug for TempProject { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TempProject").field("paths", self.paths()).finish() + } +} + fn create_contract_file(path: PathBuf, content: impl AsRef) -> Result { if let Some(parent) = path.parent() { std::fs::create_dir_all(parent) @@ -138,7 +163,7 @@ fn contract_file_name(name: impl AsRef) -> String { impl TempProject { /// Creates an empty new hardhat style workspace in a new temporary dir pub fn hardhat() -> Result { - let tmp_dir = TempDir::new("tmp_hh").map_err(|err| SolcError::io(err, "tmp_hh"))?; + let tmp_dir = tempdir("tmp_hh")?; let paths = ProjectPathsConfig::hardhat(tmp_dir.path())?; @@ -150,7 +175,7 @@ impl TempProject { impl TempProject { /// Creates an empty new dapptools style workspace in a new temporary dir pub fn dapptools() -> Result { - let tmp_dir = TempDir::new("tmp_dapp").map_err(|err| SolcError::io(err, "temp_dapp"))?; + let tmp_dir = tempdir("tmp_dapp")?; let paths = ProjectPathsConfig::dapptools(tmp_dir.path())?; let inner = Project::builder().artifacts().paths(paths).build()?; diff --git a/ethers-solc/src/remappings.rs b/ethers-solc/src/remappings.rs index ff5ebb91..7d3f4a99 100644 --- a/ethers-solc/src/remappings.rs +++ b/ethers-solc/src/remappings.rs @@ -356,6 +356,7 @@ fn last_nested_source_dir(root: &Path, dir: &Path) -> PathBuf { #[cfg(test)] mod tests { use super::*; + use crate::utils::tempdir; #[test] fn serde() { @@ -398,7 +399,7 @@ mod tests { #[test] fn find_remapping_dapptools() { - let tmp_dir = tempdir::TempDir::new("lib").unwrap(); + let tmp_dir = tempdir("lib").unwrap(); let tmp_dir_path = tmp_dir.path(); let paths = ["repo1/src/", "repo1/src/contract.sol"]; mkdir_or_touch(tmp_dir_path, &paths[..]); @@ -414,7 +415,7 @@ mod tests { #[test] fn recursive_remappings() { - let tmp_dir = tempdir::TempDir::new("lib").unwrap(); + let tmp_dir = tempdir("lib").unwrap(); let tmp_dir_path = tmp_dir.path(); let paths = [ "repo1/src/", @@ -489,7 +490,7 @@ mod tests { #[test] fn remappings() { - let tmp_dir = tempdir::TempDir::new("tmp").unwrap(); + let tmp_dir = tempdir("tmp").unwrap(); let tmp_dir_path = tmp_dir.path().join("lib"); let repo1 = tmp_dir_path.join("src_repo"); let repo2 = tmp_dir_path.join("contracts_repo"); @@ -528,7 +529,7 @@ mod tests { #[test] fn simple_dapptools_remappings() { - let tmp_dir = tempdir::TempDir::new("lib").unwrap(); + let tmp_dir = tempdir("lib").unwrap(); let tmp_dir_path = tmp_dir.path(); let paths = [ "ds-test/src", @@ -570,7 +571,7 @@ mod tests { #[test] fn hardhat_remappings() { - let tmp_dir = tempdir::TempDir::new("node_modules").unwrap(); + let tmp_dir = tempdir("node_modules").unwrap(); let tmp_dir_node_modules = tmp_dir.path().join("node_modules"); let paths = [ "node_modules/@aave/aave-token/contracts/token/", diff --git a/ethers-solc/src/utils.rs b/ethers-solc/src/utils.rs index 49a0e467..df1d1abc 100644 --- a/ethers-solc/src/utils.rs +++ b/ethers-solc/src/utils.rs @@ -243,6 +243,12 @@ pub(crate) fn find_fave_or_alt_path(root: impl AsRef, fave: &str, alt: &st p } +/// Creates a new named tempdir +#[cfg(any(test, feature = "project-util"))] +pub(crate) fn tempdir(name: &str) -> Result { + tempfile::Builder::new().prefix(name).tempdir().map_err(|err| SolcIoError::new(err, name)) +} + #[cfg(test)] mod tests { use super::*; @@ -251,7 +257,7 @@ mod tests { fs::{create_dir_all, File}, }; - use tempdir::TempDir; + use tempdir; #[test] fn can_determine_local_paths() { @@ -259,7 +265,7 @@ mod tests { assert!(is_local_source_name(&[""], "../local/contract.sol")); assert!(!is_local_source_name(&[""], "/ds-test/test.sol")); - let tmp_dir = TempDir::new("contracts").unwrap(); + let tmp_dir = tempdir("contracts").unwrap(); let dir = tmp_dir.path().join("ds-test"); create_dir_all(&dir).unwrap(); File::create(dir.join("test.sol")).unwrap(); @@ -269,7 +275,7 @@ mod tests { #[test] fn can_find_solidity_sources() { - let tmp_dir = TempDir::new("contracts").unwrap(); + let tmp_dir = tempdir("contracts").unwrap(); let file_a = tmp_dir.path().join("a.sol"); let file_b = tmp_dir.path().join("a.sol"); diff --git a/ethers-solc/tests/project.rs b/ethers-solc/tests/project.rs index 86c2d290..f178dfff 100644 --- a/ethers-solc/tests/project.rs +++ b/ethers-solc/tests/project.rs @@ -7,8 +7,6 @@ use std::{ str::FromStr, }; -use tempdir::TempDir; - use ethers_solc::{ cache::{SolFilesCache, SOLIDITY_FILES_CACHE_FILENAME}, project_util::*, @@ -141,7 +139,7 @@ fn can_compile_dapp_detect_changes_in_libs() { #[test] fn can_compile_dapp_sample_with_cache() { - let tmp_dir = TempDir::new("root").unwrap(); + let tmp_dir = tempfile::tempdir().unwrap(); let root = tmp_dir.path(); let cache = root.join("cache").join(SOLIDITY_FILES_CACHE_FILENAME); let artifacts = root.join("out");