feat(solc): add strip and join functions to sources and contracts (#1252)

This commit is contained in:
Matthias Seitz 2022-05-12 23:48:16 +02:00 committed by GitHub
parent 494af08b85
commit f5efbbb86a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 4 deletions

View File

@ -4,7 +4,7 @@ use crate::artifacts::{
}; };
use semver::Version; use semver::Version;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::BTreeMap; use std::{collections::BTreeMap, path::Path};
/// file -> [(contract name -> Contract + solc version)] /// file -> [(contract name -> Contract + solc version)]
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
@ -129,6 +129,36 @@ impl VersionedContracts {
.flat_map(|(name, c)| c.into_iter().map(move |c| (name.clone(), c.contract))) .flat_map(|(name, c)| c.into_iter().map(move |c| (name.clone(), c.contract)))
}) })
} }
/// Sets the contract's file paths to `root` adjoined to `self.file`.
pub fn join_all(&mut self, root: impl AsRef<Path>) -> &mut Self {
let root = root.as_ref();
self.0 = std::mem::take(&mut self.0)
.into_iter()
.map(|(contract_path, contracts)| {
(root.join(contract_path).to_string_lossy().to_string(), contracts)
})
.collect();
self
}
/// Removes `base` from all contract paths
pub fn strip_prefix_all(&mut self, base: impl AsRef<Path>) -> &mut Self {
let base = base.as_ref();
self.0 = std::mem::take(&mut self.0)
.into_iter()
.map(|(contract_path, contracts)| {
let p = Path::new(&contract_path);
(
p.strip_prefix(base)
.map(|p| p.to_string_lossy().to_string())
.unwrap_or(contract_path),
contracts,
)
})
.collect();
self
}
} }
impl AsRef<FileToContractsMap<Vec<VersionedContract>>> for VersionedContracts { impl AsRef<FileToContractsMap<Vec<VersionedContract>>> for VersionedContracts {

View File

@ -92,10 +92,9 @@ impl<T: ArtifactOutput> ProjectCompileOutput<T> {
/// ///
/// # Example /// # Example
/// ///
/// Make all artifact files relative tot the project's root directory /// Make all artifact files relative to the project's root directory
/// ///
/// ```no_run /// ```no_run
/// use ethers_solc::artifacts::contract::CompactContractBytecode;
/// use ethers_solc::Project; /// use ethers_solc::Project;
/// ///
/// let project = Project::builder().build().unwrap(); /// let project = Project::builder().build().unwrap();
@ -105,6 +104,7 @@ impl<T: ArtifactOutput> ProjectCompileOutput<T> {
let base = base.as_ref(); let base = base.as_ref();
self.cached_artifacts = self.cached_artifacts.into_stripped_file_prefixes(base); self.cached_artifacts = self.cached_artifacts.into_stripped_file_prefixes(base);
self.compiled_artifacts = self.compiled_artifacts.into_stripped_file_prefixes(base); self.compiled_artifacts = self.compiled_artifacts.into_stripped_file_prefixes(base);
self.compiler_output.strip_prefix_all(base);
self self
} }
@ -360,6 +360,36 @@ impl AggregatedCompilerOutput {
pub fn split(self) -> (VersionedSourceFiles, VersionedContracts) { pub fn split(self) -> (VersionedSourceFiles, VersionedContracts) {
(self.sources, self.contracts) (self.sources, self.contracts)
} }
/// Strips the given prefix from all file paths to make them relative to the given
/// `base` argument.
///
/// Convenience method for [Self::strip_prefix_all()] that consumes the type.
///
/// # Example
///
/// Make all sources and contracts relative to the project's root directory
///
/// ```no_run
/// use ethers_solc::Project;
///
/// let project = Project::builder().build().unwrap();
/// let output = project.compile().unwrap().output().with_stripped_file_prefixes(project.root());
/// ```
pub fn with_stripped_file_prefixes(mut self, base: impl AsRef<Path>) -> Self {
let base = base.as_ref();
self.contracts.strip_prefix_all(base);
self.sources.strip_prefix_all(base);
self
}
/// Removes `base` from all contract paths
pub fn strip_prefix_all(&mut self, base: impl AsRef<Path>) -> &mut Self {
let base = base.as_ref();
self.contracts.strip_prefix_all(base);
self.sources.strip_prefix_all(base);
self
}
} }
/// Helper type to implement display for solc errors /// Helper type to implement display for solc errors

View File

@ -1,7 +1,7 @@
use crate::SourceFile; use crate::SourceFile;
use semver::Version; use semver::Version;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::BTreeMap; use std::{collections::BTreeMap, path::Path};
/// (source_file path -> `SourceFile` + solc version) /// (source_file path -> `SourceFile` + solc version)
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
@ -223,6 +223,36 @@ impl VersionedSourceFiles {
.map(move |source| (path.clone(), source.source_file, source.version)) .map(move |source| (path.clone(), source.source_file, source.version))
}) })
} }
/// Sets the sources' file paths to `root` adjoined to `self.file`.
pub fn join_all(&mut self, root: impl AsRef<Path>) -> &mut Self {
let root = root.as_ref();
self.0 = std::mem::take(&mut self.0)
.into_iter()
.map(|(file_path, sources)| {
(root.join(file_path).to_string_lossy().to_string(), sources)
})
.collect();
self
}
/// Removes `base` from all source file paths
pub fn strip_prefix_all(&mut self, base: impl AsRef<Path>) -> &mut Self {
let base = base.as_ref();
self.0 = std::mem::take(&mut self.0)
.into_iter()
.map(|(file_path, sources)| {
let p = Path::new(&file_path);
(
p.strip_prefix(base)
.map(|p| p.to_string_lossy().to_string())
.unwrap_or(file_path),
sources,
)
})
.collect();
self
}
} }
impl AsRef<BTreeMap<String, Vec<VersionedSourceFile>>> for VersionedSourceFiles { impl AsRef<BTreeMap<String, Vec<VersionedSourceFile>>> for VersionedSourceFiles {