Remove std::env::set_current_dir() call from EngineState::merge_env() (#12922)

As discussed in https://github.com/nushell/nushell/pull/12749, we no
longer need to call `std::env::set_current_dir()` to sync `$env.PWD`
with the actual working directory. This PR removes the call from
`EngineState::merge_env()`.
This commit is contained in:
YizhePKU 2024-05-23 00:58:27 +08:00 committed by GitHub
parent 75689ec98a
commit 7ede90cba5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 41 additions and 83 deletions

View File

@ -235,15 +235,8 @@ pub fn eval_config_contents(
engine_state.file = prev_file; engine_state.file = prev_file;
// Merge the environment in case env vars changed in the config // Merge the environment in case env vars changed in the config
match engine_state.cwd(Some(stack)) { if let Err(e) = engine_state.merge_env(stack) {
Ok(cwd) => { report_error_new(engine_state, &e);
if let Err(e) = engine_state.merge_env(stack, cwd) {
report_error_new(engine_state, &e);
}
}
Err(e) => {
report_error_new(engine_state, &e);
}
} }
} }
} }

View File

@ -15,10 +15,7 @@ use crate::{
use crossterm::cursor::SetCursorStyle; use crossterm::cursor::SetCursorStyle;
use log::{error, trace, warn}; use log::{error, trace, warn};
use miette::{ErrReport, IntoDiagnostic, Result}; use miette::{ErrReport, IntoDiagnostic, Result};
use nu_cmd_base::{ use nu_cmd_base::{hook::eval_hook, util::get_editor};
hook::eval_hook,
util::{get_editor, get_guaranteed_cwd},
};
use nu_color_config::StyleComputer; use nu_color_config::StyleComputer;
#[allow(deprecated)] #[allow(deprecated)]
use nu_engine::{convert_env_values, current_dir_str, env_to_strings}; use nu_engine::{convert_env_values, current_dir_str, env_to_strings};
@ -118,8 +115,7 @@ pub fn evaluate_repl(
PipelineData::empty(), PipelineData::empty(),
false, false,
); );
let cwd = get_guaranteed_cwd(engine_state, &unique_stack); engine_state.merge_env(&mut unique_stack)?;
engine_state.merge_env(&mut unique_stack, cwd)?;
} }
let hostname = System::host_name(); let hostname = System::host_name();
@ -281,12 +277,10 @@ fn loop_iteration(ctx: LoopContext) -> (bool, Stack, Reedline) {
hostname, hostname,
} = ctx; } = ctx;
let cwd = get_guaranteed_cwd(engine_state, &stack);
let mut start_time = std::time::Instant::now(); let mut start_time = std::time::Instant::now();
// Before doing anything, merge the environment from the previous REPL iteration into the // Before doing anything, merge the environment from the previous REPL iteration into the
// permanent state. // permanent state.
if let Err(err) = engine_state.merge_env(&mut stack, cwd) { if let Err(err) = engine_state.merge_env(&mut stack) {
report_error_new(engine_state, &err); report_error_new(engine_state, &err);
} }
perf( perf(

View File

@ -18,11 +18,11 @@ use support::{
#[fixture] #[fixture]
fn completer() -> NuCompleter { fn completer() -> NuCompleter {
// Create a new engine // Create a new engine
let (dir, _, mut engine, mut stack) = new_engine(); let (_, _, mut engine, mut stack) = new_engine();
// Add record value as example // Add record value as example
let record = "def tst [--mod -s] {}"; let record = "def tst [--mod -s] {}";
assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack, dir).is_ok()); assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack).is_ok());
// Instantiate a new completer // Instantiate a new completer
NuCompleter::new(Arc::new(engine), Arc::new(stack)) NuCompleter::new(Arc::new(engine), Arc::new(stack))
@ -31,12 +31,12 @@ fn completer() -> NuCompleter {
#[fixture] #[fixture]
fn completer_strings() -> NuCompleter { fn completer_strings() -> NuCompleter {
// Create a new engine // Create a new engine
let (dir, _, mut engine, mut stack) = new_engine(); let (_, _, mut engine, mut stack) = new_engine();
// Add record value as example // Add record value as example
let record = r#"def animals [] { ["cat", "dog", "eel" ] } let record = r#"def animals [] { ["cat", "dog", "eel" ] }
def my-command [animal: string@animals] { print $animal }"#; def my-command [animal: string@animals] { print $animal }"#;
assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack, dir).is_ok()); assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack).is_ok());
// Instantiate a new completer // Instantiate a new completer
NuCompleter::new(Arc::new(engine), Arc::new(stack)) NuCompleter::new(Arc::new(engine), Arc::new(stack))
@ -45,7 +45,7 @@ fn completer_strings() -> NuCompleter {
#[fixture] #[fixture]
fn extern_completer() -> NuCompleter { fn extern_completer() -> NuCompleter {
// Create a new engine // Create a new engine
let (dir, _, mut engine, mut stack) = new_engine(); let (_, _, mut engine, mut stack) = new_engine();
// Add record value as example // Add record value as example
let record = r#" let record = r#"
@ -56,7 +56,7 @@ fn extern_completer() -> NuCompleter {
-b: string@animals -b: string@animals
] ]
"#; "#;
assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack, dir).is_ok()); assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack).is_ok());
// Instantiate a new completer // Instantiate a new completer
NuCompleter::new(Arc::new(engine), Arc::new(stack)) NuCompleter::new(Arc::new(engine), Arc::new(stack))
@ -65,7 +65,7 @@ fn extern_completer() -> NuCompleter {
#[fixture] #[fixture]
fn custom_completer() -> NuCompleter { fn custom_completer() -> NuCompleter {
// Create a new engine // Create a new engine
let (dir, _, mut engine, mut stack) = new_engine(); let (_, _, mut engine, mut stack) = new_engine();
// Add record value as example // Add record value as example
let record = r#" let record = r#"
@ -79,7 +79,7 @@ fn custom_completer() -> NuCompleter {
completer: $external_completer completer: $external_completer
} }
"#; "#;
assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack, dir).is_ok()); assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack).is_ok());
// Instantiate a new completer // Instantiate a new completer
NuCompleter::new(Arc::new(engine), Arc::new(stack)) NuCompleter::new(Arc::new(engine), Arc::new(stack))
@ -705,11 +705,11 @@ fn folder_with_directorycompletions() {
#[test] #[test]
fn variables_completions() { fn variables_completions() {
// Create a new engine // Create a new engine
let (dir, _, mut engine, mut stack) = new_engine(); let (_, _, mut engine, mut stack) = new_engine();
// Add record value as example // Add record value as example
let record = "let actor = { name: 'Tom Hardy', age: 44 }"; let record = "let actor = { name: 'Tom Hardy', age: 44 }";
assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack, dir).is_ok()); assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack).is_ok());
// Instantiate a new completer // Instantiate a new completer
let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack));
@ -812,11 +812,11 @@ fn variables_completions() {
#[test] #[test]
fn alias_of_command_and_flags() { fn alias_of_command_and_flags() {
let (dir, _, mut engine, mut stack) = new_engine(); let (_, _, mut engine, mut stack) = new_engine();
// Create an alias // Create an alias
let alias = r#"alias ll = ls -l"#; let alias = r#"alias ll = ls -l"#;
assert!(support::merge_input(alias.as_bytes(), &mut engine, &mut stack, dir).is_ok()); assert!(support::merge_input(alias.as_bytes(), &mut engine, &mut stack).is_ok());
let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack));
@ -831,11 +831,11 @@ fn alias_of_command_and_flags() {
#[test] #[test]
fn alias_of_basic_command() { fn alias_of_basic_command() {
let (dir, _, mut engine, mut stack) = new_engine(); let (_, _, mut engine, mut stack) = new_engine();
// Create an alias // Create an alias
let alias = r#"alias ll = ls "#; let alias = r#"alias ll = ls "#;
assert!(support::merge_input(alias.as_bytes(), &mut engine, &mut stack, dir).is_ok()); assert!(support::merge_input(alias.as_bytes(), &mut engine, &mut stack).is_ok());
let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack));
@ -850,14 +850,14 @@ fn alias_of_basic_command() {
#[test] #[test]
fn alias_of_another_alias() { fn alias_of_another_alias() {
let (dir, _, mut engine, mut stack) = new_engine(); let (_, _, mut engine, mut stack) = new_engine();
// Create an alias // Create an alias
let alias = r#"alias ll = ls -la"#; let alias = r#"alias ll = ls -la"#;
assert!(support::merge_input(alias.as_bytes(), &mut engine, &mut stack, dir.clone()).is_ok()); assert!(support::merge_input(alias.as_bytes(), &mut engine, &mut stack).is_ok());
// Create the second alias // Create the second alias
let alias = r#"alias lf = ll -f"#; let alias = r#"alias lf = ll -f"#;
assert!(support::merge_input(alias.as_bytes(), &mut engine, &mut stack, dir).is_ok()); assert!(support::merge_input(alias.as_bytes(), &mut engine, &mut stack).is_ok());
let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack));
@ -874,7 +874,7 @@ fn run_external_completion(completer: &str, input: &str) -> Vec<Suggestion> {
let completer = format!("$env.config.completions.external.completer = {completer}"); let completer = format!("$env.config.completions.external.completer = {completer}");
// Create a new engine // Create a new engine
let (dir, _, mut engine_state, mut stack) = new_engine(); let (_, _, mut engine_state, mut stack) = new_engine();
let (block, delta) = { let (block, delta) = {
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, completer.as_bytes(), false); let block = parse(&mut working_set, None, completer.as_bytes(), false);
@ -890,7 +890,7 @@ fn run_external_completion(completer: &str, input: &str) -> Vec<Suggestion> {
); );
// Merge environment into the permanent state // Merge environment into the permanent state
assert!(engine_state.merge_env(&mut stack, &dir).is_ok()); assert!(engine_state.merge_env(&mut stack).is_ok());
// Instantiate a new completer // Instantiate a new completer
let mut completer = NuCompleter::new(Arc::new(engine_state), Arc::new(stack)); let mut completer = NuCompleter::new(Arc::new(engine_state), Arc::new(stack));
@ -1068,11 +1068,11 @@ fn custom_completer_triggers_cursor_after_word(mut custom_completer: NuCompleter
#[ignore = "was reverted, still needs fixing"] #[ignore = "was reverted, still needs fixing"]
#[rstest] #[rstest]
fn alias_offset_bug_7648() { fn alias_offset_bug_7648() {
let (dir, _, mut engine, mut stack) = new_engine(); let (_, _, mut engine, mut stack) = new_engine();
// Create an alias // Create an alias
let alias = r#"alias ea = ^$env.EDITOR /tmp/test.s"#; let alias = r#"alias ea = ^$env.EDITOR /tmp/test.s"#;
assert!(support::merge_input(alias.as_bytes(), &mut engine, &mut stack, dir).is_ok()); assert!(support::merge_input(alias.as_bytes(), &mut engine, &mut stack).is_ok());
let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack));
@ -1087,11 +1087,11 @@ fn alias_offset_bug_7648() {
#[ignore = "was reverted, still needs fixing"] #[ignore = "was reverted, still needs fixing"]
#[rstest] #[rstest]
fn alias_offset_bug_7754() { fn alias_offset_bug_7754() {
let (dir, _, mut engine, mut stack) = new_engine(); let (_, _, mut engine, mut stack) = new_engine();
// Create an alias // Create an alias
let alias = r#"alias ll = ls -l"#; let alias = r#"alias ll = ls -l"#;
assert!(support::merge_input(alias.as_bytes(), &mut engine, &mut stack, dir).is_ok()); assert!(support::merge_input(alias.as_bytes(), &mut engine, &mut stack).is_ok());
let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack));

View File

@ -62,7 +62,7 @@ pub fn new_engine() -> (PathBuf, String, EngineState, Stack) {
); );
// Merge environment into the permanent state // Merge environment into the permanent state
let merge_result = engine_state.merge_env(&mut stack, &dir); let merge_result = engine_state.merge_env(&mut stack);
assert!(merge_result.is_ok()); assert!(merge_result.is_ok());
(dir, dir_str, engine_state, stack) (dir, dir_str, engine_state, stack)
@ -97,7 +97,7 @@ pub fn new_quote_engine() -> (PathBuf, String, EngineState, Stack) {
); );
// Merge environment into the permanent state // Merge environment into the permanent state
let merge_result = engine_state.merge_env(&mut stack, &dir); let merge_result = engine_state.merge_env(&mut stack);
assert!(merge_result.is_ok()); assert!(merge_result.is_ok());
(dir, dir_str, engine_state, stack) (dir, dir_str, engine_state, stack)
@ -132,7 +132,7 @@ pub fn new_partial_engine() -> (PathBuf, String, EngineState, Stack) {
); );
// Merge environment into the permanent state // Merge environment into the permanent state
let merge_result = engine_state.merge_env(&mut stack, &dir); let merge_result = engine_state.merge_env(&mut stack);
assert!(merge_result.is_ok()); assert!(merge_result.is_ok());
(dir, dir_str, engine_state, stack) (dir, dir_str, engine_state, stack)
@ -173,7 +173,6 @@ pub fn merge_input(
input: &[u8], input: &[u8],
engine_state: &mut EngineState, engine_state: &mut EngineState,
stack: &mut Stack, stack: &mut Stack,
dir: PathBuf,
) -> Result<(), ShellError> { ) -> Result<(), ShellError> {
let (block, delta) = { let (block, delta) = {
let mut working_set = StateWorkingSet::new(engine_state); let mut working_set = StateWorkingSet::new(engine_state);
@ -196,5 +195,5 @@ pub fn merge_input(
.is_ok()); .is_ok());
// Merge environment into the permanent state // Merge environment into the permanent state
engine_state.merge_env(stack, &dir) engine_state.merge_env(stack)
} }

View File

@ -1,4 +1,3 @@
use crate::util::get_guaranteed_cwd;
use miette::Result; use miette::Result;
use nu_engine::{eval_block, eval_block_with_early_return}; use nu_engine::{eval_block, eval_block_with_early_return};
use nu_parser::parse; use nu_parser::parse;
@ -284,8 +283,7 @@ pub fn eval_hook(
} }
} }
let cwd = get_guaranteed_cwd(engine_state, stack); engine_state.merge_env(stack)?;
engine_state.merge_env(stack, cwd)?;
Ok(output) Ok(output)
} }

View File

@ -138,7 +138,7 @@ pub fn check_example_evaluates_to_expected_output(
stack.add_env_var("PWD".to_string(), Value::test_string(cwd.to_string_lossy())); stack.add_env_var("PWD".to_string(), Value::test_string(cwd.to_string_lossy()));
engine_state engine_state
.merge_env(&mut stack, cwd) .merge_env(&mut stack)
.expect("Error merging environment"); .expect("Error merging environment");
let empty_input = PipelineData::empty(); let empty_input = PipelineData::empty();

View File

@ -277,11 +277,7 @@ impl EngineState {
} }
/// Merge the environment from the runtime Stack into the engine state /// Merge the environment from the runtime Stack into the engine state
pub fn merge_env( pub fn merge_env(&mut self, stack: &mut Stack) -> Result<(), ShellError> {
&mut self,
stack: &mut Stack,
cwd: impl AsRef<Path>,
) -> Result<(), ShellError> {
let mut config_updated = false; let mut config_updated = false;
for mut scope in stack.env_vars.drain(..) { for mut scope in stack.env_vars.drain(..) {
@ -311,9 +307,6 @@ impl EngineState {
} }
} }
// TODO: better error
std::env::set_current_dir(cwd)?;
if config_updated { if config_updated {
// Make plugin GC config changes take effect immediately. // Make plugin GC config changes take effect immediately.
#[cfg(feature = "plugin")] #[cfg(feature = "plugin")]

View File

@ -98,8 +98,7 @@ use std pwd
eval_block::<WithoutDebug>(engine_state, &mut stack, &block, pipeline_data)?; eval_block::<WithoutDebug>(engine_state, &mut stack, &block, pipeline_data)?;
let cwd = engine_state.cwd(Some(&stack))?; engine_state.merge_env(&mut stack)?;
engine_state.merge_env(&mut stack, cwd)?;
Ok(()) Ok(())
} }

View File

@ -164,15 +164,8 @@ pub(crate) fn read_default_env_file(engine_state: &mut EngineState, stack: &mut
); );
// Merge the environment in case env vars changed in the config // Merge the environment in case env vars changed in the config
match engine_state.cwd(Some(stack)) { if let Err(e) = engine_state.merge_env(stack) {
Ok(cwd) => { report_error_new(engine_state, &e);
if let Err(e) = engine_state.merge_env(stack, cwd) {
report_error_new(engine_state, &e);
}
}
Err(e) => {
report_error_new(engine_state, &e);
}
} }
} }
@ -202,15 +195,8 @@ fn eval_default_config(
); );
// Merge the environment in case env vars changed in the config // Merge the environment in case env vars changed in the config
match engine_state.cwd(Some(stack)) { if let Err(e) = engine_state.merge_env(stack) {
Ok(cwd) => { report_error_new(engine_state, &e);
if let Err(e) = engine_state.merge_env(stack, cwd) {
report_error_new(engine_state, &e);
}
}
Err(e) => {
report_error_new(engine_state, &e);
}
} }
} }

View File

@ -250,13 +250,9 @@ pub fn nu_repl() {
for (i, line) in source_lines.iter().enumerate() { for (i, line) in source_lines.iter().enumerate() {
let mut stack = Stack::with_parent(top_stack.clone()); let mut stack = Stack::with_parent(top_stack.clone());
let cwd = engine_state
.cwd(Some(&stack))
.unwrap_or_else(|err| outcome_err(&engine_state, &err));
// Before doing anything, merge the environment from the previous REPL iteration into the // Before doing anything, merge the environment from the previous REPL iteration into the
// permanent state. // permanent state.
if let Err(err) = engine_state.merge_env(&mut stack, &cwd) { if let Err(err) = engine_state.merge_env(&mut stack) {
outcome_err(&engine_state, &err); outcome_err(&engine_state, &err);
} }