Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

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

Merged
merged 2 commits into from
May 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
38 changes: 33 additions & 5 deletions ethers-solc/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}

Expand All @@ -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();
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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())?;
}

Expand Down
62 changes: 62 additions & 0 deletions ethers-solc/tests/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<_>>()
);
}