diff --git a/crates/cheatcodes/src/config.rs b/crates/cheatcodes/src/config.rs index fa1ec6039cde..2279e24359a5 100644 --- a/crates/cheatcodes/src/config.rs +++ b/crates/cheatcodes/src/config.rs @@ -68,7 +68,7 @@ impl CheatsConfig { running_contract: Option, running_version: Option, ) -> Self { - let mut allowed_paths = vec![config.root.0.clone()]; + let mut allowed_paths = vec![config.root.clone()]; allowed_paths.extend(config.libs.clone()); allowed_paths.extend(config.allow_paths.clone()); @@ -88,8 +88,8 @@ impl CheatsConfig { rpc_endpoints, paths: config.project_paths(), fs_permissions: config.fs_permissions.clone().joined(config.root.as_ref()), - root: config.root.0.clone(), - broadcast: config.root.0.clone().join(&config.broadcast), + root: config.root.clone(), + broadcast: config.root.clone().join(&config.broadcast), allowed_paths, evm_opts, labels: config.labels.clone(), @@ -239,7 +239,7 @@ mod tests { fn config(root: &str, fs_permissions: FsPermissions) -> CheatsConfig { CheatsConfig::new( - &Config { root: PathBuf::from(root).into(), fs_permissions, ..Default::default() }, + &Config { root: root.into(), fs_permissions, ..Default::default() }, Default::default(), None, None, diff --git a/crates/cli/src/opts/build/core.rs b/crates/cli/src/opts/build/core.rs index d25018ae8df2..ff52cf0d627b 100644 --- a/crates/cli/src/opts/build/core.rs +++ b/crates/cli/src/opts/build/core.rs @@ -204,7 +204,7 @@ impl<'a> From<&'a CoreBuildArgs> for Config { // if `--config-path` is set we need to adjust the config's root path to the actual root // path for the project, otherwise it will the parent dir of the `--config-path` if args.project_paths.config_path.is_some() { - config.root = args.project_paths.project_root().into(); + config.root = args.project_paths.project_root(); } config } diff --git a/crates/cli/src/utils/mod.rs b/crates/cli/src/utils/mod.rs index 9f8475f63dab..6a2afe657d87 100644 --- a/crates/cli/src/utils/mod.rs +++ b/crates/cli/src/utils/mod.rs @@ -287,7 +287,7 @@ impl<'a> Git<'a> { #[inline] pub fn from_config(config: &'a Config) -> Self { - Self::new(config.root.0.as_path()) + Self::new(config.root.as_path()) } pub fn root_of(relative_to: &Path) -> Result { diff --git a/crates/config/src/lib.rs b/crates/config/src/lib.rs index b88f134d2cc2..f37c38345625 100644 --- a/crates/config/src/lib.rs +++ b/crates/config/src/lib.rs @@ -168,6 +168,14 @@ pub struct Config { /// See `profile`. #[serde(skip)] pub profiles: Vec, + + /// The root path where the config detection started from, [`Config::with_root`]. + // We're skipping serialization here, so it won't be included in the [`Config::to_string()`] + // representation, but will be deserialized from the `Figment` so that forge commands can + // override it. + #[serde(default = "root_default", skip_serializing)] + pub root: PathBuf, + /// path of the source contracts dir, like `src` or `contracts` pub src: PathBuf, /// path of the test dir @@ -466,13 +474,6 @@ pub struct Config { /// Soldeer custom configs pub soldeer: Option, - /// The root path where the config detection started from, [`Config::with_root`]. - // We're skipping serialization here, so it won't be included in the [`Config::to_string()`] - // representation, but will be deserialized from the `Figment` so that forge commands can - // override it. - #[serde(default, skip_serializing)] - pub root: RootPath, - /// Whether failed assertions should revert. /// /// Note that this only applies to native (cheatcode) assertions, invoked on Vm contract. @@ -679,7 +680,7 @@ impl Config { return Figment::from(self); } - let root = self.root.0.as_path(); + let root = self.root.as_path(); let profile = Self::selected_profile(); let mut figment = Figment::default().merge(DappHardhatDirProvider(root)); @@ -760,7 +761,7 @@ impl Config { /// This joins all relative paths with the current root and attempts to make them canonic #[must_use] pub fn canonic(self) -> Self { - let root = self.root.0.clone(); + let root = self.root.clone(); self.canonic_at(root) } @@ -1006,7 +1007,7 @@ impl Config { .set_no_artifacts(no_artifacts); if !self.skip.is_empty() { - let filter = SkipBuildFilters::new(self.skip.clone(), self.root.0.clone()); + let filter = SkipBuildFilters::new(self.skip.clone(), self.root.clone()); builder = builder.sparse_output(filter); } @@ -1057,7 +1058,7 @@ impl Config { fn ensure_solc(&self) -> Result, SolcError> { if self.eof { let (tx, rx) = mpsc::channel(); - let root = self.root.0.clone(); + let root = self.root.clone(); std::thread::spawn(move || { tx.send( Solc::new_with_args( @@ -1167,7 +1168,7 @@ impl Config { .artifacts(&self.out) .libs(self.libs.iter()) .remappings(self.get_all_remappings()) - .allowed_path(&self.root.0) + .allowed_path(&self.root) .allowed_paths(&self.libs) .allowed_paths(&self.allow_paths) .include_paths(&self.include_paths); @@ -1176,7 +1177,7 @@ impl Config { builder = builder.build_infos(build_info_path); } - builder.build_with_root(&self.root.0) + builder.build_with_root(&self.root) } /// Returns configuration for a compiler to use when setting up a [Project]. @@ -1428,7 +1429,7 @@ impl Config { /// Returns the remapping for the project's _test_ directory, but only if it exists pub fn get_test_dir_remapping(&self) -> Option { - if self.root.0.join(&self.test).exists() { + if self.root.join(&self.test).exists() { get_dir_remapping(&self.test) } else { None @@ -1437,7 +1438,7 @@ impl Config { /// Returns the remapping for the project's _script_ directory, but only if it exists pub fn get_script_dir_remapping(&self) -> Option { - if self.root.0.join(&self.script).exists() { + if self.root.join(&self.script).exists() { get_dir_remapping(&self.script) } else { None @@ -1615,7 +1616,7 @@ impl Config { let paths = ProjectPathsConfig::builder().build_with_root::<()>(root); let artifacts: PathBuf = paths.artifacts.file_name().unwrap().into(); Self { - root: paths.root.into(), + root: paths.root, src: paths.sources.file_name().unwrap().into(), out: artifacts.clone(), libs: paths.libraries.into_iter().map(|lib| lib.file_name().unwrap().into()).collect(), @@ -1707,7 +1708,7 @@ impl Config { pub fn update_libs(&self) -> eyre::Result<()> { self.update(|doc| { let profile = self.profile.as_str().as_str(); - let root = &self.root.0; + let root = &self.root; let libs: toml_edit::Value = self .libs .iter() @@ -1764,7 +1765,7 @@ impl Config { /// Returns the path to the `foundry.toml` of this `Config`. pub fn get_config_path(&self) -> PathBuf { - self.root.0.join(Self::FILE_NAME) + self.root.join(Self::FILE_NAME) } /// Returns the selected profile. @@ -2211,43 +2212,6 @@ pub(crate) mod from_opt_glob { } } -/// A helper wrapper around the root path used during Config detection -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] -#[serde(transparent)] -pub struct RootPath(pub PathBuf); - -impl Default for RootPath { - fn default() -> Self { - ".".into() - } -} - -impl> From

for RootPath { - fn from(p: P) -> Self { - Self(p.into()) - } -} - -impl AsRef for RootPath { - fn as_ref(&self) -> &Path { - &self.0 - } -} - -impl std::ops::Deref for RootPath { - type Target = PathBuf; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl std::ops::DerefMut for RootPath { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - /// Parses a config profile /// /// All `Profile` date is ignored by serde, however the `Config::to_string_pretty` includes it and @@ -2299,7 +2263,7 @@ impl Default for Config { profiles: vec![Self::DEFAULT_PROFILE], fs_permissions: FsPermissions::new([PathPermission::read("out")]), isolate: cfg!(feature = "isolate-by-default"), - root: Default::default(), + root: root_default(), src: "src".into(), test: "test".into(), script: "script".into(), @@ -3068,6 +3032,10 @@ fn canonic(path: impl Into) -> PathBuf { foundry_compilers::utils::canonicalize(&path).unwrap_or(path) } +fn root_default() -> PathBuf { + ".".into() +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/forge/bin/cmd/bind_json.rs b/crates/forge/bin/cmd/bind_json.rs index de7a5a7a71aa..d8a361134f50 100644 --- a/crates/forge/bin/cmd/bind_json.rs +++ b/crates/forge/bin/cmd/bind_json.rs @@ -64,7 +64,7 @@ impl BindJsonArgs { let config = self.try_load_config_emit_warnings()?; let project = config.create_project(false, true)?; - let target_path = config.root.0.join(self.out.as_ref().unwrap_or(&config.bind_json.out)); + let target_path = config.root.join(self.out.as_ref().unwrap_or(&config.bind_json.out)); let sources = project.paths.read_input_files()?; let graph = Graph::::resolve_sources(&project.paths, sources)?; diff --git a/crates/forge/bin/cmd/build.rs b/crates/forge/bin/cmd/build.rs index 3efe68db7722..7dea6b0068d0 100644 --- a/crates/forge/bin/cmd/build.rs +++ b/crates/forge/bin/cmd/build.rs @@ -137,7 +137,7 @@ impl BuildArgs { // directories as well as the `foundry.toml` configuration file. self.watch.watchexec_config(|| { let config = Config::from(self); - let foundry_toml: PathBuf = config.root.0.join(Config::FILE_NAME); + let foundry_toml: PathBuf = config.root.join(Config::FILE_NAME); [config.src, config.test, config.script, foundry_toml] }) } diff --git a/crates/forge/bin/cmd/doc/mod.rs b/crates/forge/bin/cmd/doc/mod.rs index ad61facf5c95..2fa996a04fe2 100644 --- a/crates/forge/bin/cmd/doc/mod.rs +++ b/crates/forge/bin/cmd/doc/mod.rs @@ -68,7 +68,7 @@ pub struct DocArgs { impl DocArgs { pub async fn run(self) -> Result<()> { let config = self.config()?; - let root = &config.root.0; + let root = &config.root; let project = config.project()?; let compiler = ProjectCompiler::new().quiet(true); let _output = compiler.compile(&project)?; diff --git a/crates/forge/bin/cmd/fmt.rs b/crates/forge/bin/cmd/fmt.rs index 49548e1b6c06..137e139e6b32 100644 --- a/crates/forge/bin/cmd/fmt.rs +++ b/crates/forge/bin/cmd/fmt.rs @@ -48,7 +48,7 @@ impl FmtArgs { let config = self.try_load_config_emit_warnings()?; // Expand ignore globs and canonicalize from the get go - let ignored = expand_globs(&config.root.0, config.fmt.ignore.iter())? + let ignored = expand_globs(&config.root, config.fmt.ignore.iter())? .iter() .flat_map(foundry_common::fs::canonicalize_path) .collect::>(); @@ -96,9 +96,7 @@ impl FmtArgs { let format = |source: String, path: Option<&Path>| -> Result<_> { let name = match path { - Some(path) => { - path.strip_prefix(&config.root.0).unwrap_or(path).display().to_string() - } + Some(path) => path.strip_prefix(&config.root).unwrap_or(path).display().to_string(), None => "stdin".to_string(), }; diff --git a/crates/forge/bin/cmd/test/mod.rs b/crates/forge/bin/cmd/test/mod.rs index 18ab08d6d152..e5a058c0d72d 100644 --- a/crates/forge/bin/cmd/test/mod.rs +++ b/crates/forge/bin/cmd/test/mod.rs @@ -559,7 +559,7 @@ impl TestArgs { if self.decode_internal.is_some() { let sources = - ContractSources::from_project_output(output, &config.root.0, Some(&libraries))?; + ContractSources::from_project_output(output, &config.root, Some(&libraries))?; builder = builder.with_debug_identifier(DebugTraceIdentifier::new(sources)); } let mut decoder = builder.build(); diff --git a/crates/forge/bin/cmd/update.rs b/crates/forge/bin/cmd/update.rs index 5ddc5460a78c..c61b03d7a089 100644 --- a/crates/forge/bin/cmd/update.rs +++ b/crates/forge/bin/cmd/update.rs @@ -52,7 +52,7 @@ impl UpdateArgs { /// Returns `(root, paths)` where `root` is the root of the Git repository and `paths` are the /// relative paths of the dependencies. pub fn dependencies_paths(deps: &[Dependency], config: &Config) -> Result<(PathBuf, Vec)> { - let git_root = Git::root_of(&config.root.0)?; + let git_root = Git::root_of(&config.root)?; let libs = config.install_lib_dir(); let mut paths = Vec::with_capacity(deps.len()); diff --git a/crates/forge/bin/cmd/watch.rs b/crates/forge/bin/cmd/watch.rs index 1f679d2c72c4..926aecdbadc2 100644 --- a/crates/forge/bin/cmd/watch.rs +++ b/crates/forge/bin/cmd/watch.rs @@ -268,7 +268,7 @@ pub async fn watch_test(args: TestArgs) -> Result<()> { args.watch.run_all; let last_test_files = Mutex::new(HashSet::::default()); - let project_root = config.root.0.to_string_lossy().into_owned(); + let project_root = config.root.to_string_lossy().into_owned(); let config = args.watch.watchexec_config_with_override( || [&config.test, &config.src], move |events, command| { diff --git a/crates/forge/tests/cli/config.rs b/crates/forge/tests/cli/config.rs index 9a7e61c6a4e3..02ff2fce8536 100644 --- a/crates/forge/tests/cli/config.rs +++ b/crates/forge/tests/cli/config.rs @@ -31,7 +31,7 @@ forgetest!(can_extract_config_values, |prj, cmd| { profile: Config::DEFAULT_PROFILE, // `profiles` is not serialized. profiles: vec![], - root: Default::default(), + root: ".".into(), src: "test-src".into(), test: "test-test".into(), script: "test-script".into(), diff --git a/crates/forge/tests/it/repros.rs b/crates/forge/tests/it/repros.rs index 69c3a0fb35f7..0e4adbbc281e 100644 --- a/crates/forge/tests/it/repros.rs +++ b/crates/forge/tests/it/repros.rs @@ -299,7 +299,7 @@ test_repro!(6538); // https://github.com/foundry-rs/foundry/issues/6554 test_repro!(6554; |config| { - let path = config.runner.config.root.0.join("out/default/Issue6554.t.sol"); + let path = config.runner.config.root.join("out/default/Issue6554.t.sol"); let mut prj_config = Config::clone(&config.runner.config); prj_config.fs_permissions.add(PathPermission::read_write(path)); diff --git a/crates/script/src/simulate.rs b/crates/script/src/simulate.rs index 0d7990591cd1..cf6aeb349436 100644 --- a/crates/script/src/simulate.rs +++ b/crates/script/src/simulate.rs @@ -427,7 +427,7 @@ impl FilledTransactionsState { )?) }; - let commit = get_commit_hash(&self.script_config.config.root.0); + let commit = get_commit_hash(&self.script_config.config.root); let libraries = self .build_data