From f03c790baf9afc9ad9d1f1de97400827079c4a42 Mon Sep 17 00:00:00 2001 From: Eval Exec Date: Sat, 19 Sep 2026 05:51:00 -0400 Subject: [PATCH 1/2] test(infra): resolve the workspace root at runtime Binaries shipped through cargo nextest archive run on machines other than the one that compiled them, but the ubiquitous env!("CARGO_WORKSPACE_DIR") bakes the build machine's absolute path into every binary. One archive job landing on a runner pool with a different home (/home/ubuntu vs /home/runner) turned every downstream artifact write into EACCES and wiped out an entire CI run while looking exactly like a code regression. neomacs-infra and neovm-core's test_utils now expose the same three functions: cargo_workspace_root (the baked constant), nextest_workspace_root (the runtime NEXTEST_WORKSPACE_ROOT nextest exports, already adjusted by --workspace-remap), and workspace_root (the resolver call sites use -- runtime value when present, baked constant otherwise, so the fallback order is decided exactly once). The tui harness had already converged on this resolver; the remaining call sites migrate in a follow-up. --- crates/neomacs-infra/src/lib.rs | 27 ++++++++++++++++++++++++++ crates/neovm-core/src/test_utils.rs | 30 +++++++++++++++++++---------- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/crates/neomacs-infra/src/lib.rs b/crates/neomacs-infra/src/lib.rs index d06c03baef..24a4974455 100644 --- a/crates/neomacs-infra/src/lib.rs +++ b/crates/neomacs-infra/src/lib.rs @@ -12,6 +12,33 @@ pub mod display; use std::fs; use std::os::unix::fs::PermissionsExt; +/// The workspace root baked in at compile time. +/// +/// This is the **build** machine's path — for binaries shipped through +/// `cargo nextest archive`, wrong on every other runner. Only +/// [`workspace_root`] should read it; call sites never choose it directly. +pub fn cargo_workspace_root() -> PathBuf { + PathBuf::from(env!("CARGO_WORKSPACE_DIR")) +} + +/// The workspace root nextest exports at runtime: the live workspace on +/// the machine *running* the test, already adjusted by +/// `--workspace-remap`. `None` outside nextest (`cargo test`, plain +/// `cargo run`). +pub fn nextest_workspace_root() -> Option { + std::env::var_os("NEXTEST_WORKSPACE_ROOT").map(PathBuf::from) +} + +/// The workspace root of the machine *running* the test: nextest's +/// runtime value when present, the compile-time constant otherwise. +/// +/// One archive job landing on a runner pool with a different home +/// (`/home/ubuntu` vs `/home/runner`) turned every downstream artifact +/// write into EACCES and wiped out a whole CI run — which is why this +/// fallback order lives here, once, instead of at each call site. +pub fn workspace_root() -> PathBuf { + nextest_workspace_root().unwrap_or_else(cargo_workspace_root) +} use std::path::{Path, PathBuf}; use std::process::Command; diff --git a/crates/neovm-core/src/test_utils.rs b/crates/neovm-core/src/test_utils.rs index 7046aa9844..d8dbfff629 100644 --- a/crates/neovm-core/src/test_utils.rs +++ b/crates/neovm-core/src/test_utils.rs @@ -20,20 +20,30 @@ use std::path::PathBuf; /// many existing call sites in this crate's test files. Tests never /// write to a log file regardless of `NEOMACS_LOG_TO_FILE` — output is /// always routed through the test harness's writer. -/// -/// # Usage -/// Call at the start of any test that needs tracing: -/// ```rust,ignore -/// #[test] -/// fn my_test() { -/// crate::test_utils::init_test_tracing(); -/// // ... test code ... -/// } -/// ``` pub fn init_test_tracing() { crate::logging::init_for_tests(); } +/// The workspace root baked in at compile time — the **build** machine's +/// path, wrong for archive-shipped binaries on every other runner. Only +/// [`workspace_root`] reads it. +pub fn cargo_workspace_root() -> PathBuf { + PathBuf::from(env!("CARGO_WORKSPACE_DIR")) +} + +/// The workspace root nextest exports at runtime: the live workspace on +/// the running machine. `None` outside nextest. +pub fn nextest_workspace_root() -> Option { + std::env::var_os("NEXTEST_WORKSPACE_ROOT").map(PathBuf::from) +} + +/// The workspace root of the machine *running* the test: nextest's runtime +/// value when present, the compile-time constant otherwise. The fallback +/// order lives here once, so no call site can get it wrong. +pub fn workspace_root() -> PathBuf { + nextest_workspace_root().unwrap_or_else(cargo_workspace_root) +} + /// Load a small GNU Lisp runtime that is sufficient for tests that need /// `byte-run`, backquote expansion, and the basic `subr.el` support layer, /// without paying for full `loadup.el` startup. From cf27717b7e1377a6e604b82459766f5263966bae Mon Sep 17 00:00:00 2001 From: Eval Exec Date: Sat, 19 Sep 2026 06:12:35 -0400 Subject: [PATCH 2/2] test: resolve the workspace root at runtime across the archive-shipped crates Follow-through on the resolver: every test that runs from a cargo nextest archive now asks for the workspace of the machine it is running on. neovm-core tests call crate::test_utils::workspace_root, the gui/melpa/neomacs/display/renderer suites call neomacs_infra::workspace_root, perf grows the same pub helper, and xtask's tests reuse its own repository_root. Left baking on purpose: include_bytes!/include_str! (bytes embedded at compile time -- no runtime path exists), the production runtime-root candidates in load/mod.rs and gui_chrome.rs (a fallback chain whose compile-time member is genuinely the build machine, correct for a binary that ships with its checkout), and parity-reference's manifest lookup (a CLI run on the build tree, never archive-shipped). Verified: neovm-core/infra/test-fonts/melpa-support subsets (690), gui harness contracts, and the present contract on Vulkan all green. --- Cargo.lock | 4 ++ crates/neomacs-display-runtime/Cargo.toml | 1 + .../src/macos_bundle_runtime_test.rs | 2 +- .../tests/desktop_font_startup.rs | 2 +- .../tests/harness_contract.rs | 8 +-- .../neomacs-gui-tests/tests/native_display.rs | 2 +- .../tests/native_frame_focus.rs | 2 +- .../neomacs-gui-tests/tests/native_menus.rs | 2 +- .../tests/native_scrolling.rs | 2 +- .../tests/present_contract.rs | 2 +- .../neomacs-gui-tests/tests/real_gui_smoke.rs | 2 +- .../tests/resize_presentation.rs | 2 +- .../tests/startup_failure.rs | 6 +- crates/neomacs-melpa-test-support/src/lib.rs | 2 +- crates/neomacs-melpa-tests/Cargo.toml | 1 + .../src/parity_tests/tide/mod.rs | 2 +- .../neomacs-perf/src/build_provenance_test.rs | 2 +- crates/neomacs-perf/src/harness_test.rs | 42 ++++++------- crates/neomacs-perf/src/lib.rs | 9 +++ crates/neomacs-perf/src/profile_test.rs | 22 +++---- crates/neomacs-perf/src/suite_test.rs | 2 +- crates/neomacs-renderer-wgpu/Cargo.toml | 1 + .../src/image_cache_test.rs | 16 +++-- crates/neomacs-test-fonts/src/lib.rs | 12 ++-- crates/neomacs/Cargo.toml | 1 + crates/neomacs/src/main_test.rs | 6 +- crates/neomacs/tests/common/mod.rs | 2 +- crates/neomacs/tests/neomacsclient_cli.rs | 12 ++-- .../commands/interactive/tests/mod.rs | 16 ++--- .../emacs_core/display/display/tests/mod.rs | 5 +- .../src/emacs_core/display/font/tests/mod.rs | 5 +- .../display/window_cmds/tests/mod.rs | 5 +- .../emacs_core/editing/indent/tests/mod.rs | 4 +- .../editing/navigation/tests/mod.rs | 2 +- .../src/emacs_core/editing/rect/tests/mod.rs | 5 +- .../src/emacs_core/lisp/autoload/tests/mod.rs | 2 +- .../src/emacs_core/lisp/doc/tests/mod.rs | 8 ++- .../src/emacs_core/lisp/load/mod.rs | 2 +- .../src/emacs_core/lisp/load/tests/mod.rs | 62 +++++++++++-------- .../lisp/load/tests/stale_bytecode.rs | 4 +- .../platform/linux/tests/worker.rs | 3 +- .../builtins/file_notify/tests/linux.rs | 3 +- .../native/builtins/file_notify/tests/mod.rs | 3 +- .../file_notify/tests/native_runtime.rs | 3 +- .../lisp/native/builtins/tests/mod.rs | 5 +- .../src/emacs_core/runtime/eval/tests/mod.rs | 5 +- .../symbol/tests/buffer_local_global_read.rs | 2 +- .../callproc/tests/working_dir_infile.rs | 2 +- .../system/fileio/tests/backup_test.rs | 5 +- .../src/emacs_core/system/fileio/tests/mod.rs | 3 +- .../system/fileio/tests/windows_test.rs | 3 +- .../emacs_core/system/process/tests/mod.rs | 21 +++++-- .../src/emacs_core/system/profiler/mod.rs | 3 +- .../src/emacs_core/system/timer/tests/mod.rs | 2 +- .../emacs_core/system/tls/tests/runtime.rs | 4 +- .../tests/build_support/compile_main_rule.rs | 2 +- .../tests/build_support/generated_lisp.rs | 2 +- .../emacs_core/text/chartable/tests/mod.rs | 8 ++- .../src/emacs_core/text/regex/tests/mod.rs | 5 +- crates/neovm-core/tests/common/mod.rs | 11 +++- .../neovm-core/tests/compat_face_surface.rs | 2 +- 61 files changed, 229 insertions(+), 157 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 270f574fe8..6fcd8c0d3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3702,6 +3702,7 @@ dependencies = [ "neomacs-diagnostics", "neomacs-display-protocol", "neomacs-display-runtime", + "neomacs-infra", "neomacs-layout-engine", "neomacs-terminfo", "neomacs-video-model", @@ -3777,6 +3778,7 @@ dependencies = [ "image", "libc", "neomacs-display-protocol", + "neomacs-infra", "neomacs-layout-engine", "neomacs-renderer-wgpu", "neomacs-video", @@ -3906,6 +3908,7 @@ dependencies = [ "fs4", "libc", "neomacs-gui-tests", + "neomacs-infra", "neomacs-melpa-test-support", "neomacs-test-oracle", "neomacs-tui-tests", @@ -3955,6 +3958,7 @@ dependencies = [ "naga", "neomacs-display-protocol", "neomacs-font-materializer", + "neomacs-infra", "neomacs-layout-engine", "neomacs-test-fonts", "neomacs-video", diff --git a/crates/neomacs-display-runtime/Cargo.toml b/crates/neomacs-display-runtime/Cargo.toml index 52dc6e98c1..f9b9adcbc2 100644 --- a/crates/neomacs-display-runtime/Cargo.toml +++ b/crates/neomacs-display-runtime/Cargo.toml @@ -65,6 +65,7 @@ parking_lot = { workspace = true, optional = true } portable-pty = { workspace = true, optional = true } [dev-dependencies] +neomacs-infra.workspace = true tempfile.workspace = true [features] diff --git a/crates/neomacs-display-runtime/src/macos_bundle_runtime_test.rs b/crates/neomacs-display-runtime/src/macos_bundle_runtime_test.rs index e4717c15e1..3075375f2b 100644 --- a/crates/neomacs-display-runtime/src/macos_bundle_runtime_test.rs +++ b/crates/neomacs-display-runtime/src/macos_bundle_runtime_test.rs @@ -2,7 +2,7 @@ use super::MacOsBundleRuntime; use std::fs; fn workspace_tempdir() -> tempfile::TempDir { - let workspace_tmp = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let workspace_tmp = neomacs_infra::workspace_root().as_path().join("tmp"); fs::create_dir_all(&workspace_tmp).expect("workspace tmp directory"); tempfile::Builder::new() .prefix("macos-bundle-runtime.") diff --git a/crates/neomacs-gui-tests/tests/desktop_font_startup.rs b/crates/neomacs-gui-tests/tests/desktop_font_startup.rs index aa6856523f..5713137d23 100644 --- a/crates/neomacs-gui-tests/tests/desktop_font_startup.rs +++ b/crates/neomacs-gui-tests/tests/desktop_font_startup.rs @@ -199,7 +199,7 @@ fn check_fixture_with_font( desktop: WestonDesktop, font: Option<&str>, ) -> GuiRunResult { - let root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let root = neomacs_infra::workspace_root(); let artifacts = root.join("target/neomacs-gui-tests").join(scenario); let receipt = artifacts.join("presentation.sexp"); match fs::remove_file(&receipt) { diff --git a/crates/neomacs-gui-tests/tests/harness_contract.rs b/crates/neomacs-gui-tests/tests/harness_contract.rs index 0de92647f9..f1df87d8da 100644 --- a/crates/neomacs-gui-tests/tests/harness_contract.rs +++ b/crates/neomacs-gui-tests/tests/harness_contract.rs @@ -238,7 +238,7 @@ fn svg_package_defaults_are_checkout_relative_and_preserve_explicit_overrides() #[cfg(target_os = "linux")] #[test] fn wayland_session_owns_runtime_below_long_artifact_root() { - let root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")) + let root = neomacs_infra::workspace_root() .join("target/neomacs-gui-tests") .join(format!( "long-wayland-{}-{}", @@ -271,7 +271,7 @@ fn wayland_session_owns_runtime_below_long_artifact_root() { #[cfg(target_os = "linux")] #[test] fn x11_session_owns_authenticated_tcp_display_below_artifact_root() { - let workspace = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let workspace = neomacs_infra::workspace_root(); let root = workspace.join(format!( "target/neomacs-gui-tests/xvfb-contract-{}", std::process::id() @@ -439,7 +439,7 @@ fn test_plan_can_drive_an_init_directory_startup_surface() { #[test] fn test_plan_materializes_json_manifest_artifact() { - let workspace_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let workspace_root = neomacs_infra::workspace_root(); let artifact_root = workspace_root.join("target/neomacs-gui-tests"); let artifacts = GuiArtifactSet::new(&artifact_root, GuiBackend::LinuxWayland, "startup-smoke"); let _ = std::fs::remove_file(&artifacts.json); @@ -693,7 +693,7 @@ fn run_with_runner_records_frame_snapshot_artifacts() { } fn workspace_root() -> PathBuf { - PathBuf::from(env!("CARGO_WORKSPACE_DIR")) + neomacs_infra::workspace_root() } struct FakeRunner { diff --git a/crates/neomacs-gui-tests/tests/native_display.rs b/crates/neomacs-gui-tests/tests/native_display.rs index ea2ecf962a..c89cb67e46 100644 --- a/crates/neomacs-gui-tests/tests/native_display.rs +++ b/crates/neomacs-gui-tests/tests/native_display.rs @@ -61,7 +61,7 @@ fn native_resource_font_drives_first_window() { } fn run_native_contract(name: &str, fixture: &str, resources: bool) -> GuiRunResult { - let root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let root = neomacs_infra::workspace_root(); let backend = if cfg!(target_os = "macos") { GuiBackend::Macos } else if cfg!(windows) { diff --git a/crates/neomacs-gui-tests/tests/native_frame_focus.rs b/crates/neomacs-gui-tests/tests/native_frame_focus.rs index a2f53259a7..79c5d3d609 100644 --- a/crates/neomacs-gui-tests/tests/native_frame_focus.rs +++ b/crates/neomacs-gui-tests/tests/native_frame_focus.rs @@ -29,7 +29,7 @@ fn native_x11_focus_routes_typing_to_the_focused_frame() { } Some(other) => panic!("unsupported NEOMACS_GUI_TEST_BACKEND={other:?}"), } - let root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let root = neomacs_infra::workspace_root(); let artifacts = root.join(format!( "target/neomacs-gui-tests/native-frame-focus-{}", std::process::id() diff --git a/crates/neomacs-gui-tests/tests/native_menus.rs b/crates/neomacs-gui-tests/tests/native_menus.rs index eeef3428d6..a1d884f8ed 100644 --- a/crates/neomacs-gui-tests/tests/native_menus.rs +++ b/crates/neomacs-gui-tests/tests/native_menus.rs @@ -31,7 +31,7 @@ struct Ready { #[test] fn native_submenu_hover_keeps_editor_and_compositor_alive() { - let root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let root = neomacs_infra::workspace_root(); let artifacts = root.join(format!( "target/neomacs-gui-tests/native-submenu-{}-{}", std::process::id(), diff --git a/crates/neomacs-gui-tests/tests/native_scrolling.rs b/crates/neomacs-gui-tests/tests/native_scrolling.rs index 4fcbe32799..357ad1d7c7 100644 --- a/crates/neomacs-gui-tests/tests/native_scrolling.rs +++ b/crates/neomacs-gui-tests/tests/native_scrolling.rs @@ -85,7 +85,7 @@ enum ScrollTarget { } fn run_native_scroll(kind: ScrollKind, target: ScrollTarget) { - let root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let root = neomacs_infra::workspace_root(); let artifact_root = root.join("target/neomacs-gui-tests"); fs::create_dir_all(&artifact_root).unwrap(); let artifacts = artifact_root.join(format!( diff --git a/crates/neomacs-gui-tests/tests/present_contract.rs b/crates/neomacs-gui-tests/tests/present_contract.rs index eedeaa0de8..f140759ed4 100644 --- a/crates/neomacs-gui-tests/tests/present_contract.rs +++ b/crates/neomacs-gui-tests/tests/present_contract.rs @@ -250,7 +250,7 @@ impl ContractApp { #[test] fn resize_then_present_shows_the_new_frame_on_the_current_backend() { let backend_label = std::env::var("WGPU_BACKEND").unwrap_or_else(|_| "default".to_owned()); - let artifact_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("target/neomacs-gui-tests"); + let artifact_root = neomacs_infra::workspace_root().join("target/neomacs-gui-tests"); std::fs::create_dir_all(&artifact_root).unwrap(); let artifacts = artifact_root.join(format!("present-contract-{backend_label}")); std::fs::create_dir_all(&artifacts).unwrap(); diff --git a/crates/neomacs-gui-tests/tests/real_gui_smoke.rs b/crates/neomacs-gui-tests/tests/real_gui_smoke.rs index df0fd2bd5d..18e38b5a47 100644 --- a/crates/neomacs-gui-tests/tests/real_gui_smoke.rs +++ b/crates/neomacs-gui-tests/tests/real_gui_smoke.rs @@ -589,7 +589,7 @@ fn requested_backend() -> Option { } fn workspace_root() -> PathBuf { - PathBuf::from(env!("CARGO_WORKSPACE_DIR")) + neomacs_infra::workspace_root() } fn neomacs_binary(workspace_root: &std::path::Path) -> PathBuf { diff --git a/crates/neomacs-gui-tests/tests/resize_presentation.rs b/crates/neomacs-gui-tests/tests/resize_presentation.rs index e1e3034c06..6c66c23479 100644 --- a/crates/neomacs-gui-tests/tests/resize_presentation.rs +++ b/crates/neomacs-gui-tests/tests/resize_presentation.rs @@ -270,7 +270,7 @@ fn x11_backend_requested() -> bool { } fn workspace_root() -> PathBuf { - PathBuf::from(env!("CARGO_WORKSPACE_DIR")) + neomacs_infra::workspace_root() } fn neomacs_binary(workspace_root: &Path) -> PathBuf { diff --git a/crates/neomacs-gui-tests/tests/startup_failure.rs b/crates/neomacs-gui-tests/tests/startup_failure.rs index f19539f2cc..d74a188ef9 100644 --- a/crates/neomacs-gui-tests/tests/startup_failure.rs +++ b/crates/neomacs-gui-tests/tests/startup_failure.rs @@ -41,7 +41,7 @@ fn check_pending_gpu(action: GpuStartupAction) { time::Instant, }; - let root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let root = neomacs_infra::workspace_root(); let artifacts = root.join("target/neomacs-gui-tests").join(format!( "startup-pending-gpu-{}-{}", action.as_ref(), @@ -298,7 +298,7 @@ enum PendingFontAction { fn run_with_pending_font(action: PendingFontAction) -> neomacs_gui_tests::GuiRunResult { use std::{io::Write, os::unix::fs::OpenOptionsExt, process::Command, time::Instant}; - let root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let root = neomacs_infra::workspace_root(); let artifacts = root.join("target/neomacs-gui-tests"); fs::create_dir_all(&artifacts).unwrap(); let scenario = match action { @@ -410,7 +410,7 @@ fn successful_exit_during_lisp_startup_remains_successful() { } fn check_lisp_startup_exit_status(status: i32) { - let root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let root = neomacs_infra::workspace_root(); let artifacts = root.join("target/neomacs-gui-tests"); let backend = GuiBackend::LinuxWayland; let session = DisplayHarness::for_backend(backend) diff --git a/crates/neomacs-melpa-test-support/src/lib.rs b/crates/neomacs-melpa-test-support/src/lib.rs index 0231701757..9816c57fec 100644 --- a/crates/neomacs-melpa-test-support/src/lib.rs +++ b/crates/neomacs-melpa-test-support/src/lib.rs @@ -56,7 +56,7 @@ pub fn workspace_root() -> PathBuf { if let Some(root) = std::env::var_os("NEXTEST_WORKSPACE_ROOT") { return PathBuf::from(root); } - Path::new(env!("CARGO_WORKSPACE_DIR")).to_path_buf() + PathBuf::from(env!("CARGO_WORKSPACE_DIR")) } /// Per-scenario filesystem and subprocess isolation. diff --git a/crates/neomacs-melpa-tests/Cargo.toml b/crates/neomacs-melpa-tests/Cargo.toml index 7c6c42aacf..7b4e7ff587 100644 --- a/crates/neomacs-melpa-tests/Cargo.toml +++ b/crates/neomacs-melpa-tests/Cargo.toml @@ -25,6 +25,7 @@ libc.workspace = true windows-sys = { workspace = true, features = ["Win32_System_Diagnostics_ToolHelp", "Win32_System_JobObjects"] } [dev-dependencies] +neomacs-infra.workspace = true expect-test.workspace = true neomacs-melpa-test-support = { workspace = true, features = ["tui"] } diff --git a/crates/neomacs-melpa-tests/src/parity_tests/tide/mod.rs b/crates/neomacs-melpa-tests/src/parity_tests/tide/mod.rs index f308366363..35b4e8a5e4 100644 --- a/crates/neomacs-melpa-tests/src/parity_tests/tide/mod.rs +++ b/crates/neomacs-melpa-tests/src/parity_tests/tide/mod.rs @@ -6697,7 +6697,7 @@ fn assert_typed_contracts() { 2, ); - let workspace = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let workspace = neomacs_melpa_test_support::workspace_root(); assert!(OwnedAbsoluteRoot::new("relative", workspace.join("tmp/owned")).is_err()); assert!(OwnedAbsoluteRoot::new(&workspace, "/tmp/ambient").is_err()); assert!(OwnedAbsoluteRoot::new(&workspace, workspace.join("tmp")).is_err()); diff --git a/crates/neomacs-perf/src/build_provenance_test.rs b/crates/neomacs-perf/src/build_provenance_test.rs index 1163d4c7bb..f77abccf40 100644 --- a/crates/neomacs-perf/src/build_provenance_test.rs +++ b/crates/neomacs-perf/src/build_provenance_test.rs @@ -18,7 +18,7 @@ fn git(directory: &std::path::Path, arguments: &[&str]) { #[test] fn git_metadata_watch_paths_are_absolute_and_worktree_aware() { - let workspace_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let workspace_tmp = crate::workspace_root().join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let scratch = tempfile::Builder::new() .prefix("neomacs-perf-build-provenance-") diff --git a/crates/neomacs-perf/src/harness_test.rs b/crates/neomacs-perf/src/harness_test.rs index facfd99c02..e32f6ac876 100644 --- a/crates/neomacs-perf/src/harness_test.rs +++ b/crates/neomacs-perf/src/harness_test.rs @@ -11,7 +11,7 @@ use super::{ #[test] fn invalid_scenario_output_is_persisted_but_never_accepted_as_a_sample() { - let workspace_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let workspace_tmp = crate::workspace_root().join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let workspace = tempfile::Builder::new() .prefix("neomacs-perf-test-") @@ -65,7 +65,7 @@ fn invalid_scenario_output_is_persisted_but_never_accepted_as_a_sample() { #[test] fn fixture_overlay_count_is_checked_against_the_harness_oracle() { - let workspace_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let workspace_tmp = crate::workspace_root().join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let workspace = tempfile::Builder::new() .prefix("neomacs-perf-oracle-test-") @@ -114,7 +114,7 @@ fn fixture_overlay_count_is_checked_against_the_harness_oracle() { #[test] fn mx_tab_result_is_valid_only_when_the_real_completion_window_lifecycle_completed() { - let workspace_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let workspace_tmp = crate::workspace_root().join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let workspace = tempfile::Builder::new() .prefix("neomacs-perf-mx-tab-result-") @@ -170,7 +170,7 @@ fn mx_tab_result_is_valid_only_when_the_real_completion_window_lifecycle_complet #[test] fn mx_tab_result_cannot_treat_a_missing_completion_window_as_a_fast_sample() { - let workspace_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let workspace_tmp = crate::workspace_root().join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let workspace = tempfile::Builder::new() .prefix("neomacs-perf-mx-tab-mismatch-") @@ -228,7 +228,7 @@ fn mx_tab_result_cannot_treat_a_missing_completion_window_as_a_fast_sample() { #[test] fn bytecode_call_loop_accepts_only_the_full_interpreted_call_count() { - let workspace_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let workspace_tmp = crate::workspace_root().join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let workspace = tempfile::Builder::new() .prefix("neomacs-perf-bytecode-call-result-") @@ -276,7 +276,7 @@ fn bytecode_call_loop_accepts_only_the_full_interpreted_call_count() { #[test] fn bytecode_call_loop_rejects_a_short_or_wrong_result() { - let workspace_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let workspace_tmp = crate::workspace_root().join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let workspace = tempfile::Builder::new() .prefix("neomacs-perf-bytecode-call-mismatch-") @@ -325,7 +325,7 @@ fn bytecode_call_loop_rejects_a_short_or_wrong_result() { #[test] fn scenario_result_requires_every_schema_field() { - let workspace_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let workspace_tmp = crate::workspace_root().join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let workspace = tempfile::Builder::new() .prefix("neomacs-perf-schema-test-") @@ -364,7 +364,7 @@ fn scenario_result_requires_every_schema_field() { #[test] fn scenario_result_rejects_a_success_status_with_an_error() { - let workspace_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let workspace_tmp = crate::workspace_root().join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let workspace = tempfile::Builder::new() .prefix("neomacs-perf-outcome-test-") @@ -408,7 +408,7 @@ fn scenario_result_rejects_a_success_status_with_an_error() { #[test] fn editing_simulation_requires_every_promoted_phase_measurement() { - let workspace_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let workspace_root = crate::workspace_root(); let workspace_tmp = workspace_root.join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let scratch = tempfile::Builder::new() @@ -465,7 +465,7 @@ fn editing_simulation_requires_every_promoted_phase_measurement() { #[test] fn sustained_editing_reports_insert_and_delete_as_two_edits() { - let workspace_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let workspace_root = crate::workspace_root(); let workspace_tmp = workspace_root.join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let scratch = tempfile::Builder::new() @@ -534,7 +534,7 @@ fn sustained_editing_reports_insert_and_delete_as_two_edits() { #[test] fn gui_input_latency_counts_keystrokes_over_the_one_millisecond_budget() { - let workspace_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let workspace_root = crate::workspace_root(); let workspace_tmp = workspace_root.join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let scratch = tempfile::Builder::new() @@ -599,7 +599,7 @@ fn gui_input_latency_counts_keystrokes_over_the_one_millisecond_budget() { #[test] fn sustained_native_video_promotes_pacing_gpu_pool_and_memory_metrics() { - let workspace_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let workspace_root = crate::workspace_root(); let workspace_tmp = workspace_root.join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let scratch = tempfile::Builder::new() @@ -711,7 +711,7 @@ fn sustained_native_video_promotes_pacing_gpu_pool_and_memory_metrics() { #[test] fn sustained_native_video_rejects_a_cpu_upload_fallback() { - let workspace_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let workspace_root = crate::workspace_root(); let workspace_tmp = workspace_root.join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let scratch = tempfile::Builder::new() @@ -764,7 +764,7 @@ fn sustained_native_video_rejects_a_cpu_upload_fallback() { #[test] fn run_persists_a_missing_editor_as_an_infrastructure_failure() { - let workspace_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let workspace_tmp = crate::workspace_root().join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let workspace = tempfile::Builder::new() .prefix("neomacs-perf-run-test-") @@ -796,7 +796,7 @@ fn run_persists_a_missing_editor_as_an_infrastructure_failure() { #[test] fn non_video_scenario_rejects_a_video_file_before_launching_editor() { - let workspace_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let workspace_tmp = crate::workspace_root().join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let workspace = tempfile::Builder::new() .prefix("neomacs-perf-input-contract-test-") @@ -821,7 +821,7 @@ fn non_video_scenario_rejects_a_video_file_before_launching_editor() { #[cfg(unix)] #[test] fn pty_runner_publishes_the_raw_terminal_byte_stream() { - let workspace_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let workspace_root = crate::workspace_root(); let scratch_root = workspace_root.join("tmp"); fs::create_dir_all(&scratch_root).expect("create workspace-local test scratch root"); let scratch = tempfile::Builder::new() @@ -860,7 +860,7 @@ fn pty_runner_publishes_the_raw_terminal_byte_stream() { #[cfg(unix)] #[test] fn pty_runner_allows_a_profile_wrapper_to_finalize_after_the_sentinel() { - let workspace_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let workspace_root = crate::workspace_root(); let scratch_root = workspace_root.join("tmp"); fs::create_dir_all(&scratch_root).expect("create workspace-local test scratch root"); let scratch = tempfile::Builder::new() @@ -948,7 +948,7 @@ fn benchmark_environment_does_not_inherit_logging_or_allocator_controls() { fn editor_provenance_uses_content_and_pdump_fingerprints() { use std::os::unix::fs::PermissionsExt; - let workspace_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let workspace_root = crate::workspace_root(); let scratch = tempfile::Builder::new() .prefix("neomacs-perf-editor-provenance-") .tempdir_in(workspace_root.join("tmp")) @@ -1049,7 +1049,7 @@ fn benchmark_environment_forwards_the_allowlist_and_jit_knobs_only() { #[test] fn org_journal_open_result_is_valid_when_every_journal_invariant_holds() { - let workspace_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let workspace_tmp = crate::workspace_root().join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let workspace = tempfile::Builder::new() .prefix("neomacs-perf-org-journal-") @@ -1109,7 +1109,7 @@ fn org_journal_open_result_is_valid_when_every_journal_invariant_holds() { #[test] fn org_journal_open_rejects_a_journal_that_never_created_overlays_or_an_entry() { - let workspace_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let workspace_tmp = crate::workspace_root().join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let workspace = tempfile::Builder::new() .prefix("neomacs-perf-org-journal-reject-") @@ -1173,7 +1173,7 @@ fn org_journal_open_rejects_a_journal_that_never_created_overlays_or_an_entry() #[test] fn org_journal_open_relaxes_creation_invariants_for_an_external_journal() { - let workspace_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let workspace_tmp = crate::workspace_root().join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace-local test scratch root"); let workspace = tempfile::Builder::new() .prefix("neomacs-perf-org-journal-external-") diff --git a/crates/neomacs-perf/src/lib.rs b/crates/neomacs-perf/src/lib.rs index 5fd578805e..616d4236dd 100644 --- a/crates/neomacs-perf/src/lib.rs +++ b/crates/neomacs-perf/src/lib.rs @@ -60,6 +60,15 @@ pub use suite::{ SuiteScenario, SuiteScenarioResult, SuiteVerdict, }; +/// The workspace root of the machine running this code: nextest's runtime +/// `NEXTEST_WORKSPACE_ROOT` when present, the baked compile-time constant +/// otherwise (see neomacs-infra::workspace_root). +pub fn workspace_root() -> std::path::PathBuf { + std::env::var_os("NEXTEST_WORKSPACE_ROOT") + .map(std::path::PathBuf::from) + .unwrap_or_else(|| std::path::PathBuf::from(env!("CARGO_WORKSPACE_DIR"))) +} + #[cfg(test)] mod architecture_test; #[cfg(test)] diff --git a/crates/neomacs-perf/src/profile_test.rs b/crates/neomacs-perf/src/profile_test.rs index 4d20291425..0cfebeebf2 100644 --- a/crates/neomacs-perf/src/profile_test.rs +++ b/crates/neomacs-perf/src/profile_test.rs @@ -61,7 +61,7 @@ fn captured_profile_artifact_links_raw_data_report_and_scenario_run_without_timi fn edit_loop_gate_forwards_only_acknowledged_enable_disable_sequence() { let scratch = tempfile::Builder::new() .prefix("neomacs-perf-gate-sequence-") - .tempdir_in(PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp")) + .tempdir_in(crate::workspace_root().join("tmp")) .expect("create workspace-local profile gate directory"); let mut gate = ProfileGate::start(scratch.path(), Duration::from_secs(2)).expect("start profile gate"); @@ -119,7 +119,7 @@ fn edit_loop_gate_forwards_only_acknowledged_enable_disable_sequence() { fn edit_loop_gate_rejects_a_command_after_disable() { let scratch = tempfile::Builder::new() .prefix("neomacs-perf-gate-after-disable-") - .tempdir_in(PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp")) + .tempdir_in(crate::workspace_root().join("tmp")) .expect("create workspace-local profile gate directory"); let mut gate = ProfileGate::start(scratch.path(), Duration::from_secs(2)).expect("start profile gate"); @@ -177,7 +177,7 @@ fn edit_loop_gate_rejects_a_command_after_disable() { fn edit_loop_gate_rejects_disable_before_enable() { let scratch = tempfile::Builder::new() .prefix("neomacs-perf-gate-order-") - .tempdir_in(PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp")) + .tempdir_in(crate::workspace_root().join("tmp")) .expect("create workspace-local profile gate directory"); let mut gate = ProfileGate::start(scratch.path(), Duration::from_secs(2)).expect("start profile gate"); @@ -207,7 +207,7 @@ fn edit_loop_gate_rejects_malformed_and_incomplete_commands() { ] { let scratch = tempfile::Builder::new() .prefix("neomacs-perf-gate-malformed-") - .tempdir_in(PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp")) + .tempdir_in(crate::workspace_root().join("tmp")) .expect("create workspace-local profile gate directory"); let mut gate = ProfileGate::start(scratch.path(), Duration::from_secs(2)).expect("start profile gate"); @@ -234,7 +234,7 @@ fn edit_loop_gate_rejects_malformed_and_incomplete_commands() { fn edit_loop_gate_rejects_missing_perf_acknowledgement() { let scratch = tempfile::Builder::new() .prefix("neomacs-perf-gate-missing-ack-") - .tempdir_in(PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp")) + .tempdir_in(crate::workspace_root().join("tmp")) .expect("create workspace-local profile gate directory"); let mut gate = ProfileGate::start(scratch.path(), Duration::from_millis(150)).expect("start profile gate"); @@ -258,7 +258,7 @@ fn edit_loop_gate_rejects_missing_perf_acknowledgement() { fn edit_loop_gate_rejects_disconnect_before_disable() { let scratch = tempfile::Builder::new() .prefix("neomacs-perf-gate-incomplete-sequence-") - .tempdir_in(PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp")) + .tempdir_in(crate::workspace_root().join("tmp")) .expect("create workspace-local profile gate directory"); let mut gate = ProfileGate::start(scratch.path(), Duration::from_secs(2)).expect("start profile gate"); @@ -301,7 +301,7 @@ fn edit_loop_gate_rejects_disconnect_before_disable() { fn malformed_perf_data_is_rejected_by_the_binary_parser() { let scratch = tempfile::Builder::new() .prefix("neomacs-perf-malformed-data-") - .tempdir_in(PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp")) + .tempdir_in(crate::workspace_root().join("tmp")) .expect("create workspace-local profile scratch directory"); let perf_data = scratch.path().join("perf.data"); fs::write(&perf_data, b"not perf data").expect("write malformed profile"); @@ -312,7 +312,7 @@ fn malformed_perf_data_is_rejected_by_the_binary_parser() { #[test] fn unavailable_profile_target_persists_a_rejected_diagnostic_artifact() { - let workspace_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let workspace_root = crate::workspace_root(); let scratch = tempfile::Builder::new() .prefix("neomacs-perf-profile-rejection-") .tempdir_in(workspace_root.join("tmp")) @@ -414,7 +414,7 @@ fn native_perf_support_is_compile_time_gated_to_linux() { fn batch_capture_distinguishes_edit_loop_from_whole_process_scope() { let scratch = tempfile::Builder::new() .prefix("neomacs-perf-batch-profile-command-") - .tempdir_in(PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp")) + .tempdir_in(crate::workspace_root().join("tmp")) .expect("create workspace-local profile command directory"); let mut edit_loop = PerfCapture::new( scratch.path(), @@ -481,7 +481,7 @@ fn batch_capture_distinguishes_edit_loop_from_whole_process_scope() { fn gui_capture_profiles_only_the_app_via_the_frontend_hook() { let scratch = tempfile::Builder::new() .prefix("neomacs-perf-gui-profile-command-") - .tempdir_in(PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp")) + .tempdir_in(crate::workspace_root().join("tmp")) .expect("create workspace-local profile scratch directory"); let mut capture = PerfCapture::new( scratch.path(), @@ -524,7 +524,7 @@ fn gui_capture_profiles_only_the_app_via_the_frontend_hook() { fn tui_capture_profiles_only_the_app_inside_the_private_pty() { let scratch = tempfile::Builder::new() .prefix("neomacs-perf-tui-profile-command-") - .tempdir_in(PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp")) + .tempdir_in(crate::workspace_root().join("tmp")) .expect("create workspace-local profile scratch directory"); let mut capture = PerfCapture::new( scratch.path(), diff --git a/crates/neomacs-perf/src/suite_test.rs b/crates/neomacs-perf/src/suite_test.rs index a44d78ff08..b31052bf3b 100644 --- a/crates/neomacs-perf/src/suite_test.rs +++ b/crates/neomacs-perf/src/suite_test.rs @@ -45,7 +45,7 @@ fn suite_thresholds_distinguish_improvements_regressions_and_rejections() { #[test] fn history_rejects_an_unknown_suite_artifact_schema() { - let workspace_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let workspace_tmp = crate::workspace_root().join("tmp"); fs::create_dir_all(&workspace_tmp).expect("create workspace scratch root"); let directory = tempfile::Builder::new() .prefix("neomacs-perf-suite-history-") diff --git a/crates/neomacs-renderer-wgpu/Cargo.toml b/crates/neomacs-renderer-wgpu/Cargo.toml index 8a3ba58a87..b09fdcb2fa 100644 --- a/crates/neomacs-renderer-wgpu/Cargo.toml +++ b/crates/neomacs-renderer-wgpu/Cargo.toml @@ -39,6 +39,7 @@ neomacs-layout-engine.workspace = true neomacs-video = { workspace = true, optional = true } [dev-dependencies] +neomacs-infra.workspace = true neomacs-test-fonts.workspace = true tracing-test.workspace = true diff --git a/crates/neomacs-renderer-wgpu/src/image_cache_test.rs b/crates/neomacs-renderer-wgpu/src/image_cache_test.rs index e568a5c8ed..7b72f784c4 100644 --- a/crates/neomacs-renderer-wgpu/src/image_cache_test.rs +++ b/crates/neomacs-renderer-wgpu/src/image_cache_test.rs @@ -433,7 +433,9 @@ fn explicit_lisp_background_paints_the_svg_wrapper_background() { #[test] fn symbolic_widget_svg_uses_the_resolved_face_foreground() { - let path = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")).join("etc/images/down.svg"); + let path = neomacs_infra::workspace_root() + .as_path() + .join("etc/images/down.svg"); let data = std::fs::read(&path) .unwrap_or_else(|error| panic!("read symbolic widget SVG at {}: {error}", path.display())); @@ -931,7 +933,7 @@ fn svg_does_not_load_images_relative_to_the_process_working_directory() { #[test] fn svg_explicit_base_uri_resolves_a_relative_raster() { - let repository_root = Path::new(env!("CARGO_WORKSPACE_DIR")); + let repository_root = neomacs_infra::workspace_root(); let base_uri = repository_root.join("telega-avatar.svg"); let data = br#" @@ -955,7 +957,7 @@ fn svg_explicit_base_uri_resolves_a_relative_raster() { #[test] fn svg_base_uri_cannot_authorize_parent_directory_escape() { - let repository_root = Path::new(env!("CARGO_WORKSPACE_DIR")); + let repository_root = neomacs_infra::workspace_root(); let base_uri = repository_root .join("crates") .join("neomacs-renderer-wgpu") @@ -1235,7 +1237,9 @@ fn hidpi_svg_decode_metadata_stays_logical_while_texture_pixels_are_physical() { /// Real `etc/images/splash.svg` is 333×233 — the asset behind HiDPI #243. #[test] fn splash_svg_native_extent_is_333_by_233() { - let path = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")).join("etc/images/splash.svg"); + let path = neomacs_infra::workspace_root() + .as_path() + .join("etc/images/splash.svg"); let data = std::fs::read(&path).unwrap_or_else(|err| { panic!("read splash.svg at {}: {err}", path.display()); }); @@ -1262,7 +1266,9 @@ fn splash_svg_native_extent_is_333_by_233() { /// recovers GNU Fimage_size (333×233) via report_scale. #[test] fn splash_svg_scale_default_hidpi_preserves_gnu_image_pixel_extent() { - let path = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")).join("etc/images/splash.svg"); + let path = neomacs_infra::workspace_root() + .as_path() + .join("etc/images/splash.svg"); let data = std::fs::read(&path).expect("splash.svg"); // layout_scale = 1/1.25, report_scale = 1.25 (ImageScalePolicy::Default). let realization = ImageRealization::new(1.0 / 1.25, 1.25, 1.25); diff --git a/crates/neomacs-test-fonts/src/lib.rs b/crates/neomacs-test-fonts/src/lib.rs index ad9bed137b..bfd75effd2 100644 --- a/crates/neomacs-test-fonts/src/lib.rs +++ b/crates/neomacs-test-fonts/src/lib.rs @@ -4,6 +4,14 @@ //! the verified files below the workspace's `./tmp` directory so no binary //! fixtures need to be committed. +/// Runtime workspace root: nextest's NEXTEST_WORKSPACE_ROOT when present, +/// the compile-time constant otherwise (see neomacs-infra). +pub fn workspace_root() -> std::path::PathBuf { + std::env::var_os("NEXTEST_WORKSPACE_ROOT") + .map(std::path::PathBuf::from) + .unwrap_or_else(|| std::path::PathBuf::from(env!("CARGO_WORKSPACE_DIR"))) +} + use std::collections::BTreeMap; use std::fs::{self, File, OpenOptions}; use std::io::{self, Read, Write}; @@ -230,10 +238,6 @@ fn prepare_spleen_fixtures_locked(cache_root: &Path) -> Result PathBuf { - Path::new(env!("CARGO_WORKSPACE_DIR")).to_path_buf() -} - fn open_lock(path: &Path) -> Result { OpenOptions::new() .create(true) diff --git a/crates/neomacs/Cargo.toml b/crates/neomacs/Cargo.toml index 136453af13..4ae7f208b7 100644 --- a/crates/neomacs/Cargo.toml +++ b/crates/neomacs/Cargo.toml @@ -109,6 +109,7 @@ windows-version = "0.1.7" windows-sys.workspace = true [dev-dependencies] +neomacs-infra.workspace = true tempfile.workspace = true stacker.workspace = true rustix = { workspace = true, features = ["pty", "termios"] } diff --git a/crates/neomacs/src/main_test.rs b/crates/neomacs/src/main_test.rs index c74744ed6f..8b98f0411a 100644 --- a/crates/neomacs/src/main_test.rs +++ b/crates/neomacs/src/main_test.rs @@ -2569,7 +2569,7 @@ fn primary_image_catalog_lookup_returns_pending_without_waiting_for_render_threa #[cfg(feature = "neo-term")] terminal_state: super::TerminalHostState::new(new_shared_terminals()), }; - let repo_root = Path::new(env!("CARGO_WORKSPACE_DIR")); + let repo_root = neomacs_infra::workspace_root(); let image_path = repo_root.join("test/data/image/blank-100x200.png"); let request = ImageResolveRequest { spec: test_image_spec_identity(image_path.to_str().expect("utf8 path")), @@ -5754,7 +5754,7 @@ fn gnu_startup_processes_load_option_from_forwarded_args() { let mut eval = create_bootstrap_evaluator_cached_with_features(&["neomacs"]) .expect("cached bootstrap evaluator"); let frame_id = bootstrap_runtime_gui_frame(&mut eval); - let repo_root = Path::new(env!("CARGO_WORKSPACE_DIR")); + let repo_root = neomacs_infra::workspace_root(); let face_test = repo_root.join("test/neomacs/neomacs-face-test.el"); let startup = gui_startup_with_args(&[ "-Q", @@ -5789,7 +5789,7 @@ fn recursive_edit_processes_load_option_from_forwarded_args_before_first_input() let mut eval = create_bootstrap_evaluator_cached_with_features(&["neomacs"]) .expect("cached bootstrap evaluator"); let frame_id = bootstrap_runtime_gui_frame(&mut eval); - let repo_root = Path::new(env!("CARGO_WORKSPACE_DIR")); + let repo_root = neomacs_infra::workspace_root(); let face_test = repo_root.join("test/neomacs/neomacs-face-test.el"); let startup = gui_startup_with_args(&[ "-Q", diff --git a/crates/neomacs/tests/common/mod.rs b/crates/neomacs/tests/common/mod.rs index be021a22e5..d79574c18a 100644 --- a/crates/neomacs/tests/common/mod.rs +++ b/crates/neomacs/tests/common/mod.rs @@ -50,7 +50,7 @@ pub fn oracle_emacs_path() -> String { if let Ok(path) = std::env::var("NEOVM_FORCE_ORACLE_PATH") { return path; } - let mut dir = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let mut dir = neomacs_infra::workspace_root(); for _ in 0..4 { let candidate = dir.join("emacs-mirror/emacs/src/emacs"); if candidate.exists() { diff --git a/crates/neomacs/tests/neomacsclient_cli.rs b/crates/neomacs/tests/neomacsclient_cli.rs index 2dc78e7419..6c41010c9f 100644 --- a/crates/neomacs/tests/neomacsclient_cli.rs +++ b/crates/neomacs/tests/neomacsclient_cli.rs @@ -23,7 +23,7 @@ fn neomacsclient_sends_gnu_server_request_over_local_socket() { use std::path::PathBuf; use std::thread; - let repo_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let repo_tmp = neomacs_infra::workspace_root().join("tmp"); fs::create_dir_all(&repo_tmp).expect("repo-local tmp dir"); let dir = tempfile::Builder::new() .prefix("neomacsclient-cli-") @@ -80,7 +80,7 @@ fn neomacsclient_parent_id_implies_a_new_graphical_frame() { use std::path::PathBuf; use std::thread; - let repo_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let repo_tmp = neomacs_infra::workspace_root().join("tmp"); fs::create_dir_all(&repo_tmp).expect("repo-local tmp dir"); let dir = tempfile::Builder::new() .prefix("neomacsclient-parent-frame-") @@ -129,7 +129,7 @@ fn neomacsclient_create_frame_requests_window_system_without_display_arg() { use std::path::PathBuf; use std::thread; - let repo_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let repo_tmp = neomacs_infra::workspace_root().join("tmp"); fs::create_dir_all(&repo_tmp).expect("repo-local tmp dir"); let dir = tempfile::Builder::new() .prefix("neomacsclient-create-frame-") @@ -192,7 +192,7 @@ fn neomacsclient_tty_identifies_its_terminal_to_the_server() { use std::process::Stdio; use std::thread; - let repo_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let repo_tmp = neomacs_infra::workspace_root().join("tmp"); fs::create_dir_all(&repo_tmp).expect("repo-local tmp dir"); let dir = tempfile::Builder::new() .prefix("neomacsclient-tty-") @@ -265,7 +265,7 @@ fn neomacsclient_tty_forwards_resize_to_the_server_process() { use std::thread; use std::time::{Duration, Instant}; - let repo_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let repo_tmp = neomacs_infra::workspace_root().join("tmp"); fs::create_dir_all(&repo_tmp).expect("repo-local tmp dir"); let dir = tempfile::Builder::new() .prefix("neomacsclient-resize-") @@ -345,7 +345,7 @@ fn neomacsclient_sends_gnu_auth_for_tcp_server_file() { use std::path::PathBuf; use std::thread; - let repo_tmp = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let repo_tmp = neomacs_infra::workspace_root().join("tmp"); fs::create_dir_all(&repo_tmp).expect("repo-local tmp dir"); let dir = tempfile::Builder::new() .prefix("neomacsclient-tcp-") diff --git a/crates/neovm-core/src/emacs_core/commands/interactive/tests/mod.rs b/crates/neovm-core/src/emacs_core/commands/interactive/tests/mod.rs index 48e02f3c94..16740ccc50 100644 --- a/crates/neovm-core/src/emacs_core/commands/interactive/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/commands/interactive/tests/mod.rs @@ -168,7 +168,7 @@ fn install_bare_elisp_shims(ev: &mut Context) { } fn gnu_subr_keymap_eval_all(src: &str) -> Vec { - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let subr_path = project_root.join("lisp/subr.el"); let subr_source = fs::read_to_string(&subr_path).expect("read GNU subr.el"); @@ -195,7 +195,7 @@ fn gnu_subr_keymap_eval_all(src: &str) -> Vec { } fn gnu_simple_command_execute_eval() -> Context { - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let simple_path = project_root.join("lisp/simple.el"); let simple_source = fs::read_to_string(&simple_path).expect("read GNU simple.el"); let subr_path = project_root.join("lisp/subr.el"); @@ -276,7 +276,7 @@ fn gnu_simple_command_execute_eval_all(src: &str) -> Vec { } fn gnu_simple_execute_extended_command_eval() -> Context { - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let simple_path = project_root.join("lisp/simple.el"); let simple_source = fs::read_to_string(&simple_path).expect("read GNU simple.el"); @@ -302,7 +302,7 @@ fn gnu_simple_execute_extended_command_eval() -> Context { } fn gnu_files_command_eval() -> Context { - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let files_path = project_root.join("lisp/files.el"); let files_source = fs::read_to_string(&files_path).expect("read GNU files.el"); @@ -328,7 +328,7 @@ fn gnu_simple_execute_extended_command_eval_all(src: &str) -> Vec { } fn load_gnu_eval_expression_into(ev: &mut Context) { - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let simple_path = project_root.join("lisp/simple.el"); let simple_source = fs::read_to_string(&simple_path).expect("read GNU simple.el"); @@ -370,7 +370,7 @@ fn gnu_simple_command_execute_with_eval_expression_eval() -> Context { } fn gnu_simple_universal_argument_eval_all(src: &str) -> Vec { - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let simple_path = project_root.join("lisp/simple.el"); let simple_source = fs::read_to_string(&simple_path).expect("read GNU simple.el"); @@ -387,7 +387,7 @@ fn gnu_simple_universal_argument_eval_all(src: &str) -> Vec { } fn gnu_simple_quoted_insert_eval_all(src: &str) -> Vec { - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let simple_path = project_root.join("lisp/simple.el"); let simple_source = fs::read_to_string(&simple_path).expect("read GNU simple.el"); @@ -1329,7 +1329,7 @@ fn ldefs_boot_aliases_name_last_kbd_macro_to_kmacro_name_last_macro() { crate::test_utils::init_test_tracing(); let mut ev = Context::new(); let ldefs_source = - fs::read_to_string(PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("lisp/ldefs-boot.el")) + fs::read_to_string(crate::test_utils::workspace_root().join("lisp/ldefs-boot.el")) .expect("read ldefs-boot.el"); eval_first_form_after_marker( &mut ev, diff --git a/crates/neovm-core/src/emacs_core/display/display/tests/mod.rs b/crates/neovm-core/src/emacs_core/display/display/tests/mod.rs index 1f390f9ae9..293e0245be 100644 --- a/crates/neovm-core/src/emacs_core/display/display/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/display/display/tests/mod.rs @@ -312,9 +312,8 @@ fn headless_primary_selection_ownership_tracks_even_an_empty_value() { #[test] fn gnu_select_el_defines_x_selection_aliases() { crate::test_utils::init_test_tracing(); - let source = - fs::read_to_string(PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("lisp/select.el")) - .expect("read select.el"); + let source = fs::read_to_string(crate::test_utils::workspace_root().join("lisp/select.el")) + .expect("read select.el"); assert!( source .contains("(define-obsolete-function-alias 'x-select-text 'gui-select-text \"25.1\")"), diff --git a/crates/neovm-core/src/emacs_core/display/font/tests/mod.rs b/crates/neovm-core/src/emacs_core/display/font/tests/mod.rs index 54f896d650..428f0c5649 100644 --- a/crates/neovm-core/src/emacs_core/display/font/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/display/font/tests/mod.rs @@ -136,9 +136,8 @@ fn named_font_string_requires_a_representable_positive_point_size() { #[test] fn gnu_faces_el_defines_x_color_aliases() { crate::test_utils::init_test_tracing(); - let source = - fs::read_to_string(PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("lisp/faces.el")) - .expect("read faces.el"); + let source = fs::read_to_string(crate::test_utils::workspace_root().join("lisp/faces.el")) + .expect("read faces.el"); assert!( source.contains( "(define-obsolete-function-alias 'x-defined-colors #'defined-colors \"30.1\")" diff --git a/crates/neovm-core/src/emacs_core/display/window_cmds/tests/mod.rs b/crates/neovm-core/src/emacs_core/display/window_cmds/tests/mod.rs index da832202e2..e5aa37eb79 100644 --- a/crates/neovm-core/src/emacs_core/display/window_cmds/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/display/window_cmds/tests/mod.rs @@ -5481,9 +5481,8 @@ fn raw_context_does_not_prebind_window_inside_aliases() { #[test] fn gnu_window_el_defines_window_inside_aliases() { crate::test_utils::init_test_tracing(); - let source = - fs::read_to_string(PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("lisp/window.el")) - .expect("read window.el"); + let source = fs::read_to_string(crate::test_utils::workspace_root().join("lisp/window.el")) + .expect("read window.el"); assert!( source.contains("(defun window-body-edges (&optional window)"), "GNU window.el should define window-body-edges", diff --git a/crates/neovm-core/src/emacs_core/editing/indent/tests/mod.rs b/crates/neovm-core/src/emacs_core/editing/indent/tests/mod.rs index 79d37d8bde..8996899693 100644 --- a/crates/neovm-core/src/emacs_core/editing/indent/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/editing/indent/tests/mod.rs @@ -65,7 +65,7 @@ fn install_bare_elisp_shims(ev: &mut Context) { } fn gnu_simple_indent_eval() -> Context { - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let simple_path = project_root.join("lisp/simple.el"); let simple_source = fs::read_to_string(&simple_path).expect("read GNU simple.el"); @@ -77,7 +77,7 @@ fn gnu_simple_indent_eval() -> Context { } fn gnu_indent_el_eval() -> Context { - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let indent_path = project_root.join("lisp/indent.el"); let indent_source = fs::read_to_string(&indent_path).expect("read GNU indent.el"); let simple_path = project_root.join("lisp/simple.el"); diff --git a/crates/neovm-core/src/emacs_core/editing/navigation/tests/mod.rs b/crates/neovm-core/src/emacs_core/editing/navigation/tests/mod.rs index 2e830e8e8d..e8318b8157 100644 --- a/crates/neovm-core/src/emacs_core/editing/navigation/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/editing/navigation/tests/mod.rs @@ -93,7 +93,7 @@ fn install_bare_elisp_shims(ev: &mut Context) { } fn gnu_simple_line_eval() -> Context { - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let simple_path = project_root.join("lisp/simple.el"); let subr_path = project_root.join("lisp/subr.el"); let simple_source = fs::read_to_string(&simple_path) diff --git a/crates/neovm-core/src/emacs_core/editing/rect/tests/mod.rs b/crates/neovm-core/src/emacs_core/editing/rect/tests/mod.rs index 89aa65728c..0432e6fd47 100644 --- a/crates/neovm-core/src/emacs_core/editing/rect/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/editing/rect/tests/mod.rs @@ -514,9 +514,8 @@ fn raw_context_does_not_prebind_replace_rectangle_alias() { #[test] fn gnu_ldefs_boot_defines_replace_rectangle_alias() { crate::test_utils::init_test_tracing(); - let source = - fs::read_to_string(PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("lisp/ldefs-boot.el")) - .expect("read ldefs-boot"); + let source = fs::read_to_string(crate::test_utils::workspace_root().join("lisp/ldefs-boot.el")) + .expect("read ldefs-boot"); assert!( source.contains( "(define-obsolete-function-alias 'replace-rectangle #'string-rectangle \"29.1\")", diff --git a/crates/neovm-core/src/emacs_core/lisp/autoload/tests/mod.rs b/crates/neovm-core/src/emacs_core/lisp/autoload/tests/mod.rs index 6a39349b0b..c7d50834f8 100644 --- a/crates/neovm-core/src/emacs_core/lisp/autoload/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/lisp/autoload/tests/mod.rs @@ -83,7 +83,7 @@ fn install_bare_elisp_shims(ev: &mut Context) { fn load_minimal_autoload_runtime(ev: &mut Context) { install_bare_elisp_shims(ev); - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let subr_source = fs::read_to_string(project_root.join("lisp/subr.el")).expect("read GNU subr.el"); diff --git a/crates/neovm-core/src/emacs_core/lisp/doc/tests/mod.rs b/crates/neovm-core/src/emacs_core/lisp/doc/tests/mod.rs index e2aba2b325..2f893c53ef 100644 --- a/crates/neovm-core/src/emacs_core/lisp/doc/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/lisp/doc/tests/mod.rs @@ -2000,7 +2000,9 @@ fn a_stale_reference_into_a_compiled_file_is_reread_and_retried() { // Under the repo's own `tmp/`, not `/tmp`: this project's temp output goes // in the tree (and `tmp/` is ignored), so a fixture cannot land on a // volume that has no room for it. - let dir = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")).join("tmp/l194-doc-reread-unit"); + let dir = crate::test_utils::workspace_root() + .as_path() + .join("tmp/l194-doc-reread-unit"); std::fs::create_dir_all(&dir).expect("fixture dir"); let path = dir.join("victim.el"); let escaped = path.display().to_string(); @@ -2059,7 +2061,9 @@ fn a_reread_that_does_not_repair_the_reference_happens_exactly_once() { // Under the repo's own `tmp/`, not `/tmp`: this project's temp output goes // in the tree (and `tmp/` is ignored), so a fixture cannot land on a // volume that has no room for it. - let dir = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")).join("tmp/l194-doc-reread-unit"); + let dir = crate::test_utils::workspace_root() + .as_path() + .join("tmp/l194-doc-reread-unit"); std::fs::create_dir_all(&dir).expect("fixture dir"); let path = dir.join("norepair.el"); let escaped = path.display().to_string(); diff --git a/crates/neovm-core/src/emacs_core/lisp/load/mod.rs b/crates/neovm-core/src/emacs_core/lisp/load/mod.rs index ac9e1f2ec6..9dc0feed6f 100644 --- a/crates/neovm-core/src/emacs_core/lisp/load/mod.rs +++ b/crates/neovm-core/src/emacs_core/lisp/load/mod.rs @@ -3291,7 +3291,7 @@ fn prune_bootstrap_cache_generations(dump_path: &Path, keep: usize) { /// which run 15-20 MB apiece. #[cfg(test)] pub(crate) fn test_bootstrap_cache_path(kind: &str) -> PathBuf { - let dir = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("target/test-cache"); + let dir = crate::test_utils::workspace_root().join("target/test-cache"); let _ = std::fs::create_dir_all(&dir); let fingerprint = bootstrap_source_fingerprint(&runtime_project_root()); let path = dir.join(format!( diff --git a/crates/neovm-core/src/emacs_core/lisp/load/tests/mod.rs b/crates/neovm-core/src/emacs_core/lisp/load/tests/mod.rs index 70cb86584d..ebf55cd655 100644 --- a/crates/neovm-core/src/emacs_core/lisp/load/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/lisp/load/tests/mod.rs @@ -129,7 +129,7 @@ fn isolated_runtime_bootstrap_eval() -> Context { } fn bootstrap_lisp_root() -> PathBuf { - PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("lisp") + crate::test_utils::workspace_root().join("lisp") } fn source_bootstrap_path(rel: &str) -> PathBuf { @@ -1046,7 +1046,7 @@ fn gnu_subr_x_string_chop_newline_loads_without_rust_builtin() { // `subr-x.el`, not from a Rust builtin. let mut eval = Context::new(); crate::test_utils::load_minimal_gnu_help_runtime(&mut eval); - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let lisp_dir = project_root.join("lisp"); eval.set_variable( "load-path", @@ -1116,7 +1116,7 @@ fn load_bindings_source_survives_gc_stress_after_custom_runtime() { let mut eval = Context::new(); crate::test_utils::load_minimal_gnu_help_runtime(&mut eval); - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let lisp_dir = project_root.join("lisp"); eval.set_variable( "load-path", @@ -1258,7 +1258,7 @@ fn gnu_subr_el_defines_wholenump_without_rust_shim() { #[test] fn load_subr_survives_exact_post_form_gc_after_byte_run() { crate::test_utils::init_test_tracing(); - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let lisp_dir = project_root.join("lisp"); let mut eval = Context::new(); @@ -2010,7 +2010,7 @@ fn format_eval_error(eval: &Context, err: &EvalError) -> String { fn partial_bootstrap_eval_until(stop_before: &str, prefer_compiled: bool) -> Context { crate::test_utils::init_test_tracing(); - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let lisp_dir = project_root.join("lisp"); assert!( lisp_dir.is_dir(), @@ -2109,7 +2109,7 @@ fn partial_bootstrap_eval_until(stop_before: &str, prefer_compiled: bool) -> Con fn build_pre_macroexp_reload_eval() -> Context { crate::test_utils::init_test_tracing(); - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let lisp_dir = project_root.join("lisp"); assert!( lisp_dir.is_dir(), @@ -4719,7 +4719,7 @@ fn bootstrap_runtime_find_file_handles_multibyte_markdown_like_gnu() { let mut eval = create_bootstrap_evaluator_cached().expect("bootstrap"); apply_runtime_startup_state(&mut eval).expect("runtime startup state"); - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let target = project_root.join("docs/rust-display-engine.md"); let target_str = target.to_string_lossy(); @@ -7406,7 +7406,7 @@ fn bootstrap_neomacs_cursor_blink_setup_keeps_lisp_timers_stopped() { #[test] fn loadup_source_preloads_mouse_help_fixup_runtime_surface() { crate::test_utils::init_test_tracing(); - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let loadup = project_root.join("lisp/loadup.el"); let source = fs::read_to_string(&loadup).expect("read loadup.el"); @@ -7437,7 +7437,7 @@ fn neo_win_source_requires_easy_mmode_before_minor_mode_definitions() { #[test] fn bootstrap_help_fns_loads_and_preserves_hook_depth_metadata() { crate::test_utils::init_test_tracing(); - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let help_fns = project_root.join("lisp/help-fns.el"); let rendered = fresh_bootstrap_eval_with_loaded_file( @@ -7460,7 +7460,7 @@ fn bootstrap_help_fns_loads_and_preserves_hook_depth_metadata() { #[test] fn bootstrap_help_fns_describe_function_writes_help_buffer() { crate::test_utils::init_test_tracing(); - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let help_fns = project_root.join("lisp/help-fns.el"); let rendered = fresh_bootstrap_eval_with_loaded_file( @@ -7481,7 +7481,7 @@ fn bootstrap_help_fns_describe_function_writes_help_buffer() { #[test] fn bootstrap_help_fns_describe_variable_writes_help_buffer() { crate::test_utils::init_test_tracing(); - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let help_fns = project_root.join("lisp/help-fns.el"); let rendered = fresh_bootstrap_eval_with_loaded_file( @@ -8483,7 +8483,7 @@ fn runtime_startup_state_preserves_gui_frame_metrics() { #[test] fn bootstrap_misc_upcase_char_preserves_point_and_uppercases_region() { crate::test_utils::init_test_tracing(); - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let misc = project_root.join("lisp/misc.el"); let rendered = fresh_bootstrap_eval_with_loaded_file( @@ -8649,7 +8649,7 @@ fn profile_single_bootstrap_file_load() { let prefer_compiled = std::env::var("NEOVM_PROFILE_BOOTSTRAP_PREFER_COMPILED").as_deref() == Ok("1"); - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let lisp_dir = project_root.join("lisp"); let mut eval = partial_bootstrap_eval_until(&stop_before, prefer_compiled); @@ -9990,7 +9990,7 @@ fn ensure_startup_compat_variables_backfills_xfaces_bootstrap_state() { eval.obarray_mut().makunbound(name); } - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); ensure_startup_compat_variables(&mut eval, &project_root); assert_eq!( @@ -10831,8 +10831,12 @@ fn reader_accepts_utf8_emacs_extended_char_literals_from_ethiopic_source() { #[test] fn reader_accepts_utf8_emacs_extended_char_literals_in_full_ethiopic_source() { crate::test_utils::init_test_tracing(); - let bytes = fs::read(Path::new(env!("CARGO_WORKSPACE_DIR")).join("lisp/language/ethiopic.el")) - .expect("read ethiopic source fixture"); + let bytes = fs::read( + crate::test_utils::workspace_root() + .as_path() + .join("lisp/language/ethiopic.el"), + ) + .expect("read ethiopic source fixture"); let source = decode_emacs_utf8_source_lisp(&bytes, crate::emacs_core::coding::EolConversion::Enabled); @@ -10848,8 +10852,12 @@ fn reader_accepts_utf8_emacs_extended_char_literals_in_full_ethiopic_source() { #[test] fn lisp_source_reader_accepts_utf8_emacs_extended_char_literals_in_full_ethiopic_source() { crate::test_utils::init_test_tracing(); - let bytes = fs::read(Path::new(env!("CARGO_WORKSPACE_DIR")).join("lisp/language/ethiopic.el")) - .expect("read ethiopic source fixture"); + let bytes = fs::read( + crate::test_utils::workspace_root() + .as_path() + .join("lisp/language/ethiopic.el"), + ) + .expect("read ethiopic source fixture"); let text = decode_emacs_utf8_source_lisp(&bytes, crate::emacs_core::coding::EolConversion::Enabled); let source = crate::emacs_core::value_reader::LispReadSource::new(&text); @@ -13142,7 +13150,7 @@ fn direct_setq_funcall_updates_variable_place() { #[test] fn pdump_roundtrip_preserves_advice_remove_member_lifecycle() { crate::test_utils::init_test_tracing(); - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let mut eval = create_bootstrap_evaluator().expect("bootstrap evaluator"); ensure_startup_compat_variables(&mut eval, &project_root); @@ -13238,7 +13246,7 @@ fn pdump_roundtrip_preserves_advice_remove_member_lifecycle() { #[test] fn pdump_roundtrip_evaluates_full_advice_remove_member_form() { crate::test_utils::init_test_tracing(); - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let mut eval = create_bootstrap_evaluator().expect("bootstrap evaluator"); ensure_startup_compat_variables(&mut eval, &project_root); @@ -13943,7 +13951,7 @@ fn runtime_add_function_on_process_sentinel_place() { #[test] fn bootstrap_cl_extra_source_vs_compiled_cl_subseq_setf() { crate::test_utils::init_test_tracing(); - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let cl_extra_base = project_root.join("lisp/emacs-lisp/cl-extra"); let source_path = source_suffixed_path(&cl_extra_base); let compiled_path = compiled_suffixed_path(&cl_extra_base); @@ -13967,7 +13975,7 @@ fn bootstrap_cl_extra_source_vs_compiled_cl_subseq_setf() { #[test] fn bootstrap_cl_extra_gv_expander_matches_gnu_source_and_compiled_surfaces() { crate::test_utils::init_test_tracing(); - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let cl_extra_base = project_root.join("lisp/emacs-lisp/cl-extra"); let source_path = source_suffixed_path(&cl_extra_base); let compiled_path = compiled_suffixed_path(&cl_extra_base); @@ -14094,7 +14102,7 @@ fn macroexpand_all_pcase_terminates() { return; } crate::test_utils::init_test_tracing(); - let project_root = std::path::PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let lisp_dir = project_root.join("lisp"); assert!(lisp_dir.is_dir()); let mut eval = crate::emacs_core::eval::Context::new(); @@ -14184,7 +14192,7 @@ fn macroexpand_all_pcase_terminates() { #[test] fn macroexp_eager_reload_preserves_symbol_identity() { crate::test_utils::init_test_tracing(); - let project_root = std::path::PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let lisp_dir = project_root.join("lisp"); assert!(lisp_dir.is_dir()); @@ -14330,7 +14338,7 @@ fn eager_expand_toplevel_forms_keeps_recursive_progn_forms_alive_under_exact_gc( #[test] fn function_get_only_exposes_cxxr_compiler_macro_on_cxxr_symbols() { crate::test_utils::init_test_tracing(); - let project_root = std::path::PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let lisp_dir = project_root.join("lisp"); assert!(lisp_dir.is_dir()); @@ -14377,7 +14385,7 @@ fn function_get_only_exposes_cxxr_compiler_macro_on_cxxr_symbols() { #[test] fn pcase_integer_literal_pattern() { crate::test_utils::init_test_tracing(); - let project_root = std::path::PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let lisp_dir = project_root.join("lisp"); assert!(lisp_dir.is_dir()); let mut eval = crate::emacs_core::eval::Context::new(); @@ -14519,7 +14527,7 @@ fn pcase_integer_literal_pattern() { fn key_parse_modifier_bits() { crate::test_utils::init_test_tracing(); - let project_root = std::path::PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let lisp_dir = project_root.join("lisp"); if !lisp_dir.is_dir() { tracing::info!("skipping key_parse_modifier_bits: no lisp/ directory"); diff --git a/crates/neovm-core/src/emacs_core/lisp/load/tests/stale_bytecode.rs b/crates/neovm-core/src/emacs_core/lisp/load/tests/stale_bytecode.rs index 1c50b1ebdc..459c7c96b8 100644 --- a/crates/neovm-core/src/emacs_core/lisp/load/tests/stale_bytecode.rs +++ b/crates/neovm-core/src/emacs_core/lisp/load/tests/stale_bytecode.rs @@ -56,7 +56,7 @@ impl Fixture { .duration_since(std::time::UNIX_EPOCH) .expect("clock before epoch") .as_nanos(); - let root = std::path::PathBuf::from(env!("CARGO_WORKSPACE_DIR")) + let root = crate::test_utils::workspace_root() .join("tmp") .join("stale-bytecode-tests") .join(format!("{name}-{unique}")); @@ -490,7 +490,7 @@ fn only_the_shipped_editors_main_announces_itself() { "crates/neovm-core/src/emacs_core/lisp/load/tests/stale_bytecode.rs", ]; - let root = std::path::PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let root = crate::test_utils::workspace_root(); let mut scanned = 0usize; let mut callers: Vec = Vec::new(); diff --git a/crates/neovm-core/src/emacs_core/lisp/native/builtins/file_notify/platform/linux/tests/worker.rs b/crates/neovm-core/src/emacs_core/lisp/native/builtins/file_notify/platform/linux/tests/worker.rs index 21d3883988..5c6f4a7657 100644 --- a/crates/neovm-core/src/emacs_core/lisp/native/builtins/file_notify/platform/linux/tests/worker.rs +++ b/crates/neovm-core/src/emacs_core/lisp/native/builtins/file_notify/platform/linux/tests/worker.rs @@ -1,7 +1,8 @@ use super::*; fn workspace_temp_dir() -> tempfile::TempDir { - let parent = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")) + let parent = crate::test_utils::workspace_root() + .as_path() .join("target") .join("neovm-core-file-notify-tests"); std::fs::create_dir_all(&parent).expect("create workspace test directory"); diff --git a/crates/neovm-core/src/emacs_core/lisp/native/builtins/file_notify/tests/linux.rs b/crates/neovm-core/src/emacs_core/lisp/native/builtins/file_notify/tests/linux.rs index e3e2617941..434192f938 100644 --- a/crates/neovm-core/src/emacs_core/lisp/native/builtins/file_notify/tests/linux.rs +++ b/crates/neovm-core/src/emacs_core/lisp/native/builtins/file_notify/tests/linux.rs @@ -1,7 +1,8 @@ use super::*; fn workspace_temp_dir() -> tempfile::TempDir { - let parent = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")) + let parent = crate::test_utils::workspace_root() + .as_path() .join("target") .join("neovm-core-file-notify-tests"); std::fs::create_dir_all(&parent).expect("create workspace test directory"); diff --git a/crates/neovm-core/src/emacs_core/lisp/native/builtins/file_notify/tests/mod.rs b/crates/neovm-core/src/emacs_core/lisp/native/builtins/file_notify/tests/mod.rs index 5d9a45c585..ae956f27ca 100644 --- a/crates/neovm-core/src/emacs_core/lisp/native/builtins/file_notify/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/lisp/native/builtins/file_notify/tests/mod.rs @@ -3,7 +3,8 @@ use super::*; use crate::emacs_core::intern::intern; fn workspace_temp_dir() -> tempfile::TempDir { - let parent = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")) + let parent = crate::test_utils::workspace_root() + .as_path() .join("target") .join("neovm-core-file-notify-tests"); std::fs::create_dir_all(&parent).expect("create workspace test directory"); diff --git a/crates/neovm-core/src/emacs_core/lisp/native/builtins/file_notify/tests/native_runtime.rs b/crates/neovm-core/src/emacs_core/lisp/native/builtins/file_notify/tests/native_runtime.rs index 16c237094d..cdf64de3aa 100644 --- a/crates/neovm-core/src/emacs_core/lisp/native/builtins/file_notify/tests/native_runtime.rs +++ b/crates/neovm-core/src/emacs_core/lisp/native/builtins/file_notify/tests/native_runtime.rs @@ -6,7 +6,8 @@ use std::path::Path; use std::path::PathBuf; fn workspace_temp_dir() -> tempfile::TempDir { - let parent = Path::new(env!("CARGO_WORKSPACE_DIR")) + let parent = crate::test_utils::workspace_root() + .as_path() .join("target") .join("neovm-core-file-notify-tests"); std::fs::create_dir_all(&parent).expect("create workspace test directory"); diff --git a/crates/neovm-core/src/emacs_core/lisp/native/builtins/tests/mod.rs b/crates/neovm-core/src/emacs_core/lisp/native/builtins/tests/mod.rs index 0063335c59..d303cae15b 100644 --- a/crates/neovm-core/src/emacs_core/lisp/native/builtins/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/lisp/native/builtins/tests/mod.rs @@ -149,7 +149,10 @@ fn load_gnu_save_selected_window_runtime(eval: &mut Context) { ) .expect("eval forms"); - let window_path = concat!(env!("CARGO_WORKSPACE_DIR"), "/lisp/window.el"); + let window_path = crate::test_utils::workspace_root() + .join("lisp/window.el") + .to_string_lossy() + .into_owned(); let window_source = fs::read_to_string(window_path).expect("read GNU window.el"); for marker in [ "(defun internal--before-save-selected-window ()", diff --git a/crates/neovm-core/src/emacs_core/runtime/eval/tests/mod.rs b/crates/neovm-core/src/emacs_core/runtime/eval/tests/mod.rs index 5186574272..3e86145880 100644 --- a/crates/neovm-core/src/emacs_core/runtime/eval/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/runtime/eval/tests/mod.rs @@ -19949,7 +19949,10 @@ fn vm_subr_mix_fontlock() { let mut ev = crate::test_utils::runtime_startup_context(); // 256 KiB of real elisp, cut at a char boundary (same as the regex benches). - let path = concat!(env!("CARGO_WORKSPACE_DIR"), "/lisp/subr.el"); + let path = crate::test_utils::workspace_root() + .join("lisp/subr.el") + .to_string_lossy() + .into_owned(); let text = std::fs::read_to_string(path).expect("read lisp/subr.el haystack"); let mut cut = text.len().min(256 * 1024); while !text.is_char_boundary(cut) { diff --git a/crates/neovm-core/src/emacs_core/runtime/symbol/tests/buffer_local_global_read.rs b/crates/neovm-core/src/emacs_core/runtime/symbol/tests/buffer_local_global_read.rs index 5f9157e548..4659601333 100644 --- a/crates/neovm-core/src/emacs_core/runtime/symbol/tests/buffer_local_global_read.rs +++ b/crates/neovm-core/src/emacs_core/runtime/symbol/tests/buffer_local_global_read.rs @@ -410,7 +410,7 @@ fn no_production_rust_reads_a_per_buffer_name_from_the_bare_obarray() { // because the ban is about the *name*, not about which crate spells it: the // layout engine and the app binary both hold an evaluator, and a per-buffer // read there would be exactly as wrong and exactly as silent. - let workspace = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")).to_path_buf(); + let workspace = crate::test_utils::workspace_root().as_path().to_path_buf(); let crates = workspace.join("crates"); let roots = [ "neovm-core", diff --git a/crates/neovm-core/src/emacs_core/system/callproc/tests/working_dir_infile.rs b/crates/neovm-core/src/emacs_core/system/callproc/tests/working_dir_infile.rs index 8915bababb..9c7a3abdcf 100644 --- a/crates/neovm-core/src/emacs_core/system/callproc/tests/working_dir_infile.rs +++ b/crates/neovm-core/src/emacs_core/system/callproc/tests/working_dir_infile.rs @@ -12,7 +12,7 @@ use crate::heap_types::LispString; use std::path::{Path, PathBuf}; fn workspace_temp_dir(prefix: &str) -> tempfile::TempDir { - let workspace_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let workspace_root = crate::test_utils::workspace_root(); let temp_root = workspace_root.join("tmp"); std::fs::create_dir_all(&temp_root).expect("create workspace tmp directory"); tempfile::Builder::new() diff --git a/crates/neovm-core/src/emacs_core/system/fileio/tests/backup_test.rs b/crates/neovm-core/src/emacs_core/system/fileio/tests/backup_test.rs index 21ddee081f..93de151a89 100644 --- a/crates/neovm-core/src/emacs_core/system/fileio/tests/backup_test.rs +++ b/crates/neovm-core/src/emacs_core/system/fileio/tests/backup_test.rs @@ -1,7 +1,8 @@ use super::*; fn workspace_temp_dir() -> tempfile::TempDir { - let parent = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")) + let parent = crate::test_utils::workspace_root() + .as_path() .join("target") .join("neovm-core-fileio-tests"); std::fs::create_dir_all(&parent).expect("create workspace test directory"); @@ -13,7 +14,7 @@ fn workspace_temp_dir() -> tempfile::TempDir { fn context_with_gnu_files() -> Context { let mut eval = Context::new(); - let lisp = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")).join("lisp"); + let lisp = crate::test_utils::workspace_root().as_path().join("lisp"); eval.set_lexical_binding(true); eval.set_variable( "load-path", diff --git a/crates/neovm-core/src/emacs_core/system/fileio/tests/mod.rs b/crates/neovm-core/src/emacs_core/system/fileio/tests/mod.rs index a79aab6975..8d7f9d24ee 100644 --- a/crates/neovm-core/src/emacs_core/system/fileio/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/system/fileio/tests/mod.rs @@ -1263,7 +1263,8 @@ fn test_builtin_copy_file_optional_arg_semantics() { #[test] fn copy_file_keep_time_preserves_source_modification_time() { crate::test_utils::init_test_tracing(); - let parent = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")) + let parent = crate::test_utils::workspace_root() + .as_path() .join("target") .join("neovm-core-fileio-tests"); fs::create_dir_all(&parent).expect("create workspace test directory"); diff --git a/crates/neovm-core/src/emacs_core/system/fileio/tests/windows_test.rs b/crates/neovm-core/src/emacs_core/system/fileio/tests/windows_test.rs index 50617dbc19..2b1d6928fb 100644 --- a/crates/neovm-core/src/emacs_core/system/fileio/tests/windows_test.rs +++ b/crates/neovm-core/src/emacs_core/system/fileio/tests/windows_test.rs @@ -1,7 +1,8 @@ use super::*; fn workspace_temp_dir() -> tempfile::TempDir { - let parent = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")) + let parent = crate::test_utils::workspace_root() + .as_path() .join("target") .join("neovm-core-fileio-tests"); std::fs::create_dir_all(&parent).expect("create workspace test directory"); diff --git a/crates/neovm-core/src/emacs_core/system/process/tests/mod.rs b/crates/neovm-core/src/emacs_core/system/process/tests/mod.rs index 01dae86507..52fe608090 100644 --- a/crates/neovm-core/src/emacs_core/system/process/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/system/process/tests/mod.rs @@ -330,7 +330,7 @@ fn tmp_file(label: &str) -> String { .duration_since(std::time::UNIX_EPOCH) .expect("time should be monotonic") .as_nanos(); - let root = Path::new(env!("CARGO_WORKSPACE_DIR")).join("tmp"); + let root = crate::test_utils::workspace_root().as_path().join("tmp"); std::fs::create_dir_all(&root).expect("create workspace temp root"); root.join(format!("neovm-{label}-{}-{nonce}.txt", std::process::id())) .to_string_lossy() @@ -342,7 +342,8 @@ fn tmp_dir(label: &str) -> String { .duration_since(std::time::UNIX_EPOCH) .expect("time should be monotonic") .as_nanos(); - let dir = Path::new(env!("CARGO_WORKSPACE_DIR")) + let dir = crate::test_utils::workspace_root() + .as_path() .join("tmp") .join(format!("neovm-{label}-{}-{nonce}", std::process::id())) .to_string_lossy() @@ -13815,7 +13816,9 @@ fn a_child_that_exited_with_nobody_waiting_is_still_run_here_and_exit_in_gnu() { let sh = find_bin("sh"); // Under the repo's own `target/`, never /tmp (this project's // standing rule), and named per pin so two tests cannot collide. - let marker_dir = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")).join("target/pw193"); + let marker_dir = crate::test_utils::workspace_root() + .as_path() + .join("target/pw193"); std::fs::create_dir_all(&marker_dir).expect("marker dir"); let marker = marker_dir .join("pw193dead.marker") @@ -13915,7 +13918,9 @@ fn an_exited_child_is_a_zombie_here_and_reaped_in_gnu() { let sh = find_bin("sh"); // Under the repo's own `target/`, never /tmp (this project's // standing rule), and named per pin so two tests cannot collide. - let marker_dir = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")).join("target/pw193"); + let marker_dir = crate::test_utils::workspace_root() + .as_path() + .join("target/pw193"); std::fs::create_dir_all(&marker_dir).expect("marker dir"); let marker = marker_dir .join("pw193reap.marker") @@ -14706,7 +14711,9 @@ fn the_child_status_record_is_the_waits_work_and_maybe_quit_never_does_it() { fn delete_process_discards_a_status_recorded_before_it_like_gnu() { crate::test_utils::init_test_tracing(); let sh = find_bin("sh"); - let marker_dir = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")).join("target/pw193"); + let marker_dir = crate::test_utils::workspace_root() + .as_path() + .join("target/pw193"); std::fs::create_dir_all(&marker_dir).expect("marker dir"); let marker = marker_dir .join("pw193delete.marker") @@ -15288,7 +15295,9 @@ fn the_pinned_rows_hold_on_a_build_with_no_sigchld_handler_at_all() { crate::emacs_core::os_signal::install(); let sh = find_bin("sh"); - let marker_dir = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")).join("target/pw200"); + let marker_dir = crate::test_utils::workspace_root() + .as_path() + .join("target/pw200"); std::fs::create_dir_all(&marker_dir).expect("marker dir"); let probe = |tag: &str| { diff --git a/crates/neovm-core/src/emacs_core/system/profiler/mod.rs b/crates/neovm-core/src/emacs_core/system/profiler/mod.rs index 46ddd1edc5..8b5c1d77f5 100644 --- a/crates/neovm-core/src/emacs_core/system/profiler/mod.rs +++ b/crates/neovm-core/src/emacs_core/system/profiler/mod.rs @@ -852,7 +852,8 @@ mod tests { #[test] fn profiler_el_public_memory_workflow_builds_and_renders_a_report() { let mut ctx = crate::emacs_core::load::create_bootstrap_evaluator_cached().unwrap(); - let lisp_root = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")) + let lisp_root = crate::test_utils::workspace_root() + .as_path() .join("lisp") .canonicalize() .unwrap(); diff --git a/crates/neovm-core/src/emacs_core/system/timer/tests/mod.rs b/crates/neovm-core/src/emacs_core/system/timer/tests/mod.rs index 9042cf94c4..6bf5c40c04 100644 --- a/crates/neovm-core/src/emacs_core/system/timer/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/system/timer/tests/mod.rs @@ -38,7 +38,7 @@ fn install_bare_elisp_shims(ev: &mut Context) { } fn gnu_subr_sit_for_eval() -> Context { - let project_root = PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let project_root = crate::test_utils::workspace_root(); let subr_path = project_root.join("lisp/subr.el"); let subr_source = fs::read_to_string(&subr_path).expect("read GNU subr.el"); diff --git a/crates/neovm-core/src/emacs_core/system/tls/tests/runtime.rs b/crates/neovm-core/src/emacs_core/system/tls/tests/runtime.rs index 3ba2c39d7c..09a5f5683b 100644 --- a/crates/neovm-core/src/emacs_core/system/tls/tests/runtime.rs +++ b/crates/neovm-core/src/emacs_core/system/tls/tests/runtime.rs @@ -357,8 +357,8 @@ fn gnutls_boot_parameters_reject_non_string_trust_file_entries() { #[test] fn rustls_root_store_adds_certificates_from_explicit_trust_files() { - let certificate = PathBuf::from(env!("CARGO_WORKSPACE_DIR")) - .join("test/lisp/net/network-stream-resources/cert.pem"); + let certificate = + crate::test_utils::workspace_root().join("test/lisp/net/network-stream-resources/cert.pem"); let default_roots = rustls_root_store(&TlsTrustRoots::Default).expect("default roots"); let augmented_roots = rustls_root_store(&TlsTrustRoots::DefaultPlusFiles(vec![certificate])) .expect("explicit PEM root"); diff --git a/crates/neovm-core/src/emacs_core/tests/build_support/compile_main_rule.rs b/crates/neovm-core/src/emacs_core/tests/build_support/compile_main_rule.rs index 8ec51e94f8..e603787b32 100644 --- a/crates/neovm-core/src/emacs_core/tests/build_support/compile_main_rule.rs +++ b/crates/neovm-core/src/emacs_core/tests/build_support/compile_main_rule.rs @@ -54,7 +54,7 @@ use compile_main_rule::{BytecodeCoverage, LispBytecodeCoverage}; use std::path::PathBuf; fn project_root() -> PathBuf { - PathBuf::from(env!("CARGO_WORKSPACE_DIR")) + crate::test_utils::workspace_root() } /// **The postcondition of GNU's `compile-main`, asserted over the real tree.** diff --git a/crates/neovm-core/src/emacs_core/tests/build_support/generated_lisp.rs b/crates/neovm-core/src/emacs_core/tests/build_support/generated_lisp.rs index 9e0298b23b..342b39397e 100644 --- a/crates/neovm-core/src/emacs_core/tests/build_support/generated_lisp.rs +++ b/crates/neovm-core/src/emacs_core/tests/build_support/generated_lisp.rs @@ -56,7 +56,7 @@ use generated_lisp::{AWK_GENERATED_UNICODE_LISP, AwkGeneratedLisp, GeneratedLisp use std::path::{Path, PathBuf}; fn project_root() -> PathBuf { - PathBuf::from(env!("CARGO_WORKSPACE_DIR")) + crate::test_utils::workspace_root() } /// This checkout, read and written by the same recipes the build scripts run. diff --git a/crates/neovm-core/src/emacs_core/text/chartable/tests/mod.rs b/crates/neovm-core/src/emacs_core/text/chartable/tests/mod.rs index be3c8bdf15..df277c73e3 100644 --- a/crates/neovm-core/src/emacs_core/text/chartable/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/text/chartable/tests/mod.rs @@ -1243,7 +1243,8 @@ fn run_key_from_map_key(key: Value) -> (i64, i64) { #[test] fn unicode_property_table_read_from_generated_uni_category_decodes_ascii() { crate::test_utils::init_test_tracing(); - let path = std::path::Path::new(env!("CARGO_WORKSPACE_DIR")) + let path = crate::test_utils::workspace_root() + .as_path() .join("lisp/international/uni-category.el"); let bytes = std::fs::read(&path).expect("read generated Unicode category table"); let decoded = crate::emacs_core::load::decode_emacs_utf8(&bytes); @@ -1271,8 +1272,9 @@ fn unicode_property_table_read_from_generated_uni_category_decodes_ascii() { #[test] fn unicode_property_table_read_from_generated_uni_bidi_maps_decoded_symbols() { crate::test_utils::init_test_tracing(); - let path = - std::path::Path::new(env!("CARGO_WORKSPACE_DIR")).join("lisp/international/uni-bidi.el"); + let path = crate::test_utils::workspace_root() + .as_path() + .join("lisp/international/uni-bidi.el"); let bytes = std::fs::read(&path).expect("read generated Unicode bidi table"); let decoded = crate::emacs_core::load::decode_emacs_utf8(&bytes); let forms = crate::emacs_core::value_reader::read_all_with_source_multibyte( diff --git a/crates/neovm-core/src/emacs_core/text/regex/tests/mod.rs b/crates/neovm-core/src/emacs_core/text/regex/tests/mod.rs index 8a131f57a8..14eef5bda9 100644 --- a/crates/neovm-core/src/emacs_core/text/regex/tests/mod.rs +++ b/crates/neovm-core/src/emacs_core/text/regex/tests/mod.rs @@ -2967,7 +2967,10 @@ const REGEX_BENCH_FONTLOCK_PATTERNS: &[(&str, &str)] = &[ /// First ~256 KiB of `lisp/subr.el`, cut at a char boundary. fn regex_bench_haystack() -> String { - let path = concat!(env!("CARGO_WORKSPACE_DIR"), "/lisp/subr.el"); + let path = crate::test_utils::workspace_root() + .join("lisp/subr.el") + .to_string_lossy() + .into_owned(); let text = std::fs::read_to_string(path).expect("read lisp/subr.el haystack"); let mut end = text.len().min(256 * 1024); while !text.is_char_boundary(end) { diff --git a/crates/neovm-core/tests/common/mod.rs b/crates/neovm-core/tests/common/mod.rs index 340ad4306a..642343c901 100644 --- a/crates/neovm-core/tests/common/mod.rs +++ b/crates/neovm-core/tests/common/mod.rs @@ -46,7 +46,7 @@ pub fn oracle_enabled() -> bool { #[allow(dead_code)] // grandfathered when dead_code lint was enabled; delete or wire up pub fn repo_root() -> PathBuf { - PathBuf::from(env!("CARGO_WORKSPACE_DIR")) + workspace_root() } #[allow(dead_code)] // grandfathered when dead_code lint was enabled; delete or wire up @@ -179,6 +179,15 @@ pub fn run_oracle_eval(form: &str) -> Result { } #[allow(dead_code)] // grandfathered when dead_code lint was enabled; delete or wire up + +/// Runtime workspace root: nextest's NEXTEST_WORKSPACE_ROOT when present, +/// the compile-time constant otherwise (see neovm-core test_utils). +pub fn workspace_root() -> std::path::PathBuf { + std::env::var_os("NEXTEST_WORKSPACE_ROOT") + .map(std::path::PathBuf::from) + .unwrap_or_else(|| std::path::PathBuf::from(env!("CARGO_WORKSPACE_DIR"))) +} + pub fn run_neovm_eval(form: &str) -> Result { let mut eval = RUNTIME_TEMPLATE.with(|slot| { if slot.borrow().is_none() { diff --git a/crates/neovm-core/tests/compat_face_surface.rs b/crates/neovm-core/tests/compat_face_surface.rs index f6d0af0720..ce715606c6 100644 --- a/crates/neovm-core/tests/compat_face_surface.rs +++ b/crates/neovm-core/tests/compat_face_surface.rs @@ -8,7 +8,7 @@ use common::{oracle_enabled, run_neovm_eval, run_oracle_eval}; use native_regex::Regex as NativeRegex; fn gnu_xfaces_c_path() -> Option { - let mut dir = std::path::PathBuf::from(env!("CARGO_WORKSPACE_DIR")); + let mut dir = common::workspace_root(); for _ in 0..5 { let candidate = dir.join("emacs-mirror/emacs/src/xfaces.c"); if candidate.exists() {