mirror of
https://github.com/nushell/nushell
synced 2025-01-12 21:29:07 +00:00
Virtual std module subdirectories (#14040)
# Description Uses "normal" module `std/<submodule>/mod.nu` instead of renaming the files (as requested in #13842). # User-Facing Changes No user-facing changes other than in `view files` results. Imports remain the same after this PR. # Tests + Formatting - 🟢 `toolkit fmt` - 🟢 `toolkit clippy` - 🟢 `toolkit test` - 🟢 `toolkit test stdlib` Also manually confirmed that it does not interfere with nupm, since we did have a conflict at one point (and it's not possible to test here). # Performance Tests ## Linux ### Nushell Startup - No config ```nu bench --pretty -n 200 { <path_to>/nu -c "exit" } ``` | Release | Startup Time | | --- | --- | | 0.98.0 | 22ms 730µs 768ns +/- 1ms 515µs 942ns | This commit | 9ms 312µs 68ns +/- 709µs 378ns | Yesterday's nightly | 9ms 230µs 953ns +/- 9ms 67µs 689ns ### Nushell Startup - Load full standard library Measures relative impact of a full `use std *`, which isn't recommended, but worth tracking. ```nu bench --pretty -n 200 { <path_to>/nu -c "use std *; exit" } ``` | Release | Startup Time | | --- | --- | | 0.98.0 | 23ms 10µs 636ns +/- 1ms 277µs 854ns | This commit | 26ms 922µs 769ns +/- 562µs 538ns | Yesterday's nightly | 28ms 133µs 95ns +/- 761µs 943ns | `deprecated_dirs` removal PR * | 23ms 610µs 333ns +/- 369µs 436ns \* Current increase is partially due to double-loading `dirs` with removal warning in older version. # After Submitting Still TODO - Update standard library doc
This commit is contained in:
parent
52f646d8db
commit
2a3805c164
15 changed files with 72 additions and 44 deletions
|
@ -5,55 +5,85 @@ use nu_parser::parse;
|
|||
use nu_protocol::{
|
||||
debugger::WithoutDebug,
|
||||
engine::{FileStack, Stack, StateWorkingSet, VirtualPath},
|
||||
report_parse_error, PipelineData,
|
||||
report_parse_error, PipelineData, VirtualPathId,
|
||||
};
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn create_virt_file(working_set: &mut StateWorkingSet, name: &str, content: &str) -> VirtualPathId {
|
||||
let sanitized_name = PathBuf::from(name).to_string_lossy().to_string();
|
||||
let file_id = working_set.add_file(sanitized_name.clone(), content.as_bytes());
|
||||
|
||||
working_set.add_virtual_path(sanitized_name, VirtualPath::File(file_id))
|
||||
}
|
||||
|
||||
pub fn load_standard_library(
|
||||
engine_state: &mut nu_protocol::engine::EngineState,
|
||||
) -> Result<(), miette::ErrReport> {
|
||||
trace!("load_standard_library");
|
||||
|
||||
let mut working_set = StateWorkingSet::new(engine_state);
|
||||
// Contents of the std virtual directory
|
||||
let mut std_virt_paths = vec![];
|
||||
|
||||
// std/mod.nu
|
||||
let std_mod_virt_file_id = create_virt_file(
|
||||
&mut working_set,
|
||||
"std/mod.nu",
|
||||
include_str!("../std/mod.nu"),
|
||||
);
|
||||
std_virt_paths.push(std_mod_virt_file_id);
|
||||
|
||||
// Submodules/subdirectories ... std/<module>/mod.nu
|
||||
let mut std_submodules = vec![
|
||||
// Loaded at startup - Not technically part of std
|
||||
("mod.nu", "std/core", include_str!("../std/core/mod.nu")),
|
||||
// std submodules
|
||||
("mod.nu", "std/assert", include_str!("../std/assert/mod.nu")),
|
||||
("mod.nu", "std/bench", include_str!("../std/bench/mod.nu")),
|
||||
("mod.nu", "std/dirs", include_str!("../std/dirs/mod.nu")),
|
||||
("mod.nu", "std/dt", include_str!("../std/dt/mod.nu")),
|
||||
(
|
||||
"mod.nu",
|
||||
"std/formats",
|
||||
include_str!("../std/formats/mod.nu"),
|
||||
),
|
||||
("mod.nu", "std/help", include_str!("../std/help/mod.nu")),
|
||||
("mod.nu", "std/input", include_str!("../std/input/mod.nu")),
|
||||
("mod.nu", "std/iter", include_str!("../std/iter/mod.nu")),
|
||||
("mod.nu", "std/log", include_str!("../std/log/mod.nu")),
|
||||
("mod.nu", "std/math", include_str!("../std/math/mod.nu")),
|
||||
("mod.nu", "std/util", include_str!("../std/util/mod.nu")),
|
||||
("mod.nu", "std/xml", include_str!("../std/xml/mod.nu")),
|
||||
// Remove in following release
|
||||
(
|
||||
"mod.nu",
|
||||
"std/deprecated_dirs",
|
||||
include_str!("../std/deprecated_dirs/mod.nu"),
|
||||
),
|
||||
];
|
||||
|
||||
for (filename, std_subdir_name, content) in std_submodules.drain(..) {
|
||||
let mod_dir = PathBuf::from(std_subdir_name);
|
||||
let name = mod_dir.join(filename);
|
||||
let virt_file_id = create_virt_file(&mut working_set, &name.to_string_lossy(), content);
|
||||
|
||||
// Place file in virtual subdir
|
||||
let mod_dir_filelist = vec![virt_file_id];
|
||||
|
||||
let virt_dir_id = working_set.add_virtual_path(
|
||||
mod_dir.to_string_lossy().to_string(),
|
||||
VirtualPath::Dir(mod_dir_filelist),
|
||||
);
|
||||
// Add the subdir to the list of paths in std
|
||||
std_virt_paths.push(virt_dir_id);
|
||||
}
|
||||
|
||||
// Create std virtual dir with all subdirs and files
|
||||
let std_dir = PathBuf::from("std").to_string_lossy().to_string();
|
||||
let _ = working_set.add_virtual_path(std_dir, VirtualPath::Dir(std_virt_paths));
|
||||
|
||||
// Load prelude
|
||||
let (block, delta) = {
|
||||
let std_dir = PathBuf::from("std");
|
||||
|
||||
let mut std_files = vec![
|
||||
// Loaded at startup
|
||||
("core", include_str!("../std/core.nu")),
|
||||
// std module - Loads all commands and submodules
|
||||
("mod.nu", include_str!("../std/mod.nu")),
|
||||
// std submodules
|
||||
("assert", include_str!("../std/assert.nu")),
|
||||
("bench", include_str!("../std/bench.nu")),
|
||||
("dirs", include_str!("../std/dirs.nu")),
|
||||
("dt", include_str!("../std/dt.nu")),
|
||||
("formats", include_str!("../std/formats.nu")),
|
||||
("help", include_str!("../std/help.nu")),
|
||||
("input", include_str!("../std/input.nu")),
|
||||
("iter", include_str!("../std/iter.nu")),
|
||||
("log", include_str!("../std/log.nu")),
|
||||
("math", include_str!("../std/math.nu")),
|
||||
("util", include_str!("../std/util.nu")),
|
||||
("xml", include_str!("../std/xml.nu")),
|
||||
// Remove in following release
|
||||
("deprecated_dirs", include_str!("../std/deprecated_dirs.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 = r#"
|
||||
# Prelude
|
||||
use std/core *
|
||||
|
@ -67,8 +97,6 @@ use std/deprecated_dirs [
|
|||
]
|
||||
"#;
|
||||
|
||||
let _ = working_set.add_virtual_path(std_dir, VirtualPath::Dir(std_virt_paths));
|
||||
|
||||
// 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("load std/core");
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use dt [datetime-diff, pretty-print-duration]
|
||||
use std/dt [datetime-diff, pretty-print-duration]
|
||||
|
||||
# Print a banner for nushell with information about the project
|
||||
export def banner [] {
|
Loading…
Reference in a new issue