From 2a3805c164a15e37d3ff4f11a9acfdcbde9a3b03 Mon Sep 17 00:00:00 2001 From: Douglas <32344964+NotTheDr01ds@users.noreply.github.com> Date: Thu, 10 Oct 2024 07:56:37 -0400 Subject: [PATCH] Virtual std module subdirectories (#14040) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description Uses "normal" module `std//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 - :green_circle: `toolkit fmt` - :green_circle: `toolkit clippy` - :green_circle: `toolkit test` - :green_circle: `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 { /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 { /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 --- crates/nu-std/src/lib.rs | 114 +++++++++++------- .../nu-std/std/{assert.nu => assert/mod.nu} | 0 crates/nu-std/std/{bench.nu => bench/mod.nu} | 0 crates/nu-std/std/{core.nu => core/mod.nu} | 2 +- .../mod.nu} | 0 crates/nu-std/std/{dirs.nu => dirs/mod.nu} | 0 crates/nu-std/std/{dt.nu => dt/mod.nu} | 0 .../nu-std/std/{formats.nu => formats/mod.nu} | 0 crates/nu-std/std/{help.nu => help/mod.nu} | 0 crates/nu-std/std/{input.nu => input/mod.nu} | 0 crates/nu-std/std/{iter.nu => iter/mod.nu} | 0 crates/nu-std/std/{log.nu => log/mod.nu} | 0 crates/nu-std/std/{math.nu => math/mod.nu} | 0 crates/nu-std/std/{util.nu => util/mod.nu} | 0 crates/nu-std/std/{xml.nu => xml/mod.nu} | 0 15 files changed, 72 insertions(+), 44 deletions(-) rename crates/nu-std/std/{assert.nu => assert/mod.nu} (100%) rename crates/nu-std/std/{bench.nu => bench/mod.nu} (100%) rename crates/nu-std/std/{core.nu => core/mod.nu} (96%) rename crates/nu-std/std/{deprecated_dirs.nu => deprecated_dirs/mod.nu} (100%) rename crates/nu-std/std/{dirs.nu => dirs/mod.nu} (100%) rename crates/nu-std/std/{dt.nu => dt/mod.nu} (100%) rename crates/nu-std/std/{formats.nu => formats/mod.nu} (100%) rename crates/nu-std/std/{help.nu => help/mod.nu} (100%) rename crates/nu-std/std/{input.nu => input/mod.nu} (100%) rename crates/nu-std/std/{iter.nu => iter/mod.nu} (100%) rename crates/nu-std/std/{log.nu => log/mod.nu} (100%) rename crates/nu-std/std/{math.nu => math/mod.nu} (100%) rename crates/nu-std/std/{util.nu => util/mod.nu} (100%) rename crates/nu-std/std/{xml.nu => xml/mod.nu} (100%) diff --git a/crates/nu-std/src/lib.rs b/crates/nu-std/src/lib.rs index 2857290f41..09585b8697 100644 --- a/crates/nu-std/src/lib.rs +++ b/crates/nu-std/src/lib.rs @@ -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//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"); diff --git a/crates/nu-std/std/assert.nu b/crates/nu-std/std/assert/mod.nu similarity index 100% rename from crates/nu-std/std/assert.nu rename to crates/nu-std/std/assert/mod.nu diff --git a/crates/nu-std/std/bench.nu b/crates/nu-std/std/bench/mod.nu similarity index 100% rename from crates/nu-std/std/bench.nu rename to crates/nu-std/std/bench/mod.nu diff --git a/crates/nu-std/std/core.nu b/crates/nu-std/std/core/mod.nu similarity index 96% rename from crates/nu-std/std/core.nu rename to crates/nu-std/std/core/mod.nu index 1a777bcd0f..3e28937dad 100644 --- a/crates/nu-std/std/core.nu +++ b/crates/nu-std/std/core/mod.nu @@ -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 [] { diff --git a/crates/nu-std/std/deprecated_dirs.nu b/crates/nu-std/std/deprecated_dirs/mod.nu similarity index 100% rename from crates/nu-std/std/deprecated_dirs.nu rename to crates/nu-std/std/deprecated_dirs/mod.nu diff --git a/crates/nu-std/std/dirs.nu b/crates/nu-std/std/dirs/mod.nu similarity index 100% rename from crates/nu-std/std/dirs.nu rename to crates/nu-std/std/dirs/mod.nu diff --git a/crates/nu-std/std/dt.nu b/crates/nu-std/std/dt/mod.nu similarity index 100% rename from crates/nu-std/std/dt.nu rename to crates/nu-std/std/dt/mod.nu diff --git a/crates/nu-std/std/formats.nu b/crates/nu-std/std/formats/mod.nu similarity index 100% rename from crates/nu-std/std/formats.nu rename to crates/nu-std/std/formats/mod.nu diff --git a/crates/nu-std/std/help.nu b/crates/nu-std/std/help/mod.nu similarity index 100% rename from crates/nu-std/std/help.nu rename to crates/nu-std/std/help/mod.nu diff --git a/crates/nu-std/std/input.nu b/crates/nu-std/std/input/mod.nu similarity index 100% rename from crates/nu-std/std/input.nu rename to crates/nu-std/std/input/mod.nu diff --git a/crates/nu-std/std/iter.nu b/crates/nu-std/std/iter/mod.nu similarity index 100% rename from crates/nu-std/std/iter.nu rename to crates/nu-std/std/iter/mod.nu diff --git a/crates/nu-std/std/log.nu b/crates/nu-std/std/log/mod.nu similarity index 100% rename from crates/nu-std/std/log.nu rename to crates/nu-std/std/log/mod.nu diff --git a/crates/nu-std/std/math.nu b/crates/nu-std/std/math/mod.nu similarity index 100% rename from crates/nu-std/std/math.nu rename to crates/nu-std/std/math/mod.nu diff --git a/crates/nu-std/std/util.nu b/crates/nu-std/std/util/mod.nu similarity index 100% rename from crates/nu-std/std/util.nu rename to crates/nu-std/std/util/mod.nu diff --git a/crates/nu-std/std/xml.nu b/crates/nu-std/std/xml/mod.nu similarity index 100% rename from crates/nu-std/std/xml.nu rename to crates/nu-std/std/xml/mod.nu