Skip to content

Commit 8ddebcb

Browse files
authored
Add $env.CURRENT_FILE variable (#8861)
Co-authored-by: Jelle Besseling <jelle@bigbridge.nl>
1 parent b2d7427 commit 8ddebcb

7 files changed

Lines changed: 48 additions & 22 deletions

File tree

crates/nu-cli/src/eval_file.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ pub fn evaluate_file(
9393
"FILE_PWD".to_string(),
9494
Value::string(parent.to_string_lossy(), Span::unknown()),
9595
);
96+
stack.add_env_var(
97+
"CURRENT_FILE".to_string(),
98+
Value::string(file_path.to_string_lossy(), Span::unknown()),
99+
);
96100

97101
let mut working_set = StateWorkingSet::new(engine_state);
98102
trace!("parsing file: {}", file_path_str);

crates/nu-cmd-lang/src/core_commands/overlay/use_.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ impl Command for OverlayUse {
134134
callee_stack.add_env_var("FILE_PWD".to_string(), file_pwd);
135135
}
136136

137+
if let Some(file_path) = &maybe_path {
138+
let file_path = Value::string(file_path.to_string_lossy(), call.head);
139+
callee_stack.add_env_var("CURRENT_FILE".to_string(), file_path);
140+
}
141+
137142
let _ = eval_block(
138143
engine_state,
139144
&mut callee_stack,

crates/nu-cmd-lang/src/core_commands/use_.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,16 @@ impl Command for Use {
7272
let module_arg_str = String::from_utf8_lossy(
7373
engine_state.get_span_contents(&import_pattern.head.span),
7474
);
75-
let maybe_parent = if let Some(path) = find_in_dirs_env(
75+
76+
let maybe_file_path = find_in_dirs_env(
7677
&module_arg_str,
7778
engine_state,
7879
caller_stack,
7980
get_dirs_var_from_call(call),
80-
)? {
81-
path.parent().map(|p| p.to_path_buf()).or(None)
82-
} else {
83-
None
84-
};
81+
)?;
82+
let maybe_parent = maybe_file_path
83+
.as_ref()
84+
.and_then(|path| path.parent().map(|p| p.to_path_buf()));
8585

8686
let mut callee_stack = caller_stack.gather_captures(&block.captures);
8787

@@ -91,6 +91,11 @@ impl Command for Use {
9191
callee_stack.add_env_var("FILE_PWD".to_string(), file_pwd);
9292
}
9393

94+
if let Some(file_path) = maybe_file_path {
95+
let file_path = Value::string(file_path.to_string_lossy(), call.head);
96+
callee_stack.add_env_var("CURRENT_FILE".to_string(), file_path);
97+
}
98+
9499
// Run the block (discard the result)
95100
let _ = eval_block(
96101
engine_state,

crates/nu-command/src/env/let_env.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ impl Command for LetEnv {
5151
.0
5252
.into_value(call.head);
5353

54-
if env_var.item == "FILE_PWD" || env_var.item == "PWD" {
54+
if env_var.item == "FILE_PWD" || env_var.item == "CURRENT_FILE" || env_var.item == "PWD" {
5555
return Err(ShellError::AutomaticEnvVarSetManually {
5656
envvar_name: env_var.item,
5757
span: env_var.span,

crates/nu-command/src/env/load_env.rs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,28 +42,22 @@ impl Command for LoadEnv {
4242
match arg {
4343
Some((cols, vals)) => {
4444
for (env_var, rhs) in cols.into_iter().zip(vals) {
45-
if env_var == "FILE_PWD" {
45+
let env_var_ = env_var.as_str();
46+
if ["FILE_PWD", "CURRENT_FILE", "PWD"].contains(&env_var_) {
4647
return Err(ShellError::AutomaticEnvVarSetManually {
4748
envvar_name: env_var,
4849
span: call.head,
4950
});
5051
}
51-
52-
if env_var == "PWD" {
53-
return Err(ShellError::AutomaticEnvVarSetManually {
54-
envvar_name: env_var,
55-
span: call.head,
56-
});
57-
} else {
58-
stack.add_env_var(env_var, rhs);
59-
}
52+
stack.add_env_var(env_var, rhs);
6053
}
6154
Ok(PipelineData::empty())
6255
}
6356
None => match input {
6457
PipelineData::Value(Value::Record { cols, vals, .. }, ..) => {
6558
for (env_var, rhs) in cols.into_iter().zip(vals) {
66-
if env_var == "FILE_PWD" {
59+
let env_var_ = env_var.as_str();
60+
if ["FILE_PWD", "CURRENT_FILE"].contains(&env_var_) {
6761
return Err(ShellError::AutomaticEnvVarSetManually {
6862
envvar_name: env_var,
6963
span: call.head,

crates/nu-command/src/env/source_env.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ impl Command for SourceEnv {
4747
let block_id: i64 = call.req_parser_info(engine_state, caller_stack, "block_id")?;
4848

4949
// Set the currently evaluated directory (file-relative PWD)
50-
let mut parent = if let Some(path) = find_in_dirs_env(
50+
let file_path = if let Some(path) = find_in_dirs_env(
5151
&source_filename.item,
5252
engine_state,
5353
caller_stack,
@@ -57,11 +57,17 @@ impl Command for SourceEnv {
5757
} else {
5858
return Err(ShellError::FileNotFound(source_filename.span));
5959
};
60-
parent.pop();
6160

62-
let file_pwd = Value::string(parent.to_string_lossy(), call.head);
61+
if let Some(parent) = file_path.parent() {
62+
let file_pwd = Value::string(parent.to_string_lossy(), call.head);
6363

64-
caller_stack.add_env_var("FILE_PWD".to_string(), file_pwd);
64+
caller_stack.add_env_var("FILE_PWD".to_string(), file_pwd);
65+
}
66+
67+
caller_stack.add_env_var(
68+
"CURRENT_FILE".to_string(),
69+
Value::string(file_path.to_string_lossy(), call.head),
70+
);
6571

6672
// Evaluate the block
6773
let block = engine_state.get_block(block_id as usize).clone();
@@ -81,6 +87,7 @@ impl Command for SourceEnv {
8187

8288
// Remove the file-relative PWD
8389
caller_stack.remove_env_var(engine_state, "FILE_PWD");
90+
caller_stack.remove_env_var(engine_state, "CURRENT_FILE");
8491

8592
result
8693
}

tests/shell/environment/env.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,17 @@ fn has_file_pwd() {
126126
})
127127
}
128128

129+
#[test]
130+
fn has_file_loc() {
131+
Playground::setup("has_file_pwd", |dirs, sandbox| {
132+
sandbox.with_files(vec![FileWithContent("spam.nu", "$env.CURRENT_FILE")]);
133+
134+
let actual = nu!(cwd: dirs.test(), "nu spam.nu");
135+
136+
assert!(actual.out.ends_with("spam.nu"));
137+
})
138+
}
139+
129140
// FIXME: autoenv not currently implemented
130141
#[ignore]
131142
#[test]

0 commit comments

Comments
 (0)