From 3d2c3427e58053f33ea24cd9ddbe33c65c297b02 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Sat, 7 Feb 2026 19:04:45 +0000 Subject: [PATCH] [hermes] Isolate shadow crate from other artifacts Previously, we stored the shadow crate in `target/hermes_shadow_`. Now we store it in `target/hermes//shadow`. This allows us to store other build artifacts in `target/hermes/` but outside of `/shadow` to avoid polluting the shadow copy. gherrit-pr-id: G7f8abd90b628d02a6fdc01985535eef50509312e --- tools/hermes/src/resolve.rs | 20 ++++++++++++++------ tools/hermes/src/shadow.rs | 16 ++++++---------- tools/hermes/tests/integration.rs | 4 ++-- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/tools/hermes/src/resolve.rs b/tools/hermes/src/resolve.rs index ef0b1e8dad..6d7eff63ae 100644 --- a/tools/hermes/src/resolve.rs +++ b/tools/hermes/src/resolve.rs @@ -102,10 +102,17 @@ impl TryFrom<&TargetKind> for HermesTargetKind { pub struct Roots { pub workspace: PathBuf, pub cargo_target_dir: PathBuf, - pub shadow_root: PathBuf, + // E.g., `target/hermes/`. + hermes_run_root: PathBuf, pub roots: Vec<(PackageName, HermesTargetKind, PathBuf)>, } +impl Roots { + pub fn shadow_root(&self) -> PathBuf { + self.hermes_run_root.join("shadow") + } +} + /// Resolves all verification roots. /// /// Each entry represents a distinct compilation artifact to be verified. @@ -129,7 +136,7 @@ pub fn resolve_roots(args: &Args) -> Result { let mut roots = Roots { workspace: metadata.workspace_root.as_std_path().to_owned(), cargo_target_dir: metadata.target_directory.as_std_path().to_owned(), - shadow_root: resolve_shadow_path(&metadata), + hermes_run_root: resolve_run_root(&metadata), roots: Vec::new(), }; @@ -155,15 +162,16 @@ pub fn resolve_roots(args: &Args) -> Result { Ok(roots) } -fn resolve_shadow_path(metadata: &Metadata) -> PathBuf { - log::trace!("resolve_shadow_path"); +fn resolve_run_root(metadata: &Metadata) -> PathBuf { + log::trace!("resolve_run_root"); log::debug!("workspace_root: {:?}", metadata.workspace_root.as_std_path()); // NOTE: Automatically handles `CARGO_TARGET_DIR` env var. let target_dir = metadata.target_directory.as_std_path(); + let hermes_global = target_dir.join("hermes"); // Used by integration tests to ensure deterministic shadow dir names. if let Ok(name) = std::env::var("HERMES_TEST_SHADOW_NAME") { - return target_dir.join(name); + return hermes_global.join(name); } // Hash the path to the workspace root to avoid collisions between different @@ -175,7 +183,7 @@ fn resolve_shadow_path(metadata: &Metadata) -> PathBuf { hasher.finish() }; - target_dir.join(format!("hermes_shadow_{workspace_root_hash}")) + hermes_global.join(format!("{workspace_root_hash:x}")) } /// Resolves which packages to process based on workspace flags and CWD. diff --git a/tools/hermes/src/shadow.rs b/tools/hermes/src/shadow.rs index 2a9959ecef..7570794adc 100644 --- a/tools/hermes/src/shadow.rs +++ b/tools/hermes/src/shadow.rs @@ -18,10 +18,11 @@ use crate::{parse, resolve::Roots, transform}; /// 2. Creates symlinks for the remaining skeleton. pub fn build_shadow_crate(roots: &Roots) -> Result<()> { log::trace!("build_shadow_crate({:?})", roots); - if roots.shadow_root.exists() { - fs::remove_dir_all(&roots.shadow_root).context("Failed to clear shadow root")?; + let shadow_root = roots.shadow_root(); + if shadow_root.exists() { + fs::remove_dir_all(&shadow_root).context("Failed to clear shadow root")?; } - fs::create_dir_all(&roots.shadow_root).context("Failed to create shadow root")?; + fs::create_dir_all(&shadow_root).context("Failed to create shadow root")?; let visited_paths = DashSet::new(); let (err_tx, err_rx) = std::sync::mpsc::channel(); @@ -62,12 +63,7 @@ pub fn build_shadow_crate(roots: &Roots) -> Result<()> { let skip_paths: HashSet = visited_paths.into_iter().collect(); - create_symlink_skeleton( - &roots.workspace, - &roots.shadow_root, - &roots.cargo_target_dir, - &skip_paths, - )?; + create_symlink_skeleton(&roots.workspace, &shadow_root, &roots.cargo_target_dir, &skip_paths)?; Ok(()) } @@ -99,7 +95,7 @@ fn process_file_recursive<'a>( return; } }; - let dest_path = config.shadow_root.join(relative_path); + let dest_path = config.shadow_root().join(relative_path); let result = (|| -> Result> { if let Some(parent) = dest_path.parent() { diff --git a/tools/hermes/tests/integration.rs b/tools/hermes/tests/integration.rs index 93a50e91bd..b413374533 100644 --- a/tools/hermes/tests/integration.rs +++ b/tools/hermes/tests/integration.rs @@ -20,7 +20,7 @@ fn run_integration_test(path: &Path) -> datatest_stable::Result<()> { let mut cmd = assert_cmd::cargo_bin_cmd!("hermes"); cmd.env("CARGO_TARGET_DIR", sandbox_root.join("target")) .env_remove("RUSTFLAGS") - .env("HERMES_TEST_SHADOW_NAME", "hermes_shadow"); + .env("HERMES_TEST_SHADOW_NAME", "hermes_test_target"); // Tests can specify the cwd to invoke from. let cwd_file = test_case_root.join("cwd.txt"); @@ -64,7 +64,7 @@ fn run_integration_test(path: &Path) -> datatest_stable::Result<()> { } // Tests can specify the expected shadow crate content. - let actual_shadow = sandbox_root.join("target/hermes_shadow"); + let actual_shadow = sandbox_root.join("target/hermes/hermes_test_target/shadow"); let expected_shadow = test_case_root.join("expected"); if expected_shadow.exists() {