fix $env.FILE_PWD and $env.CURRENT_FILE inside use (#14101)

# Description
Fixes: https://github.com/nushell/nushell/issues/13425

It's just a follow up to #13958.

User input can be a directory, in this case, we need to use the return
value of `find_in_dirs_env` carefully, so in case, I renamed
maybe_file_path to maybe_file_path_or_dir to emphasize it.


# User-Facing Changes
`$env.FILE_PWD` and `$env.CURRENT_FILE` will be more reliable to use.

# Tests + Formatting
Added 2 tests
This commit is contained in:
Wind 2024-11-05 14:12:01 +08:00 committed by GitHub
parent e172a621f3
commit 1e051e573d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 63 additions and 7 deletions

View File

@ -98,15 +98,21 @@ This command is a parser keyword. For details, check:
engine_state.get_span_contents(import_pattern.head.span), engine_state.get_span_contents(import_pattern.head.span),
); );
let maybe_file_path = find_in_dirs_env( let maybe_file_path_or_dir = find_in_dirs_env(
&module_arg_str, &module_arg_str,
engine_state, engine_state,
caller_stack, caller_stack,
get_dirs_var_from_call(caller_stack, call), get_dirs_var_from_call(caller_stack, call),
)?; )?;
let maybe_parent = maybe_file_path // module_arg_str maybe a directory, in this case
.as_ref() // find_in_dirs_env returns a directory.
.and_then(|path| path.parent().map(|p| p.to_path_buf())); let maybe_parent = maybe_file_path_or_dir.as_ref().and_then(|path| {
if path.is_dir() {
Some(path.to_path_buf())
} else {
path.parent().map(|p| p.to_path_buf())
}
});
let mut callee_stack = caller_stack let mut callee_stack = caller_stack
.gather_captures(engine_state, &block.captures) .gather_captures(engine_state, &block.captures)
@ -118,9 +124,15 @@ This command is a parser keyword. For details, check:
callee_stack.add_env_var("FILE_PWD".to_string(), file_pwd); callee_stack.add_env_var("FILE_PWD".to_string(), file_pwd);
} }
if let Some(file_path) = maybe_file_path { if let Some(path) = maybe_file_path_or_dir {
let file_path = Value::string(file_path.to_string_lossy(), call.head); let module_file_path = if path.is_dir() {
callee_stack.add_env_var("CURRENT_FILE".to_string(), file_path); // the existence of `mod.nu` is verified in parsing time
// so it's safe to use it here.
Value::string(path.join("mod.nu").to_string_lossy(), call.head)
} else {
Value::string(path.to_string_lossy(), call.head)
};
callee_stack.add_env_var("CURRENT_FILE".to_string(), module_file_path);
} }
let eval_block = get_eval_block(engine_state); let eval_block = get_eval_block(engine_state);

View File

@ -308,3 +308,47 @@ fn can_use_sub_subname_from_submodule() {
let actual = nu!(inp); let actual = nu!(inp);
assert_eq!(actual.out, "bar") assert_eq!(actual.out, "bar")
} }
#[test]
fn test_use_with_printing_file_pwd() {
Playground::setup("use_with_printing_file_pwd", |dirs, nu| {
let file = dirs.test().join("mod.nu");
nu.with_files(&[FileWithContent(
file.as_os_str().to_str().unwrap(),
r#"
export-env {
print $env.FILE_PWD
}
"#,
)]);
let actual = nu!(
cwd: dirs.test(),
"use ."
);
assert_eq!(actual.out, dirs.test().to_string_lossy());
});
}
#[test]
fn test_use_with_printing_current_file() {
Playground::setup("use_with_printing_current_file", |dirs, nu| {
let file = dirs.test().join("mod.nu");
nu.with_files(&[FileWithContent(
file.as_os_str().to_str().unwrap(),
r#"
export-env {
print $env.CURRENT_FILE
}
"#,
)]);
let actual = nu!(
cwd: dirs.test(),
"use ."
);
assert_eq!(actual.out, dirs.test().join("mod.nu").to_string_lossy());
});
}