diff --git a/Cargo.lock b/Cargo.lock index e7ec6435ae..68e0622aa7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2704,6 +2704,18 @@ dependencies = [ "sqlparser 0.33.0", ] +[[package]] +name = "nu-cmd-extra" +version = "0.80.1" +dependencies = [ + "nu-cmd-lang", + "nu-engine", + "nu-parser", + "nu-protocol", + "nu-test-support", + "num-traits", +] + [[package]] name = "nu-cmd-lang" version = "0.80.1" @@ -2774,6 +2786,7 @@ dependencies = [ "notify", "nu-ansi-term", "nu-cmd-dataframe", + "nu-cmd-extra", "nu-cmd-lang", "nu-color-config", "nu-engine", diff --git a/Cargo.toml b/Cargo.toml index b4de279305..3237148d84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ members = [ "crates/nu-engine", "crates/nu-parser", "crates/nu-system", + "crates/nu-cmd-extra", "crates/nu-cmd-lang", "crates/nu-cmd-dataframe", "crates/nu-command", @@ -108,8 +109,6 @@ plugin = [ "nu-protocol/plugin", "nu-engine/plugin", ] -# extra used to be more useful but now it's the same as default. Leaving it in for backcompat with existing build scripts -extra = ["default", "nu-cmd-lang/extra"] default = ["plugin", "which-support", "trash-support", "sqlite"] stable = ["default"] wasi = ["nu-cmd-lang/wasi"] @@ -121,7 +120,8 @@ static-link-openssl = ["dep:openssl", "nu-cmd-lang/static-link-openssl"] which-support = ["nu-command/which-support", "nu-cmd-lang/which-support"] trash-support = ["nu-command/trash-support", "nu-cmd-lang/trash-support"] -# Extra +# Extra feature for nushell +extra = ["nu-command/extra"] # Dataframe feature for nushell dataframe = ["nu-command/dataframe", "nu-cmd-lang/dataframe"] diff --git a/crates/nu-cmd-extra/Cargo.toml b/crates/nu-cmd-extra/Cargo.toml new file mode 100644 index 0000000000..1bfcd6c42e --- /dev/null +++ b/crates/nu-cmd-extra/Cargo.toml @@ -0,0 +1,29 @@ +[package] +authors = ["The Nushell Project Developers"] +description = "Nushell's extra commands that are not part of the 1.0 api standard." +edition = "2021" +license = "MIT" +name = "nu-cmd-extra" +repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-extra" +version = "0.80.1" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +bench = false + +[dependencies] +nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.80.1" } +nu-engine = { path = "../nu-engine", version = "0.80.1" } +nu-parser = { path = "../nu-parser", version = "0.80.1" } +nu-protocol = { path = "../nu-protocol", version = "0.80.1" } + +# Potential dependencies for extras +num-traits = "0.2" + +[features] +extra = ["default"] +default = [] + +[dev-dependencies] +nu-test-support = { path = "../nu-test-support", version = "0.80.1" } diff --git a/crates/nu-cmd-extra/LICENSE b/crates/nu-cmd-extra/LICENSE new file mode 100644 index 0000000000..ae174e8595 --- /dev/null +++ b/crates/nu-cmd-extra/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 - 2023 The Nushell Project Developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/crates/nu-cmd-extra/src/example_test.rs b/crates/nu-cmd-extra/src/example_test.rs new file mode 100644 index 0000000000..7ed7e22f75 --- /dev/null +++ b/crates/nu-cmd-extra/src/example_test.rs @@ -0,0 +1,74 @@ +#[cfg(test)] +use nu_protocol::engine::Command; + +#[cfg(test)] +pub fn test_examples(cmd: impl Command + 'static) { + test_examples::test_examples(cmd); +} + +#[cfg(test)] +mod test_examples { + + use nu_cmd_lang::example_support::{ + check_all_signature_input_output_types_entries_have_examples, + check_example_evaluates_to_expected_output, + check_example_input_and_output_types_match_command_signature, + }; + + use nu_protocol::{ + engine::{Command, EngineState, StateWorkingSet}, + Type, + }; + use std::collections::HashSet; + + pub fn test_examples(cmd: impl Command + 'static) { + let examples = cmd.examples(); + let signature = cmd.signature(); + let mut engine_state = make_engine_state(cmd.clone_box()); + + let cwd = std::env::current_dir().expect("Could not get current working directory."); + + let mut witnessed_type_transformations = HashSet::<(Type, Type)>::new(); + + for example in examples { + if example.result.is_none() { + continue; + } + witnessed_type_transformations.extend( + check_example_input_and_output_types_match_command_signature( + &example, + &cwd, + &mut make_engine_state(cmd.clone_box()), + &signature.input_output_types, + signature.operates_on_cell_paths(), + signature.vectorizes_over_list, + ), + ); + check_example_evaluates_to_expected_output(&example, cwd.as_path(), &mut engine_state); + } + + check_all_signature_input_output_types_entries_have_examples( + signature, + witnessed_type_transformations, + ); + } + + fn make_engine_state(cmd: Box) -> Box { + let mut engine_state = Box::new(EngineState::new()); + + let delta = { + // Base functions that are needed for testing + // Try to keep this working set small to keep tests running as fast as possible + let mut working_set = StateWorkingSet::new(&engine_state); + + // Adding the command that is being tested to the working set + working_set.add_decl(cmd); + working_set.render() + }; + + engine_state + .merge_delta(delta) + .expect("Error merging delta"); + engine_state + } +} diff --git a/crates/nu-command/src/bits/and.rs b/crates/nu-cmd-extra/src/extra/bits/and.rs similarity index 100% rename from crates/nu-command/src/bits/and.rs rename to crates/nu-cmd-extra/src/extra/bits/and.rs diff --git a/crates/nu-command/src/bits/bits_.rs b/crates/nu-cmd-extra/src/extra/bits/bits_.rs similarity index 100% rename from crates/nu-command/src/bits/bits_.rs rename to crates/nu-cmd-extra/src/extra/bits/bits_.rs diff --git a/crates/nu-command/src/bits/mod.rs b/crates/nu-cmd-extra/src/extra/bits/mod.rs similarity index 82% rename from crates/nu-command/src/bits/mod.rs rename to crates/nu-cmd-extra/src/extra/bits/mod.rs index b70bb73b55..9bc6775019 100644 --- a/crates/nu-command/src/bits/mod.rs +++ b/crates/nu-cmd-extra/src/extra/bits/mod.rs @@ -8,6 +8,7 @@ mod shift_left; mod shift_right; mod xor; +use nu_protocol::engine::StateWorkingSet; use nu_protocol::Spanned; pub use and::SubCommand as BitsAnd; @@ -20,6 +21,30 @@ pub use shift_left::SubCommand as BitsShiftLeft; pub use shift_right::SubCommand as BitsShiftRight; pub use xor::SubCommand as BitsXor; +pub fn add_bits_decls(working_set: &mut StateWorkingSet) { + macro_rules! bind_command { + ( $command:expr ) => { + working_set.add_decl(Box::new($command)); + }; + ( $( $command:expr ),* ) => { + $( working_set.add_decl(Box::new($command)); )* + }; + } + + // Dataframe commands + bind_command!( + Bits, + BitsAnd, + BitsNot, + BitsOr, + BitsXor, + BitsRotateLeft, + BitsRotateRight, + BitsShiftLeft, + BitsShiftRight + ); +} + #[derive(Clone, Copy)] enum NumberBytes { One, diff --git a/crates/nu-command/src/bits/not.rs b/crates/nu-cmd-extra/src/extra/bits/not.rs similarity index 100% rename from crates/nu-command/src/bits/not.rs rename to crates/nu-cmd-extra/src/extra/bits/not.rs diff --git a/crates/nu-command/src/bits/or.rs b/crates/nu-cmd-extra/src/extra/bits/or.rs similarity index 100% rename from crates/nu-command/src/bits/or.rs rename to crates/nu-cmd-extra/src/extra/bits/or.rs diff --git a/crates/nu-command/src/bits/rotate_left.rs b/crates/nu-cmd-extra/src/extra/bits/rotate_left.rs similarity index 100% rename from crates/nu-command/src/bits/rotate_left.rs rename to crates/nu-cmd-extra/src/extra/bits/rotate_left.rs diff --git a/crates/nu-command/src/bits/rotate_right.rs b/crates/nu-cmd-extra/src/extra/bits/rotate_right.rs similarity index 100% rename from crates/nu-command/src/bits/rotate_right.rs rename to crates/nu-cmd-extra/src/extra/bits/rotate_right.rs diff --git a/crates/nu-command/src/bits/shift_left.rs b/crates/nu-cmd-extra/src/extra/bits/shift_left.rs similarity index 100% rename from crates/nu-command/src/bits/shift_left.rs rename to crates/nu-cmd-extra/src/extra/bits/shift_left.rs diff --git a/crates/nu-command/src/bits/shift_right.rs b/crates/nu-cmd-extra/src/extra/bits/shift_right.rs similarity index 100% rename from crates/nu-command/src/bits/shift_right.rs rename to crates/nu-cmd-extra/src/extra/bits/shift_right.rs diff --git a/crates/nu-command/src/bits/xor.rs b/crates/nu-cmd-extra/src/extra/bits/xor.rs similarity index 100% rename from crates/nu-command/src/bits/xor.rs rename to crates/nu-cmd-extra/src/extra/bits/xor.rs diff --git a/crates/nu-cmd-extra/src/extra/mod.rs b/crates/nu-cmd-extra/src/extra/mod.rs new file mode 100644 index 0000000000..e63a5b1e14 --- /dev/null +++ b/crates/nu-cmd-extra/src/extra/mod.rs @@ -0,0 +1,9 @@ +mod bits; + +pub use bits::add_bits_decls; + +use nu_protocol::engine::StateWorkingSet; + +pub fn add_extra_decls(working_set: &mut StateWorkingSet) { + add_bits_decls(working_set); +} diff --git a/crates/nu-cmd-extra/src/lib.rs b/crates/nu-cmd-extra/src/lib.rs new file mode 100644 index 0000000000..2a3d70e6cd --- /dev/null +++ b/crates/nu-cmd-extra/src/lib.rs @@ -0,0 +1,6 @@ +mod example_test; +pub mod extra; +pub use extra::*; + +#[cfg(test)] +pub use example_test::test_examples; diff --git a/crates/nu-cmd-lang/Cargo.toml b/crates/nu-cmd-lang/Cargo.toml index 1cfeb2b6e6..d63b46a2eb 100644 --- a/crates/nu-cmd-lang/Cargo.toml +++ b/crates/nu-cmd-lang/Cargo.toml @@ -32,6 +32,4 @@ trash-support = [] sqlite = [] dataframe = [] static-link-openssl = [] -extra = [] wasi = [] - diff --git a/crates/nu-command/Cargo.toml b/crates/nu-command/Cargo.toml index e326ca1bc6..d8702b745d 100644 --- a/crates/nu-command/Cargo.toml +++ b/crates/nu-command/Cargo.toml @@ -15,6 +15,7 @@ bench = false [dependencies] nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.80.1" } nu-cmd-dataframe = { path = "../nu-cmd-dataframe", version = "0.80.1", optional = true } +nu-cmd-extra = { path = "../nu-cmd-extra", version = "0.80.1", optional = true } nu-color-config = { path = "../nu-color-config", version = "0.80.1" } nu-engine = { path = "../nu-engine", version = "0.80.1" } nu-explore = { path = "../nu-explore", version = "0.80.1" } @@ -117,6 +118,7 @@ version = "0.48" [features] dataframe = ["dep:nu-cmd-dataframe"] +extra = ["dep:nu-cmd-extra"] plugin = ["nu-parser/plugin"] sqlite = [ "rusqlite", diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index d7b19afb58..c37adadc21 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -4,6 +4,9 @@ use crate::*; #[cfg(feature = "dataframe")] use nu_cmd_dataframe::*; +#[cfg(feature = "extra")] +use nu_cmd_extra::*; + pub fn create_default_context() -> EngineState { let mut engine_state = nu_cmd_lang::create_default_context(); @@ -20,6 +23,10 @@ pub fn create_default_context() -> EngineState { // they have to be registered before the main declarations. This helps to make // them only accessible if the correct input value category is used with the // declaration + + #[cfg(feature = "extra")] + add_extra_decls(&mut working_set); + #[cfg(feature = "dataframe")] add_dataframe_decls(&mut working_set); @@ -205,19 +212,6 @@ pub fn create_default_context() -> EngineState { StrUpcase }; - // Bits - bind_command! { - Bits, - BitsAnd, - BitsNot, - BitsOr, - BitsXor, - BitsRotateLeft, - BitsRotateRight, - BitsShiftLeft, - BitsShiftRight, - } - // Bytes bind_command! { Bytes, diff --git a/crates/nu-command/src/lib.rs b/crates/nu-command/src/lib.rs index da423ee676..45cbaafd78 100644 --- a/crates/nu-command/src/lib.rs +++ b/crates/nu-command/src/lib.rs @@ -1,4 +1,3 @@ -mod bits; mod bytes; mod charting; mod conversions; @@ -30,7 +29,6 @@ mod system; pub mod util; mod viewers; -pub use bits::*; pub use bytes::*; pub use charting::*; pub use conversions::*; diff --git a/src/tests.rs b/src/tests.rs index 4e1f984e46..309a8b30c3 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "extra")] mod test_bits; mod test_cell_path; mod test_commandline;