diff --git a/crates/cli/src/utils/cmd.rs b/crates/cli/src/utils/cmd.rs index 5f6d5b1074a92..1396d964db8aa 100644 --- a/crates/cli/src/utils/cmd.rs +++ b/crates/cli/src/utils/cmd.rs @@ -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() { diff --git a/crates/forge/src/cmd/build.rs b/crates/forge/src/cmd/build.rs index e64569206775b..43b4c89104407 100644 --- a/crates/forge/src/cmd/build.rs +++ b/crates/forge/src/cmd/build.rs @@ -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}, @@ -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())?)?; } diff --git a/crates/forge/src/cmd/selectors.rs b/crates/forge/src/cmd/selectors.rs index 5e858c9da9c58..e6ecdcbac7962 100644 --- a/crates/forge/src/cmd/selectors.rs +++ b/crates/forge/src/cmd/selectors.rs @@ -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`. @@ -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 { diff --git a/crates/forge/tests/cli/test_cmd.rs b/crates/forge/tests/cli/test_cmd.rs index af4b2aed7d0e7..0d33025249075 100644 --- a/crates/forge/tests/cli/test_cmd.rs +++ b/crates/forge/tests/cli/test_cmd.rs @@ -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 + +"#]]); +});