Files
nushell/crates/nu-std/src/lib.rs
Darren Schroeder e97368433b add a few more logging statements for debugging startup (#12316)
# Description

This PR adds a few more `trace!()` and `perf()` statements that allowed
a deeper understanding of the nushell startup process when used with `nu
-n --no-std-lib --log-level trace`.

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2024-03-28 11:27:12 -05:00

107 lines
3.3 KiB
Rust

use log::trace;
use nu_engine::{env::current_dir, eval_block};
use nu_parser::parse;
use nu_protocol::{
debugger::WithoutDebug,
engine::{Stack, StateWorkingSet, VirtualPath},
report_error, PipelineData,
};
use std::path::PathBuf;
// Virtual std directory unlikely to appear in user's file system
const NU_STDLIB_VIRTUAL_DIR: &str = "NU_STDLIB_VIRTUAL_DIR";
pub fn load_standard_library(
engine_state: &mut nu_protocol::engine::EngineState,
) -> Result<(), miette::ErrReport> {
trace!("load_standard_library");
let (block, delta) = {
// Using full virtual path to avoid potential conflicts with user having 'std' directory
// in their working directory.
let std_dir = PathBuf::from(NU_STDLIB_VIRTUAL_DIR).join("std");
let mut std_files = vec![
("mod.nu", include_str!("../std/mod.nu")),
("dirs.nu", include_str!("../std/dirs.nu")),
("dt.nu", include_str!("../std/dt.nu")),
("help.nu", include_str!("../std/help.nu")),
("iter.nu", include_str!("../std/iter.nu")),
("log.nu", include_str!("../std/log.nu")),
("assert.nu", include_str!("../std/assert.nu")),
("xml.nu", include_str!("../std/xml.nu")),
("input.nu", include_str!("../std/input.nu")),
("math.nu", include_str!("../std/math.nu")),
("formats.nu", include_str!("../std/formats.nu")),
];
let mut working_set = StateWorkingSet::new(engine_state);
let mut std_virt_paths = vec![];
for (name, content) in std_files.drain(..) {
let name = std_dir.join(name);
let file_id =
working_set.add_file(name.to_string_lossy().to_string(), content.as_bytes());
let virtual_file_id = working_set.add_virtual_path(
name.to_string_lossy().to_string(),
VirtualPath::File(file_id),
);
std_virt_paths.push(virtual_file_id);
}
let std_dir = std_dir.to_string_lossy().to_string();
let source = format!(
r#"
# Define the `std` module
module {std_dir}
# Prelude
use std dirs [
enter
shells
g
n
p
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));
let block = parse(
&mut working_set,
Some("loading stdlib"),
source.as_bytes(),
false,
);
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())
};
engine_state.merge_delta(delta)?;
// We need to evaluate the module in order to run the `export-env` blocks.
let mut stack = Stack::new();
let pipeline_data = PipelineData::Empty;
eval_block::<WithoutDebug>(engine_state, &mut stack, &block, pipeline_data)?;
let cwd = current_dir(engine_state, &stack)?;
engine_state.merge_env(&mut stack, cwd)?;
Ok(())
}