From 81b12d02ec506de05ce55eddbe36f30fa6fc38a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20=C5=BD=C3=A1dn=C3=ADk?= Date: Tue, 15 Nov 2022 00:05:27 +0100 Subject: [PATCH] Change parser cwd when running a file (#7134) * Change parser cwd when running a file * Add test * Add missing file --- crates/nu-cli/src/eval_file.rs | 2 ++ crates/nu-protocol/src/engine/engine_state.rs | 14 +++++++++++++- tests/parsing/mod.rs | 9 +++++++++ tests/parsing/samples/source_file_relative.nu | 1 + 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 tests/parsing/samples/source_file_relative.nu diff --git a/crates/nu-cli/src/eval_file.rs b/crates/nu-cli/src/eval_file.rs index cdddeb319a..5160d8184a 100644 --- a/crates/nu-cli/src/eval_file.rs +++ b/crates/nu-cli/src/eval_file.rs @@ -29,6 +29,8 @@ pub fn evaluate_file( let file = std::fs::read(&path).into_diagnostic()?; + engine_state.start_in_file(Some(&path)); + let mut working_set = StateWorkingSet::new(engine_state); trace!("parsing file: {}", path); diff --git a/crates/nu-protocol/src/engine/engine_state.rs b/crates/nu-protocol/src/engine/engine_state.rs index 0d59963e26..a41cf32958 100644 --- a/crates/nu-protocol/src/engine/engine_state.rs +++ b/crates/nu-protocol/src/engine/engine_state.rs @@ -92,6 +92,8 @@ pub struct EngineState { sig_quit: Option>, config_path: HashMap, pub history_session_id: i64, + // If Nushell was started, e.g., with `nu spam.nu`, the file's parent is stored here + pub currently_parsed_cwd: Option, } pub const NU_VARIABLE_ID: usize = 0; @@ -134,6 +136,7 @@ impl EngineState { sig_quit: None, config_path: HashMap::new(), history_session_id: 0, + currently_parsed_cwd: None, } } @@ -251,6 +254,15 @@ impl EngineState { Ok(()) } + /// Mark a starting point if it is a script (e.g., nu spam.nu) + pub fn start_in_file(&mut self, file_path: Option<&str>) { + self.currently_parsed_cwd = if let Some(path) = file_path { + Path::new(path).parent().map(PathBuf::from) + } else { + None + }; + } + pub fn has_overlay(&self, name: &[u8]) -> bool { self.scope .overlays @@ -987,7 +999,7 @@ impl<'a> StateWorkingSet<'a> { permanent_state, external_commands: vec![], type_scope: TypeScope::default(), - currently_parsed_cwd: None, + currently_parsed_cwd: permanent_state.currently_parsed_cwd.clone(), parsed_module_files: vec![], } } diff --git a/tests/parsing/mod.rs b/tests/parsing/mod.rs index 5af365fe09..e84165ca85 100644 --- a/tests/parsing/mod.rs +++ b/tests/parsing/mod.rs @@ -2,6 +2,15 @@ use nu_test_support::fs::Stub::FileWithContentToBeTrimmed; use nu_test_support::playground::Playground; use nu_test_support::{nu, pipeline}; +#[test] +fn source_file_relative_to_file() { + let actual = nu!(cwd: "tests/parsing/samples", r#" + nu source_file_relative.nu + "#); + + assert_eq!(actual.out, "5"); +} + #[test] fn run_nu_script_single_line() { let actual = nu!(cwd: "tests/parsing/samples", r#" diff --git a/tests/parsing/samples/source_file_relative.nu b/tests/parsing/samples/source_file_relative.nu new file mode 100644 index 0000000000..991c7e7957 --- /dev/null +++ b/tests/parsing/samples/source_file_relative.nu @@ -0,0 +1 @@ +source single_line.nu