forked from extern/nushell
Fix circular source causing Nushell to crash (#12262)
# Description EngineState now tracks the script currently running, instead of the parent directory of the script. This also provides an easy way to expose the current running script to the user (Issue #12195). Similarly, StateWorkingSet now tracks scripts instead of directories. `parsed_module_files` and `currently_parsed_pwd` are merged into one variable, `scripts`, which acts like a stack for tracking the current running script (which is on the top of the stack). Circular import check is added for `source` operations, in addition to module import. A simple testcase is added for circular source. <!-- if this PR closes one or more issues, you can automatically link the PR with them by using one of the [*linking keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword), e.g. - this PR should close #xxxx - fixes #xxxx you can also mention related issues, PRs or discussions! --> <!-- Thank you for improving Nushell. Please, check our [contributing guide](../CONTRIBUTING.md) and talk to the core team before making major changes. Description of your pull request goes here. **Provide examples and/or screenshots** if your changes affect the user experience. --> # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> It shouldn't have any user facing changes.
This commit is contained in:
@ -3,7 +3,7 @@ use nu_engine::{env::current_dir, eval_block};
|
||||
use nu_parser::parse;
|
||||
use nu_protocol::{
|
||||
debugger::WithoutDebug,
|
||||
engine::{Stack, StateWorkingSet, VirtualPath},
|
||||
engine::{FileStack, Stack, StateWorkingSet, VirtualPath},
|
||||
report_error, PipelineData,
|
||||
};
|
||||
use std::path::PathBuf;
|
||||
@ -50,10 +50,9 @@ pub fn load_standard_library(
|
||||
}
|
||||
|
||||
let std_dir = std_dir.to_string_lossy().to_string();
|
||||
let source = format!(
|
||||
r#"
|
||||
let source = r#"
|
||||
# Define the `std` module
|
||||
module {std_dir}
|
||||
module std
|
||||
|
||||
# Prelude
|
||||
use std dirs [
|
||||
@ -65,14 +64,14 @@ use std dirs [
|
||||
dexit
|
||||
]
|
||||
use std pwd
|
||||
"#
|
||||
);
|
||||
"#;
|
||||
|
||||
let _ = working_set.add_virtual_path(std_dir, VirtualPath::Dir(std_virt_paths));
|
||||
|
||||
// Change the currently parsed directory
|
||||
let prev_currently_parsed_cwd = working_set.currently_parsed_cwd.clone();
|
||||
working_set.currently_parsed_cwd = Some(PathBuf::from(NU_STDLIB_VIRTUAL_DIR));
|
||||
// Add a placeholder file to the stack of files being evaluated.
|
||||
// The name of this file doesn't matter; it's only there to set the current working directory to NU_STDLIB_VIRTUAL_DIR.
|
||||
let placeholder = PathBuf::from(NU_STDLIB_VIRTUAL_DIR).join("loading stdlib");
|
||||
working_set.files = FileStack::with_file(placeholder);
|
||||
|
||||
let block = parse(
|
||||
&mut working_set,
|
||||
@ -81,13 +80,13 @@ use std pwd
|
||||
false,
|
||||
);
|
||||
|
||||
// Remove the placeholder file from the stack of files being evaluated.
|
||||
working_set.files.pop();
|
||||
|
||||
if let Some(err) = working_set.parse_errors.first() {
|
||||
report_error(&working_set, err);
|
||||
}
|
||||
|
||||
// Restore the currently parsed directory back
|
||||
working_set.currently_parsed_cwd = prev_currently_parsed_cwd;
|
||||
|
||||
(block, working_set.render())
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user