From a19cac2673614c726ab210fb3a7ab3e1bf93e197 Mon Sep 17 00:00:00 2001 From: Poliorcetics Date: Mon, 25 Sep 2023 15:00:59 +0200 Subject: [PATCH] Command: Add `config env/nu --default` to print defaults (#10480) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description Closes #5436 When I opened this issue more than a year ago, I mainly wanted the following capacity: easily access the full env and have the hability to update it when a new version of `nushell` comes out. With this PR I can now do the following: ```nu source-env ~/.config/nushell/defaults/env.nu source ~/.config/nushell/defaults/config.nu # Update nushell default config & env file (run this after a version update) def update-defaults [] { config env --default | save -f ~/.config/nushell/defaults/env.nu config nu --default | save -f ~/.config/nushell/defaults/config.nu } ``` Which is more than enough for me. Along with `nushell` respecting the XDG spec on macOS (`dirs-next` should be banned for CLI tools on macOS), this should be one of the last hurdle before fully switching for me! # User-Facing Changes Two new switches to existing commands: ```nu config env --default # Print the default env embedded at compile time in the binary config nu --default # Print the default config embedded at compile time in the binary ``` # Tests + Formatting - Added a test for the output of `config env --default` - Added a test for the output of `config nu --default` # After Submitting Are the docs for commands generated automatically or do I need to make a PR there too ? It's no problem if so, just point me at instructions if there are any :) --- .../nu-command/src/env/config/config_env.rs | 36 +++++++++++++---- crates/nu-command/src/env/config/config_nu.rs | 40 +++++++++++++++---- .../tests/commands/config_env_default.rs | 11 +++++ .../tests/commands/config_nu_default.rs | 11 +++++ crates/nu-command/tests/commands/mod.rs | 2 + 5 files changed, 86 insertions(+), 14 deletions(-) create mode 100644 crates/nu-command/tests/commands/config_env_default.rs create mode 100644 crates/nu-command/tests/commands/config_nu_default.rs diff --git a/crates/nu-command/src/env/config/config_env.rs b/crates/nu-command/src/env/config/config_env.rs index e1693b392f..45245b2492 100644 --- a/crates/nu-command/src/env/config/config_env.rs +++ b/crates/nu-command/src/env/config/config_env.rs @@ -2,7 +2,7 @@ use nu_engine::env_to_strings; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Type, + Category, Example, IntoPipelineData, PipelineData, ShellError, Signature, Type, Value, }; use super::utils::{gen_command, get_editor}; @@ -18,7 +18,11 @@ impl Command for ConfigEnv { fn signature(&self) -> Signature { Signature::build(self.name()) .category(Category::Env) - .input_output_types(vec![(Type::Nothing, Type::Nothing)]) + .input_output_types(vec![ + (Type::Nothing, Type::Nothing), + (Type::Nothing, Type::String), + ]) + .switch("default", "Print default `env.nu` file instead.", Some('d')) // TODO: Signature narrower than what run actually supports theoretically } @@ -27,11 +31,23 @@ impl Command for ConfigEnv { } fn examples(&self) -> Vec { - vec![Example { - description: "allow user to open and update nu env", - example: "config env", - result: None, - }] + vec![ + Example { + description: "allow user to open and update nu env", + example: "config env", + result: None, + }, + Example { + description: "allow user to print default `env.nu` file", + example: "config env --default,", + result: None, + }, + Example { + description: "allow saving the default `env.nu` locally", + example: "config env --default | save -f ~/.config/nushell/default_env.nu", + result: None, + }, + ] } fn run( @@ -41,6 +57,12 @@ impl Command for ConfigEnv { call: &Call, input: PipelineData, ) -> Result { + // `--default` flag handling + if call.has_flag("default") { + let head = call.head; + return Ok(Value::string(nu_utils::get_default_env(), head).into_pipeline_data()); + } + let env_vars_str = env_to_strings(engine_state, stack)?; let nu_config = match engine_state.get_config_path("env-path") { Some(path) => path.clone(), diff --git a/crates/nu-command/src/env/config/config_nu.rs b/crates/nu-command/src/env/config/config_nu.rs index 1591942f9a..7746a68ca2 100644 --- a/crates/nu-command/src/env/config/config_nu.rs +++ b/crates/nu-command/src/env/config/config_nu.rs @@ -2,7 +2,7 @@ use nu_engine::env_to_strings; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Type, + Category, Example, IntoPipelineData, PipelineData, ShellError, Signature, Type, Value, }; use super::utils::{gen_command, get_editor}; @@ -18,7 +18,15 @@ impl Command for ConfigNu { fn signature(&self) -> Signature { Signature::build(self.name()) .category(Category::Env) - .input_output_types(vec![(Type::Nothing, Type::Nothing)]) + .input_output_types(vec![ + (Type::Nothing, Type::Nothing), + (Type::Nothing, Type::String), + ]) + .switch( + "default", + "Print default `config.nu` file instead.", + Some('d'), + ) // TODO: Signature narrower than what run actually supports theoretically } @@ -27,11 +35,23 @@ impl Command for ConfigNu { } fn examples(&self) -> Vec { - vec![Example { - description: "allow user to open and update nu config", - example: "config nu", - result: None, - }] + vec![ + Example { + description: "allow user to open and update nu config", + example: "config nu", + result: None, + }, + Example { + description: "allow user to print default `config.nu` file", + example: "config nu --default,", + result: None, + }, + Example { + description: "allow saving the default `config.nu` locally", + example: "config nu --default | save -f ~/.config/nushell/default_config.nu", + result: None, + }, + ] } fn run( @@ -41,6 +61,12 @@ impl Command for ConfigNu { call: &Call, input: PipelineData, ) -> Result { + // `--default` flag handling + if call.has_flag("default") { + let head = call.head; + return Ok(Value::string(nu_utils::get_default_config(), head).into_pipeline_data()); + } + let env_vars_str = env_to_strings(engine_state, stack)?; let nu_config = match engine_state.get_config_path("config-path") { Some(path) => path.clone(), diff --git a/crates/nu-command/tests/commands/config_env_default.rs b/crates/nu-command/tests/commands/config_env_default.rs new file mode 100644 index 0000000000..d9b1185ffb --- /dev/null +++ b/crates/nu-command/tests/commands/config_env_default.rs @@ -0,0 +1,11 @@ +use nu_test_support::nu; + +#[test] +fn print_config_env_default_to_stdout() { + let actual = nu!("config env --default"); + assert_eq!( + actual.out, + nu_utils::get_default_env().replace(['\n', '\r'], "") + ); + assert!(actual.err.is_empty()); +} diff --git a/crates/nu-command/tests/commands/config_nu_default.rs b/crates/nu-command/tests/commands/config_nu_default.rs new file mode 100644 index 0000000000..7366031810 --- /dev/null +++ b/crates/nu-command/tests/commands/config_nu_default.rs @@ -0,0 +1,11 @@ +use nu_test_support::nu; + +#[test] +fn print_config_nu_default_to_stdout() { + let actual = nu!("config nu --default"); + assert_eq!( + actual.out, + nu_utils::get_default_config().replace(['\n', '\r'], "") + ); + assert!(actual.err.is_empty()); +} diff --git a/crates/nu-command/tests/commands/mod.rs b/crates/nu-command/tests/commands/mod.rs index 99f36650db..8c45747284 100644 --- a/crates/nu-command/tests/commands/mod.rs +++ b/crates/nu-command/tests/commands/mod.rs @@ -7,6 +7,8 @@ mod break_; mod cal; mod cd; mod compact; +mod config_env_default; +mod config_nu_default; mod continue_; mod conversions; mod cp;