From 8ddebcb932ed9ccd6a317fecda943140b0fb931a Mon Sep 17 00:00:00 2001 From: Jelle Besseling Date: Thu, 13 Apr 2023 22:33:29 +0200 Subject: [PATCH] Add $env.CURRENT_FILE variable (#8861) Co-authored-by: Jelle Besseling --- crates/nu-cli/src/eval_file.rs | 4 ++++ .../src/core_commands/overlay/use_.rs | 5 +++++ crates/nu-cmd-lang/src/core_commands/use_.rs | 17 +++++++++++------ crates/nu-command/src/env/let_env.rs | 2 +- crates/nu-command/src/env/load_env.rs | 16 +++++----------- crates/nu-command/src/env/source_env.rs | 15 +++++++++++---- tests/shell/environment/env.rs | 11 +++++++++++ 7 files changed, 48 insertions(+), 22 deletions(-) diff --git a/crates/nu-cli/src/eval_file.rs b/crates/nu-cli/src/eval_file.rs index b14fe5fb2c..f6c0226fef 100644 --- a/crates/nu-cli/src/eval_file.rs +++ b/crates/nu-cli/src/eval_file.rs @@ -93,6 +93,10 @@ pub fn evaluate_file( "FILE_PWD".to_string(), Value::string(parent.to_string_lossy(), Span::unknown()), ); + stack.add_env_var( + "CURRENT_FILE".to_string(), + Value::string(file_path.to_string_lossy(), Span::unknown()), + ); let mut working_set = StateWorkingSet::new(engine_state); trace!("parsing file: {}", file_path_str); 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 e64acbae8d..1917bb6c3e 100644 --- a/crates/nu-cmd-lang/src/core_commands/overlay/use_.rs +++ b/crates/nu-cmd-lang/src/core_commands/overlay/use_.rs @@ -134,6 +134,11 @@ impl Command for OverlayUse { callee_stack.add_env_var("FILE_PWD".to_string(), file_pwd); } + if let Some(file_path) = &maybe_path { + let file_path = Value::string(file_path.to_string_lossy(), call.head); + callee_stack.add_env_var("CURRENT_FILE".to_string(), file_path); + } + let _ = eval_block( engine_state, &mut callee_stack, diff --git a/crates/nu-cmd-lang/src/core_commands/use_.rs b/crates/nu-cmd-lang/src/core_commands/use_.rs index 5bfb0b9203..cbcef1b769 100644 --- a/crates/nu-cmd-lang/src/core_commands/use_.rs +++ b/crates/nu-cmd-lang/src/core_commands/use_.rs @@ -72,16 +72,16 @@ impl Command for Use { let module_arg_str = String::from_utf8_lossy( engine_state.get_span_contents(&import_pattern.head.span), ); - let maybe_parent = if let Some(path) = find_in_dirs_env( + + let maybe_file_path = find_in_dirs_env( &module_arg_str, engine_state, caller_stack, get_dirs_var_from_call(call), - )? { - path.parent().map(|p| p.to_path_buf()).or(None) - } else { - None - }; + )?; + let maybe_parent = maybe_file_path + .as_ref() + .and_then(|path| path.parent().map(|p| p.to_path_buf())); let mut callee_stack = caller_stack.gather_captures(&block.captures); @@ -91,6 +91,11 @@ impl Command for Use { callee_stack.add_env_var("FILE_PWD".to_string(), file_pwd); } + if let Some(file_path) = maybe_file_path { + let file_path = Value::string(file_path.to_string_lossy(), call.head); + callee_stack.add_env_var("CURRENT_FILE".to_string(), file_path); + } + // Run the block (discard the result) let _ = eval_block( engine_state, diff --git a/crates/nu-command/src/env/let_env.rs b/crates/nu-command/src/env/let_env.rs index e3ce4fa33f..d49aa1f22e 100644 --- a/crates/nu-command/src/env/let_env.rs +++ b/crates/nu-command/src/env/let_env.rs @@ -51,7 +51,7 @@ impl Command for LetEnv { .0 .into_value(call.head); - if env_var.item == "FILE_PWD" || env_var.item == "PWD" { + if env_var.item == "FILE_PWD" || env_var.item == "CURRENT_FILE" || env_var.item == "PWD" { return Err(ShellError::AutomaticEnvVarSetManually { envvar_name: env_var.item, span: env_var.span, diff --git a/crates/nu-command/src/env/load_env.rs b/crates/nu-command/src/env/load_env.rs index 485cd8e51b..618feeaa76 100644 --- a/crates/nu-command/src/env/load_env.rs +++ b/crates/nu-command/src/env/load_env.rs @@ -42,28 +42,22 @@ impl Command for LoadEnv { match arg { Some((cols, vals)) => { for (env_var, rhs) in cols.into_iter().zip(vals) { - if env_var == "FILE_PWD" { + let env_var_ = env_var.as_str(); + if ["FILE_PWD", "CURRENT_FILE", "PWD"].contains(&env_var_) { return Err(ShellError::AutomaticEnvVarSetManually { envvar_name: env_var, span: call.head, }); } - - if env_var == "PWD" { - return Err(ShellError::AutomaticEnvVarSetManually { - envvar_name: env_var, - span: call.head, - }); - } else { - stack.add_env_var(env_var, rhs); - } + stack.add_env_var(env_var, rhs); } Ok(PipelineData::empty()) } None => match input { PipelineData::Value(Value::Record { cols, vals, .. }, ..) => { for (env_var, rhs) in cols.into_iter().zip(vals) { - if env_var == "FILE_PWD" { + let env_var_ = env_var.as_str(); + if ["FILE_PWD", "CURRENT_FILE"].contains(&env_var_) { return Err(ShellError::AutomaticEnvVarSetManually { envvar_name: env_var, span: call.head, diff --git a/crates/nu-command/src/env/source_env.rs b/crates/nu-command/src/env/source_env.rs index c77008b699..fafd628b3f 100644 --- a/crates/nu-command/src/env/source_env.rs +++ b/crates/nu-command/src/env/source_env.rs @@ -47,7 +47,7 @@ impl Command for SourceEnv { let block_id: i64 = call.req_parser_info(engine_state, caller_stack, "block_id")?; // Set the currently evaluated directory (file-relative PWD) - let mut parent = if let Some(path) = find_in_dirs_env( + let file_path = if let Some(path) = find_in_dirs_env( &source_filename.item, engine_state, caller_stack, @@ -57,11 +57,17 @@ impl Command for SourceEnv { } else { return Err(ShellError::FileNotFound(source_filename.span)); }; - parent.pop(); - let file_pwd = Value::string(parent.to_string_lossy(), call.head); + if let Some(parent) = file_path.parent() { + let file_pwd = Value::string(parent.to_string_lossy(), call.head); - caller_stack.add_env_var("FILE_PWD".to_string(), file_pwd); + caller_stack.add_env_var("FILE_PWD".to_string(), file_pwd); + } + + caller_stack.add_env_var( + "CURRENT_FILE".to_string(), + Value::string(file_path.to_string_lossy(), call.head), + ); // Evaluate the block let block = engine_state.get_block(block_id as usize).clone(); @@ -81,6 +87,7 @@ impl Command for SourceEnv { // Remove the file-relative PWD caller_stack.remove_env_var(engine_state, "FILE_PWD"); + caller_stack.remove_env_var(engine_state, "CURRENT_FILE"); result } diff --git a/tests/shell/environment/env.rs b/tests/shell/environment/env.rs index 81e63886e6..a62a7b4028 100644 --- a/tests/shell/environment/env.rs +++ b/tests/shell/environment/env.rs @@ -126,6 +126,17 @@ fn has_file_pwd() { }) } +#[test] +fn has_file_loc() { + Playground::setup("has_file_pwd", |dirs, sandbox| { + sandbox.with_files(vec![FileWithContent("spam.nu", "$env.CURRENT_FILE")]); + + let actual = nu!(cwd: dirs.test(), "nu spam.nu"); + + assert!(actual.out.ends_with("spam.nu")); + }) +} + // FIXME: autoenv not currently implemented #[ignore] #[test]