feat(solc): make cache entries relative to root dir (#1307)

* feat(solc): make cache entries relative to root dir

* chore: update CHANGELOG
This commit is contained in:
Matthias Seitz 2022-05-24 16:51:09 +02:00 committed by GitHub
parent 37f3df5234
commit 95862bc62c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 97 additions and 5 deletions

View File

@ -95,6 +95,8 @@
### Unreleased
- Save cache entry objects with relative paths
[#1307](https://github.com/gakonst/ethers-rs/pull/1307)
- Bundle svm, svm-builds and sha2 dependencies in new `svm-solc` feature
[#1071](https://github.com/gakonst/ethers-rs/pull/1071)
- Emit artifact files for source files without any ContractDefinition

View File

@ -104,7 +104,12 @@ impl SolFilesCache {
Ok(cache)
}
/// Reads the cache json file from the given path and returns the cache with modified paths
/// Reads the cache json file from the given path and returns the cache with paths adjoined to
/// the `ProjectPathsConfig`.
///
/// This expects the `artifact` files to be relative to the artifacts dir of the `paths` and the
/// `CachEntry` paths to be relative to the root dir of the `paths`
///
///
///
/// # Example
@ -120,7 +125,7 @@ impl SolFilesCache {
/// ```
pub fn read_joined(paths: &ProjectPathsConfig) -> Result<Self> {
let mut cache = SolFilesCache::read(&paths.cache)?;
cache.join_artifacts_files(&paths.artifacts);
cache.join_entries(&paths.root).join_artifacts_files(&paths.artifacts);
Ok(cache)
}
@ -139,6 +144,26 @@ impl SolFilesCache {
Ok(())
}
/// Sets the `CacheEntry`'s file paths to `root` adjoined to `self.file`.
pub fn join_entries(&mut self, root: impl AsRef<Path>) -> &mut Self {
let root = root.as_ref();
self.files = std::mem::take(&mut self.files)
.into_iter()
.map(|(path, entry)| (root.join(path), entry))
.collect();
self
}
/// Removes `base` from all `CacheEntry` paths
pub fn strip_entries_prefix(&mut self, base: impl AsRef<Path>) -> &mut Self {
let base = base.as_ref();
self.files = std::mem::take(&mut self.files)
.into_iter()
.map(|(path, entry)| (path.strip_prefix(base).map(Into::into).unwrap_or(path), entry))
.collect();
self
}
/// Sets the artifact files location to `base` adjoined to the `CachEntries` artifacts.
pub fn join_artifacts_files(&mut self, base: impl AsRef<Path>) -> &mut Self {
let base = base.as_ref();
@ -182,7 +207,7 @@ impl SolFilesCache {
/// # Example
///
/// ```
/// fn t() {
/// # fn t() {
/// use ethers_solc::artifacts::contract::CompactContract;
/// use ethers_solc::cache::SolFilesCache;
/// use ethers_solc::Project;
@ -934,10 +959,13 @@ impl<'a, T: ArtifactOutput> ArtifactsCache<'a, T> {
cache
.extend(dirty_source_files.into_iter().map(|(file, (entry, _))| (file, entry)));
cache.strip_artifact_files_prefixes(project.artifacts_path());
// write to disk
if write_to_disk {
// make all `CacheEntry` paths relative to the project root and all artifact
// paths relative to the artifact's directory
cache
.strip_entries_prefix(project.root())
.strip_artifact_files_prefixes(project.artifacts_path());
cache.write(project.cache_path())?;
}

View File

@ -1708,3 +1708,65 @@ fn can_parse_notice() {
})
);
}
#[test]
fn test_relative_cache_entries() {
let project = TempProject::dapptools().unwrap();
let _a = project
.add_source(
"A",
r#"
pragma solidity ^0.8.10;
contract A { }
"#,
)
.unwrap();
let _b = project
.add_source(
"B",
r#"
pragma solidity ^0.8.10;
contract B { }
"#,
)
.unwrap();
let _c = project
.add_source(
"C",
r#"
pragma solidity ^0.8.10;
contract C { }
"#,
)
.unwrap();
let _d = project
.add_source(
"D",
r#"
pragma solidity ^0.8.10;
contract D { }
"#,
)
.unwrap();
let compiled = project.compile().unwrap();
println!("{}", compiled);
assert!(!compiled.has_compiler_errors());
let cache = SolFilesCache::read(project.cache_path()).unwrap();
let entries = vec![
PathBuf::from("src/A.sol"),
PathBuf::from("src/B.sol"),
PathBuf::from("src/C.sol"),
PathBuf::from("src/D.sol"),
];
assert_eq!(entries, cache.files.keys().cloned().collect::<Vec<_>>());
let cache = SolFilesCache::read_joined(project.paths()).unwrap();
assert_eq!(
entries.into_iter().map(|p| project.root().join(p)).collect::<Vec<_>>(),
cache.files.keys().cloned().collect::<Vec<_>>()
);
}