Skip to content

feat(forge build): cache project selectors by default #10651

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
5 changes: 4 additions & 1 deletion crates/cli/src/utils/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,10 @@ pub async fn print_traces(

/// Traverse the artifacts in the project to generate local signatures and merge them into the cache
/// file.
pub fn cache_local_signatures(output: &ProjectCompileOutput, cache_dir: &Path) -> Result<()> {
pub fn cache_local_signatures(output: &ProjectCompileOutput) -> Result<()> {
let Some(cache_dir) = Config::foundry_cache_dir() else {
eyre::bail!("Failed to get `cache_dir` to generate local signatures.");
};
let path = cache_dir.join("signatures");
let mut signatures = SignaturesCache::load(&path);
for (_, artifact) in output.artifacts() {
Expand Down
8 changes: 7 additions & 1 deletion crates/forge/src/cmd/build.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use super::{install, watch::WatchArgs};
use clap::Parser;
use eyre::Result;
use foundry_cli::{opts::BuildOpts, utils::LoadConfig};
use foundry_cli::{
opts::BuildOpts,
utils::{cache_local_signatures, LoadConfig},
};
use foundry_common::{compile::ProjectCompiler, shell};
use foundry_compilers::{
compilers::{multi::MultiCompilerLanguage, Language},
Expand Down Expand Up @@ -100,6 +103,9 @@ impl BuildArgs {

let output = compiler.compile(&project)?;

// Cache project selectors.
cache_local_signatures(&output)?;

if format_json && !self.names && !self.sizes {
sh_println!("{}", serde_json::to_string_pretty(&output.output())?)?;
}
Expand Down
3 changes: 1 addition & 2 deletions crates/forge/src/cmd/selectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use foundry_common::{
selectors::{import_selectors, SelectorImportData},
};
use foundry_compilers::{artifacts::output_selection::ContractOutputSelection, info::ContractInfo};
use foundry_config::Config;
use std::fs::canonicalize;

/// CLI arguments for `forge selectors`.
Expand Down Expand Up @@ -95,7 +94,7 @@ impl SelectorsSubcommands {
// compile the project to get the artifacts/abis
let project = build_args.project()?;
let outcome = ProjectCompiler::new().quiet(true).compile(&project)?;
cache_local_signatures(&outcome, &Config::foundry_cache_dir().unwrap())?
cache_local_signatures(&outcome)?;
}
Self::Upload { contract, all, project_paths } => {
let build_args = BuildOpts {
Expand Down
38 changes: 38 additions & 0 deletions crates/forge/tests/cli/test_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3828,3 +3828,41 @@ Encountered a total of 1 failing tests, 0 tests succeeded

"#]]);
});

// This test is a copy of `error_event_decode_with_cache` in cast/tests/cli/selectors.rs
// but it uses `forge build` to check that the project selectors are cached by default.
forgetest_init!(build_with_selectors_cache, |prj, cmd| {
prj.add_source(
"LocalProjectContract",
r#"
contract ContractWithCustomError {
error AnotherValueTooHigh(uint256, address);
event MyUniqueEventWithinLocalProject(uint256 a, address b);
}
"#,
)
.unwrap();
// Build and cache project selectors.
cmd.forge_fuse().args(["build"]).assert_success();

// Assert cast can decode custom error with local cache.
cmd.cast_fuse()
.args(["decode-error", "0x7191bc6200000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000D0004F"])
.assert_success()
.stdout_eq(str![[r#"
AnotherValueTooHigh(uint256,address)
101
0x0000000000000000000000000000000000D0004F

"#]]);
// Assert cast can decode event with local cache.
cmd.cast_fuse()
.args(["decode-event", "0xbd3699995dcc867b64dbb607be2c33be38df9134bef1178df13bfb9446e73104000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000dd00000004e"])
.assert_success()
.stdout_eq(str![[r#"
MyUniqueEventWithinLocalProject(uint256,address)
78
0x00000000000000000000000000000DD00000004e

"#]]);
});