From 7fe2e60af7294c65f46b3e43018b701422b3de22 Mon Sep 17 00:00:00 2001 From: Darren Schroeder <343840+fdncred@users.noreply.github.com> Date: Thu, 18 Apr 2024 21:03:59 -0400 Subject: [PATCH] add ability to set metadata (#12564) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description This PR adds the ability to set metadata. This is especially useful for activating LS_COLORS when using table literals. ![image](https://github.com/nushell/nushell/assets/343840/feef6433-f592-43ea-890a-38cb2df35686) You can also set the filepath metadata, although I'm not really user how useful this is. We may end up removing this option entirely. ```nushell ❯ "crates" | metadata set --datasource-filepath $'(pwd)/crates' | metadata ╭────────┬───────────────────────────────────╮ │ source │ /Users/fdncred/src/nushell/crates │ ╰────────┴───────────────────────────────────╯ ``` No file paths are checked. You could also do this. ```nushell ❯ "crates" | metadata set --datasource-filepath $'a/b/c/d/crates' | metadata ╭────────┬────────────────╮ │ source │ a/b/c/d/crates │ ╰────────┴────────────────╯ ``` The command name and parameter names are still WIP. We could change them. There are currently 3 kinds of metadata in nushell. ```rust pub enum DataSource { Ls, HtmlThemes, FilePath(PathBuf), } ``` I've skipped adding `HtmlThemes` because it seems to be specific to our `to html` command only. --- crates/nu-command/src/debug/metadata_set.rs | 92 +++++++++++++++++++++ crates/nu-command/src/debug/mod.rs | 2 + crates/nu-command/src/default_context.rs | 1 + 3 files changed, 95 insertions(+) create mode 100644 crates/nu-command/src/debug/metadata_set.rs diff --git a/crates/nu-command/src/debug/metadata_set.rs b/crates/nu-command/src/debug/metadata_set.rs new file mode 100644 index 0000000000..29cb8ab0a2 --- /dev/null +++ b/crates/nu-command/src/debug/metadata_set.rs @@ -0,0 +1,92 @@ +use nu_engine::command_prelude::*; +use nu_protocol::{DataSource, PipelineMetadata}; + +#[derive(Clone)] +pub struct MetadataSet; + +impl Command for MetadataSet { + fn name(&self) -> &str { + "metadata set" + } + + fn usage(&self) -> &str { + "Set the metadata for items in the stream." + } + + fn signature(&self) -> nu_protocol::Signature { + Signature::build("metadata set") + .input_output_types(vec![(Type::Any, Type::Any)]) + .switch( + "datasource-ls", + "Assign the DataSource::Ls metadata to the input", + Some('l'), + ) + .named( + "datasource-filepath", + SyntaxShape::Filepath, + "Assign the DataSource::FilePath metadata to the input", + Some('f'), + ) + .allow_variants_without_examples(true) + .category(Category::Debug) + } + + fn run( + &self, + engine_state: &EngineState, + stack: &mut Stack, + call: &Call, + input: PipelineData, + ) -> Result { + let head = call.head; + let ds_fp: Option = call.get_flag(engine_state, stack, "datasource-filepath")?; + let ds_ls = call.has_flag(engine_state, stack, "datasource-ls")?; + + match (ds_fp, ds_ls) { + (Some(path), false) => { + let metadata = PipelineMetadata { + data_source: DataSource::FilePath(path.into()), + }; + Ok(input.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + } + (None, true) => { + let metadata = PipelineMetadata { + data_source: DataSource::Ls, + }; + Ok(input.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + } + _ => Err(ShellError::IncorrectValue { + msg: "Expected either --datasource-ls(-l) or --datasource-filepath(-f)".to_string(), + val_span: head, + call_span: head, + }), + } + } + + fn examples(&self) -> Vec { + vec![ + Example { + description: "Set the metadata of a table literal", + example: "[[name color]; [Cargo.lock '#ff0000'] [Cargo.toml '#00ff00'] [README.md '#0000ff']] | metadata set --datasource-ls", + result: None, + }, + Example { + description: "Set the metadata of a file path", + example: "'crates' | metadata set --datasource-filepath $'(pwd)/crates' | metadata", + result: None, + }, + ] + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_examples() { + use crate::test_examples; + + test_examples(MetadataSet {}) + } +} diff --git a/crates/nu-command/src/debug/mod.rs b/crates/nu-command/src/debug/mod.rs index 0a324be10a..f19ddab916 100644 --- a/crates/nu-command/src/debug/mod.rs +++ b/crates/nu-command/src/debug/mod.rs @@ -5,6 +5,7 @@ mod info; mod inspect; mod inspect_table; mod metadata; +mod metadata_set; mod profile; mod timeit; mod view; @@ -19,6 +20,7 @@ pub use info::DebugInfo; pub use inspect::Inspect; pub use inspect_table::build_table; pub use metadata::Metadata; +pub use metadata_set::MetadataSet; pub use profile::DebugProfile; pub use timeit::TimeIt; pub use view::View; diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index d2744d2522..998584a76e 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -143,6 +143,7 @@ pub fn add_shell_command_context(mut engine_state: EngineState) -> EngineState { Explain, Inspect, Metadata, + MetadataSet, TimeIt, View, ViewFiles,