From bae04352cafae32057133795a916127d8f5617c2 Mon Sep 17 00:00:00 2001 From: Wind Date: Mon, 21 Apr 2025 20:09:08 +0800 Subject: [PATCH] overlay use: keep PWD after activating the overlay thought file. (#15566) # Description Fixes: #14048 The issue happened when re-using a ***module file***, and the overlay already has already saved `PWD`, then nushell restores the `PWD` variable after activating it. This pr is going to fix it by restoring `PWD` after re-using a module file. # User-Facing Changes `overlay use spam.nu` will always keep `PWD`, if `spam.nu` itself doesn't change `PWD` while activating. # Tests + Formatting Added 2 tests. # After Submitting NaN --- .../src/core_commands/overlay/use_.rs | 10 ++++++ tests/overlays/mod.rs | 36 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/crates/nu-cmd-lang/src/core_commands/overlay/use_.rs b/crates/nu-cmd-lang/src/core_commands/overlay/use_.rs index c8ad90e518..2fe77d548e 100644 --- a/crates/nu-cmd-lang/src/core_commands/overlay/use_.rs +++ b/crates/nu-cmd-lang/src/core_commands/overlay/use_.rs @@ -116,6 +116,8 @@ impl Command for OverlayUse { // b) refreshing an active overlay (the origin module changed) let module = engine_state.get_module(module_id); + // in such case, should also make sure that PWD is not restored in old overlays. + let cwd = caller_stack.get_env_var(engine_state, "PWD").cloned(); // Evaluate the export-env block (if any) and keep its environment if let Some(block_id) = module.env_block { @@ -160,11 +162,19 @@ impl Command for OverlayUse { // The export-env block should see the env vars *before* activating this overlay caller_stack.add_overlay(overlay_name); + // make sure that PWD is not restored in old overlays. + if let Some(cwd) = cwd { + caller_stack.add_env_var("PWD".to_string(), cwd); + } // Merge the block's environment to the current stack redirect_env(engine_state, caller_stack, &callee_stack); } else { caller_stack.add_overlay(overlay_name); + // make sure that PWD is not restored in old overlays. + if let Some(cwd) = cwd { + caller_stack.add_env_var("PWD".to_string(), cwd); + } } } else { caller_stack.add_overlay(overlay_name); diff --git a/tests/overlays/mod.rs b/tests/overlays/mod.rs index 63dd6d6446..40fe45b1a7 100644 --- a/tests/overlays/mod.rs +++ b/tests/overlays/mod.rs @@ -720,6 +720,42 @@ fn overlay_keep_pwd() { assert_eq!(actual_repl.out, "samples"); } +#[test] +fn overlay_reactivate_with_nufile_should_not_change_pwd() { + let inp = &[ + "overlay use spam.nu", + "cd ..", + "overlay hide --keep-env [ PWD ] spam", + "cd samples", + "overlay use spam.nu", + "$env.PWD | path basename", + ]; + + let actual = nu!(cwd: "tests/overlays/samples", &inp.join("; ")); + let actual_repl = nu!(cwd: "tests/overlays/samples", nu_repl_code(inp)); + + assert_eq!(actual.out, "samples"); + assert_eq!(actual_repl.out, "samples"); +} + +#[test] +fn overlay_reactivate_with_module_name_should_change_pwd() { + let inp = &[ + "overlay use spam.nu", + "cd ..", + "overlay hide --keep-env [ PWD ] spam", + "cd samples", + "overlay use spam", + "$env.PWD | path basename", + ]; + + let actual = nu!(cwd: "tests/overlays/samples", &inp.join("; ")); + let actual_repl = nu!(cwd: "tests/overlays/samples", nu_repl_code(inp)); + + assert_eq!(actual.out, "overlays"); + assert_eq!(actual_repl.out, "overlays"); +} + #[test] fn overlay_wrong_rename_type() { let inp = &["module spam {}", "overlay use spam as { echo foo }"];