Move from source to source-env (#6277)

* start working on source-env

* WIP

* Get most tests working, still one to go

* Fix file-relative paths; Report parser error

* Fix merge conflicts; Restore source as deprecated

* Tests: Use source-env; Remove redundant tests

* Fmt

* Respect hidden env vars

* Fix file-relative eval for source-env

* Add file-relative eval to "overlay use"

* Use FILE_PWD only in source-env and "overlay use"

* Ignore new tests for now

This will be another issue

* Throw an error if setting FILE_PWD manually

* Fix source-related test failures

* Fix nu-check to respect FILE_PWD

* Fix corrupted spans in source-env shell errors

* Fix up some references to old source

* Remove deprecation message

* Re-introduce deleted tests

Co-authored-by: kubouch <kubouch@gmail.com>
This commit is contained in:
JT
2022-09-01 08:32:56 +12:00
committed by GitHub
parent 11531b7630
commit c52d45cb97
33 changed files with 726 additions and 175 deletions

View File

@ -5,6 +5,8 @@ use nu_protocol::ast::PathMember;
use nu_protocol::engine::{EngineState, Stack};
use nu_protocol::{PipelineData, ShellError, Span, Value};
use nu_path::canonicalize_with;
use crate::eval_block;
#[cfg(windows)]
@ -16,6 +18,8 @@ const ENV_PATH_NAME: &str = "PATH";
const ENV_CONVERSIONS: &str = "ENV_CONVERSIONS";
static LIB_DIRS_ENV: &str = "NU_LIB_DIRS";
enum ConversionResult {
Ok(Value),
ConversionError(ShellError), // Failure during the conversion itself
@ -226,6 +230,76 @@ pub fn path_str(
env_to_string(pathname, &pathval, engine_state, stack)
}
/// This helper function is used to find files during eval
///
/// First, the actual current working directory is selected as
/// a) the directory of a file currently being parsed
/// b) current working directory (PWD)
///
/// Then, if the file is not found in the actual cwd, NU_LIB_DIRS is checked.
/// If there is a relative path in NU_LIB_DIRS, it is assumed to be relative to the actual cwd
/// determined in the first step.
///
/// Always returns an absolute path
pub fn find_in_dirs_env(
filename: &str,
engine_state: &EngineState,
stack: &Stack,
) -> Result<Option<PathBuf>, ShellError> {
// Choose whether to use file-relative or PWD-relative path
let cwd = if let Some(pwd) = stack.get_env_var(engine_state, "FILE_PWD") {
match env_to_string("FILE_PWD", &pwd, engine_state, stack) {
Ok(cwd) => {
if Path::new(&cwd).is_absolute() {
cwd
} else {
return Err(ShellError::GenericError(
"Invalid current directory".to_string(),
format!("The 'FILE_PWD' environment variable must be set to an absolute path. Found: '{}'", cwd),
Some(pwd.span()?),
None,
Vec::new()
));
}
}
Err(e) => return Err(e),
}
} else {
current_dir_str(engine_state, stack)?
};
if let Ok(p) = canonicalize_with(filename, &cwd) {
Ok(Some(p))
} else {
let path = Path::new(filename);
if path.is_relative() {
if let Some(lib_dirs) = stack.get_env_var(engine_state, LIB_DIRS_ENV) {
if let Ok(dirs) = lib_dirs.as_list() {
for lib_dir in dirs {
if let Ok(dir) = lib_dir.as_path() {
// make sure the dir is absolute path
if let Ok(dir_abs) = canonicalize_with(&dir, &cwd) {
if let Ok(path) = canonicalize_with(filename, dir_abs) {
return Ok(Some(path));
}
}
}
}
Ok(None)
} else {
Ok(None)
}
} else {
Ok(None)
}
} else {
Ok(None)
}
}
}
fn get_converted_value(
engine_state: &EngineState,
stack: &Stack,

View File

@ -173,6 +173,7 @@ pub fn eval_call(
/// Redirect the environment from callee to the caller.
pub fn redirect_env(engine_state: &EngineState, caller_stack: &mut Stack, callee_stack: &Stack) {
// Grab all environment variables from the callee
let caller_env_vars = caller_stack.get_env_var_names(engine_state);
// remove env vars that are present in the caller but not in the callee