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

@@ -1,4 +1,4 @@
use nu_engine::{current_dir, CallExt};
use nu_engine::{find_in_dirs_env, CallExt};
use nu_parser::{parse, parse_module_block, unescape_unquote_string};
use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EngineState, Stack, StateWorkingSet};
@@ -6,8 +6,6 @@ use nu_protocol::{
Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value,
};
use std::path::Path;
#[derive(Clone)]
pub struct NuCheck;
@@ -18,7 +16,8 @@ impl Command for NuCheck {
fn signature(&self) -> Signature {
Signature::build("nu-check")
.optional("path", SyntaxShape::Filepath, "File path to parse")
// type is string to avoid automatically canonicalizing the path
.optional("path", SyntaxShape::String, "File path to parse")
.switch("as-module", "Parse content as module", Some('m'))
.switch("debug", "Show error messages", Some('d'))
.switch("all", "Parse content as script first, returns result if success, otherwise, try with module", Some('a'))
@@ -102,13 +101,23 @@ impl Command for NuCheck {
}
}
_ => {
if path.is_some() {
let path = match find_path(path, engine_state, stack, call.head) {
Ok(path) => path,
if let Some(path_str) = path {
// look up the path as relative to FILE_PWD or inside NU_LIB_DIRS (same process as source-env)
let path = match find_in_dirs_env(&path_str.item, engine_state, stack) {
Ok(path) => {
if let Some(path) = path {
path
} else {
return Err(ShellError::FileNotFound(path_str.span));
}
}
Err(error) => return Err(error),
};
let ext: Vec<_> = path.rsplitn(2, '.').collect();
// get the expanded path as a string
let path_str = path.to_string_lossy().to_string();
let ext: Vec<_> = path_str.rsplitn(2, '.').collect();
if ext[0] != "nu" {
return Err(ShellError::GenericError(
"Cannot parse input".to_string(),
@@ -120,8 +129,7 @@ impl Command for NuCheck {
}
// Change currently parsed directory
let prev_currently_parsed_cwd = if let Some(parent) = Path::new(&path).parent()
{
let prev_currently_parsed_cwd = if let Some(parent) = path.parent() {
let prev = working_set.currently_parsed_cwd.clone();
working_set.currently_parsed_cwd = Some(parent.into());
@@ -132,11 +140,11 @@ impl Command for NuCheck {
};
let result = if is_all {
heuristic_parse_file(path, &mut working_set, call, is_debug)
heuristic_parse_file(path_str, &mut working_set, call, is_debug)
} else if is_module {
parse_file_module(path, &mut working_set, call, is_debug)
parse_file_module(path_str, &mut working_set, call, is_debug)
} else {
parse_file_script(path, &mut working_set, call, is_debug)
parse_file_script(path_str, &mut working_set, call, is_debug)
};
// Restore the currently parsed directory back
@@ -202,46 +210,6 @@ impl Command for NuCheck {
}
}
fn find_path(
path: Option<Spanned<String>>,
engine_state: &EngineState,
stack: &mut Stack,
span: Span,
) -> Result<String, ShellError> {
let cwd = current_dir(engine_state, stack)?;
let path = match path {
Some(s) => {
let path_no_whitespace = &s.item.trim_end_matches(|x| matches!(x, '\x09'..='\x0d'));
let path = match nu_path::canonicalize_with(path_no_whitespace, &cwd) {
Ok(p) => {
if !p.is_file() {
return Err(ShellError::GenericError(
"Cannot parse input".to_string(),
"Path is not a file".to_string(),
Some(s.span),
None,
Vec::new(),
));
} else {
p
}
}
Err(_) => {
return Err(ShellError::FileNotFound(s.span));
}
};
path.to_string_lossy().to_string()
}
None => {
return Err(ShellError::NotFound(span));
}
};
Ok(path)
}
fn heuristic_parse(
working_set: &mut StateWorkingSet,
filename: Option<&str>,