diff --git a/crates/nu-command/src/path/basename.rs b/crates/nu-command/src/path/basename.rs index 8c005b1ab0..5ac44040bf 100644 --- a/crates/nu-command/src/path/basename.rs +++ b/crates/nu-command/src/path/basename.rs @@ -11,15 +11,10 @@ use nu_protocol::{ use super::PathSubcommandArguments; struct Arguments { - columns: Option>, replace: Option>, } -impl PathSubcommandArguments for Arguments { - fn get_columns(&self) -> Option> { - self.columns.clone() - } -} +impl PathSubcommandArguments for Arguments {} #[derive(Clone)] pub struct SubCommand; @@ -33,15 +28,11 @@ impl Command for SubCommand { Signature::build("path basename") .input_output_types(vec![ (Type::String, Type::String), - // TODO: Why do these commands not use CellPaths in a standard way? - (Type::Table(vec![]), Type::Table(vec![])), + ( + Type::List(Box::new(Type::String)), + Type::List(Box::new(Type::String)), + ), ]) - .named( - "columns", - SyntaxShape::Table(vec![]), - "For a record or table input, convert strings in the given columns to their basename", - Some('c'), - ) .named( "replace", SyntaxShape::String, @@ -63,7 +54,6 @@ impl Command for SubCommand { ) -> Result { let head = call.head; let args = Arguments { - columns: call.get_flag(engine_state, stack, "columns")?, replace: call.get_flag(engine_state, stack, "replace")?, }; @@ -86,21 +76,12 @@ impl Command for SubCommand { result: Some(Value::test_string("test.txt")), }, Example { - description: "Get basename of a path in a column", - example: "ls .. | path basename -c [ name ]", - result: None, - }, - Example { - description: "Get basename of a path in a column", - example: "[[name];[C:\\Users\\Joe]] | path basename -c [ name ]", - result: Some(Value::List { - vals: vec![Value::Record { - cols: vec!["name".to_string()], - vals: vec![Value::test_string("Joe")], - span: Span::test_data(), - }], - span: Span::test_data(), - }), + description: "Get basename of a list of paths", + example: r"[ C:\Users\joe, C:\Users\doe ] | path basename", + result: Some(Value::test_list(vec![ + Value::test_string("joe"), + Value::test_string("doe"), + ])), }, Example { description: "Replace basename of a path", @@ -119,16 +100,12 @@ impl Command for SubCommand { result: Some(Value::test_string("test.txt")), }, Example { - description: "Get basename of a path by column", - example: "[[name];[/home/joe]] | path basename -c [ name ]", - result: Some(Value::List { - vals: vec![Value::Record { - cols: vec!["name".to_string()], - vals: vec![Value::test_string("joe")], - span: Span::test_data(), - }], - span: Span::test_data(), - }), + description: "Get basename of a list of paths", + example: "[ /home/joe, /home/doe ] | path basename", + result: Some(Value::test_list(vec![ + Value::test_string("joe"), + Value::test_string("doe"), + ])), }, Example { description: "Replace basename of a path", diff --git a/crates/nu-command/src/path/dirname.rs b/crates/nu-command/src/path/dirname.rs index 323fb77977..2b2df8a13d 100644 --- a/crates/nu-command/src/path/dirname.rs +++ b/crates/nu-command/src/path/dirname.rs @@ -11,16 +11,11 @@ use nu_protocol::{ use super::PathSubcommandArguments; struct Arguments { - columns: Option>, replace: Option>, num_levels: Option, } -impl PathSubcommandArguments for Arguments { - fn get_columns(&self) -> Option> { - self.columns.clone() - } -} +impl PathSubcommandArguments for Arguments {} #[derive(Clone)] pub struct SubCommand; @@ -32,13 +27,13 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("path dirname") - .input_output_types(vec![(Type::String, Type::String)]) - .named( - "columns", - SyntaxShape::Table(vec![]), - "For a record or table input, convert strings at the given columns to their dirname", - Some('c'), - ) + .input_output_types(vec![ + (Type::String, Type::String), + ( + Type::List(Box::new(Type::String)), + Type::List(Box::new(Type::String)), + ), + ]) .named( "replace", SyntaxShape::String, @@ -66,7 +61,6 @@ impl Command for SubCommand { ) -> Result { let head = call.head; let args = Arguments { - columns: call.get_flag(engine_state, stack, "columns")?, replace: call.get_flag(engine_state, stack, "replace")?, num_levels: call.get_flag(engine_state, stack, "num-levels")?, }; @@ -90,9 +84,12 @@ impl Command for SubCommand { result: Some(Value::test_string("C:\\Users\\joe\\code")), }, Example { - description: "Get dirname of a path in a column", - example: "ls ('.' | path expand) | path dirname -c [ name ]", - result: None, + description: "Get dirname of a list of paths", + example: r"[ C:\Users\joe\test.txt, C:\Users\doe\test.txt ] | path dirname", + result: Some(Value::test_list(vec![ + Value::test_string(r"C:\Users\joe"), + Value::test_string(r"C:\Users\doe"), + ])), }, Example { description: "Walk up two levels", @@ -117,9 +114,12 @@ impl Command for SubCommand { result: Some(Value::test_string("/home/joe/code")), }, Example { - description: "Get dirname of a path in a column", - example: "ls ('.' | path expand) | path dirname -c [ name ]", - result: None, + description: "Get dirname of a list of paths", + example: "[ /home/joe/test.txt, /home/doe/test.txt ] | path dirname", + result: Some(Value::test_list(vec![ + Value::test_string("/home/joe"), + Value::test_string("/home/doe"), + ])), }, Example { description: "Walk up two levels", diff --git a/crates/nu-command/src/path/exists.rs b/crates/nu-command/src/path/exists.rs index f09e81fe4f..765f847b63 100644 --- a/crates/nu-command/src/path/exists.rs +++ b/crates/nu-command/src/path/exists.rs @@ -1,25 +1,20 @@ use std::path::{Path, PathBuf}; -use nu_engine::{current_dir, CallExt}; +use nu_engine::current_dir; use nu_path::expand_path_with; use nu_protocol::ast::Call; use nu_protocol::engine::{EngineState, Stack}; use nu_protocol::{ - engine::Command, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, + engine::Command, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use super::PathSubcommandArguments; struct Arguments { - columns: Option>, pwd: PathBuf, } -impl PathSubcommandArguments for Arguments { - fn get_columns(&self) -> Option> { - self.columns.clone() - } -} +impl PathSubcommandArguments for Arguments {} #[derive(Clone)] pub struct SubCommand; @@ -30,14 +25,13 @@ impl Command for SubCommand { } fn signature(&self) -> Signature { - Signature::build("path exists") - .input_output_types(vec![(Type::String, Type::Bool)]) - .named( - "columns", - SyntaxShape::Table(vec![]), - "For a record or table input, check strings at the given columns, and replace with result", - Some('c'), - ) + Signature::build("path exists").input_output_types(vec![ + (Type::String, Type::Bool), + ( + Type::List(Box::new(Type::String)), + Type::List(Box::new(Type::Bool)), + ), + ]) } fn usage(&self) -> &str { @@ -58,7 +52,6 @@ If you need to distinguish dirs and files, please use `path type`."# ) -> Result { let head = call.head; let args = Arguments { - columns: call.get_flag(engine_state, stack, "columns")?, pwd: current_dir(engine_state, stack)?, }; // This doesn't match explicit nulls @@ -80,9 +73,12 @@ If you need to distinguish dirs and files, please use `path type`."# result: Some(Value::test_bool(false)), }, Example { - description: "Check if a file exists in a column", - example: "ls | path exists -c [ name ]", - result: None, + description: "Check if files in list exist", + example: r"[ C:\joe\todo.txt, C:\Users\doe\todo.txt ] | path exists", + result: Some(Value::test_list(vec![ + Value::test_bool(false), + Value::test_bool(false), + ])), }, ] } @@ -96,9 +92,12 @@ If you need to distinguish dirs and files, please use `path type`."# result: Some(Value::test_bool(false)), }, Example { - description: "Check if a file exists in a column", - example: "ls | path exists -c [ name ]", - result: None, + description: "Check if files in list exist", + example: "[ /home/joe/todo.txt, /home/doe/todo.txt ] | path exists", + result: Some(Value::test_list(vec![ + Value::test_bool(false), + Value::test_bool(false), + ])), }, ] } diff --git a/crates/nu-command/src/path/expand.rs b/crates/nu-command/src/path/expand.rs index 1aff543b25..f64ac582c9 100644 --- a/crates/nu-command/src/path/expand.rs +++ b/crates/nu-command/src/path/expand.rs @@ -1,28 +1,22 @@ use std::path::Path; use nu_engine::env::current_dir_str; -use nu_engine::CallExt; use nu_path::{canonicalize_with, expand_path_with}; use nu_protocol::ast::Call; use nu_protocol::engine::{EngineState, Stack}; use nu_protocol::{ - engine::Command, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, + engine::Command, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use super::PathSubcommandArguments; struct Arguments { strict: bool, - columns: Option>, cwd: String, not_follow_symlink: bool, } -impl PathSubcommandArguments for Arguments { - fn get_columns(&self) -> Option> { - self.columns.clone() - } -} +impl PathSubcommandArguments for Arguments {} #[derive(Clone)] pub struct SubCommand; @@ -34,19 +28,19 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("path expand") - .input_output_types(vec![(Type::String, Type::String)]) + .input_output_types(vec![ + (Type::String, Type::String), + ( + Type::List(Box::new(Type::String)), + Type::List(Box::new(Type::String)), + ), + ]) .switch( "strict", "Throw an error if the path could not be expanded", Some('s'), ) .switch("no-symlink", "Do not resolve symbolic links", Some('n')) - .named( - "columns", - SyntaxShape::Table(vec![]), - "For a record or table input, expand strings at the given columns", - Some('c'), - ) } fn usage(&self) -> &str { @@ -63,7 +57,6 @@ impl Command for SubCommand { let head = call.head; let args = Arguments { strict: call.has_flag("strict"), - columns: call.get_flag(engine_state, stack, "columns")?, cwd: current_dir_str(engine_state, stack)?, not_follow_symlink: call.has_flag("no-symlink"), }; @@ -85,20 +78,18 @@ impl Command for SubCommand { example: r"'C:\Users\joe\foo\..\bar' | path expand", result: Some(Value::test_string(r"C:\Users\joe\bar")), }, - Example { - description: "Expand a path in a column", - example: "ls | path expand -c [ name ]", - result: None, - }, Example { description: "Expand a relative path", example: r"'foo\..\bar' | path expand", result: None, }, Example { - description: "Expand an absolute path without following symlink", - example: r"'foo\..\bar' | path expand -n", - result: None, + description: "Expand a list of paths", + example: r"[ C:\foo\..\bar, C:\foo\..\baz ] | path expand", + result: Some(Value::test_list(vec![ + Value::test_string(r"C:\bar"), + Value::test_string(r"C:\baz"), + ])), }, ] } @@ -111,16 +102,19 @@ impl Command for SubCommand { example: "'/home/joe/foo/../bar' | path expand", result: Some(Value::test_string("/home/joe/bar")), }, - Example { - description: "Expand a path in a column", - example: "ls | path expand -c [ name ]", - result: None, - }, Example { description: "Expand a relative path", example: "'foo/../bar' | path expand", result: None, }, + Example { + description: "Expand a list of paths", + example: "[ /foo/../bar, /foo/../baz ] | path expand", + result: Some(Value::test_list(vec![ + Value::test_string("/bar"), + Value::test_string("/baz"), + ])), + }, ] } } diff --git a/crates/nu-command/src/path/join.rs b/crates/nu-command/src/path/join.rs index d5a622c313..1000760db2 100644 --- a/crates/nu-command/src/path/join.rs +++ b/crates/nu-command/src/path/join.rs @@ -12,15 +12,10 @@ use nu_protocol::{ use super::PathSubcommandArguments; struct Arguments { - columns: Option>, append: Vec>, } -impl PathSubcommandArguments for Arguments { - fn get_columns(&self) -> Option> { - self.columns.clone() - } -} +impl PathSubcommandArguments for Arguments {} #[derive(Clone)] pub struct SubCommand; @@ -38,13 +33,6 @@ impl Command for SubCommand { (Type::Record(vec![]), Type::String), (Type::Table(vec![]), Type::List(Box::new(Type::String))), ]) - .named( - "columns", - SyntaxShape::Table(vec![]), - "For a record or table input, join strings at the given columns", - Some('c'), - ) - .allow_variants_without_examples(true) .rest("append", SyntaxShape::String, "Path to append to the input") } @@ -66,7 +54,6 @@ the output of 'path parse' and 'path split' subcommands."# ) -> Result { let head = call.head; let args = Arguments { - columns: call.get_flag(engine_state, stack, "columns")?, append: call.rest(engine_state, stack, 0)?, }; @@ -105,11 +92,6 @@ the output of 'path parse' and 'path split' subcommands."# example: r"'C:\Users\viking' | path join spams this_spam.txt", result: Some(Value::test_string(r"C:\Users\viking\spams\this_spam.txt")), }, - Example { - description: "Append a filename to a path inside a column", - example: r"ls | path join spam.txt -c [ name ]", - result: None, - }, Example { description: "Join a list of parts into a path", example: r"[ 'C:' '\' 'Users' 'viking' 'spam.txt' ] | path join", @@ -117,6 +99,11 @@ the output of 'path parse' and 'path split' subcommands."# }, Example { description: "Join a structured path into a path", + example: r"{ parent: 'C:\Users\viking', stem: 'spam', extension: 'txt' } | path join", + result: Some(Value::test_string(r"C:\Users\viking\spam.txt")), + }, + Example { + description: "Join a table of structured paths into a list of paths", example: r"[ [parent stem extension]; ['C:\Users\viking' 'spam' 'txt']] | path join", result: Some(Value::List { vals: vec![Value::test_string(r"C:\Users\viking\spam.txt")], @@ -139,11 +126,6 @@ the output of 'path parse' and 'path split' subcommands."# example: r"'/home/viking' | path join spams this_spam.txt", result: Some(Value::test_string(r"/home/viking/spams/this_spam.txt")), }, - Example { - description: "Append a filename to a path inside a column", - example: r"ls | path join spam.txt -c [ name ]", - result: None, - }, Example { description: "Join a list of parts into a path", example: r"[ '/' 'home' 'viking' 'spam.txt' ] | path join", @@ -151,6 +133,11 @@ the output of 'path parse' and 'path split' subcommands."# }, Example { description: "Join a structured path into a path", + example: r"{ parent: '/home/viking', stem: 'spam', extension: 'txt' } | path join", + result: Some(Value::test_string(r"/home/viking/spam.txt")), + }, + Example { + description: "Join a table of structured paths into a list of paths", example: r"[[ parent stem extension ]; [ '/home/viking' 'spam' 'txt' ]] | path join", result: Some(Value::List { vals: vec![Value::test_string(r"/home/viking/spam.txt")], @@ -209,24 +196,11 @@ fn join_list(parts: &[Value], head: Span, span: Span, args: &Arguments) -> Value } fn join_record(cols: &[String], vals: &[Value], head: Span, span: Span, args: &Arguments) -> Value { - if args.columns.is_some() { - super::operate( - &join_single, - args, - Value::Record { - cols: cols.to_vec(), - vals: vals.to_vec(), - span, - }, - span, - ) - } else { - match merge_record(cols, vals, head, span) { - Ok(p) => join_single(p.as_path(), head, args), - Err(error) => Value::Error { - error: Box::new(error), - }, - } + match merge_record(cols, vals, head, span) { + Ok(p) => join_single(p.as_path(), head, args), + Err(error) => Value::Error { + error: Box::new(error), + }, } } diff --git a/crates/nu-command/src/path/mod.rs b/crates/nu-command/src/path/mod.rs index 5eccd2ac26..09672b0ae2 100644 --- a/crates/nu-command/src/path/mod.rs +++ b/crates/nu-command/src/path/mod.rs @@ -29,9 +29,7 @@ const ALLOWED_COLUMNS: [&str; 4] = ["prefix", "parent", "stem", "extension"]; #[cfg(not(windows))] const ALLOWED_COLUMNS: [&str; 3] = ["parent", "stem", "extension"]; -trait PathSubcommandArguments { - fn get_columns(&self) -> Option>; -} +trait PathSubcommandArguments {} fn operate(cmd: &F, args: &A, v: Value, name: Span) -> Value where @@ -40,45 +38,6 @@ where { match v { Value::String { val, span } => cmd(StdPath::new(&val), span, args), - Value::Record { cols, vals, span } => { - let col = if let Some(col) = args.get_columns() { - col - } else { - vec![] - }; - if col.is_empty() { - return Value::Error { - error: Box::new(ShellError::UnsupportedInput( - String::from("when the input is a table, you must specify the columns"), - "value originates from here".into(), - name, - span, - )), - }; - } - - let mut output_cols = vec![]; - let mut output_vals = vec![]; - - for (k, v) in cols.iter().zip(vals) { - output_cols.push(k.clone()); - if col.contains(k) { - let new_val = match v { - Value::String { val, span } => cmd(StdPath::new(&val), span, args), - _ => return handle_invalid_values(v, name), - }; - output_vals.push(new_val); - } else { - output_vals.push(v); - } - } - - Value::Record { - cols: output_cols, - vals: output_vals, - span, - } - } _ => handle_invalid_values(v, name), } } diff --git a/crates/nu-command/src/path/parse.rs b/crates/nu-command/src/path/parse.rs index 0eac1b9cec..66ef503c56 100644 --- a/crates/nu-command/src/path/parse.rs +++ b/crates/nu-command/src/path/parse.rs @@ -12,15 +12,10 @@ use nu_protocol::{ use super::PathSubcommandArguments; struct Arguments { - columns: Option>, extension: Option>, } -impl PathSubcommandArguments for Arguments { - fn get_columns(&self) -> Option> { - self.columns.clone() - } -} +impl PathSubcommandArguments for Arguments {} #[derive(Clone)] pub struct SubCommand; @@ -32,13 +27,10 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("path parse") - .input_output_types(vec![(Type::String, Type::Record(vec![]))]) - .named( - "columns", - SyntaxShape::Table(vec![]), - "For a record or table input, convert strings at the given columns", - Some('c'), - ) + .input_output_types(vec![ + (Type::String, Type::Record(vec![])), + (Type::List(Box::new(Type::String)), Type::Table(vec![])), + ]) .named( "extension", SyntaxShape::String, @@ -65,7 +57,6 @@ On Windows, an extra 'prefix' column is added."# ) -> Result { let head = call.head; let args = Arguments { - columns: call.get_flag(engine_state, stack, "columns")?, extension: call.get_flag(engine_state, stack, "extension")?, }; @@ -126,9 +117,40 @@ On Windows, an extra 'prefix' column is added."# }), }, Example { - description: "Parse all paths under the 'name' column", - example: r"ls | path parse -c [ name ]", - result: None, + description: "Parse all paths in a list", + example: r"[ C:\Users\viking.d C:\Users\spam.txt ] | path parse", + result: Some(Value::test_list(vec![ + Value::Record { + cols: vec![ + "prefix".into(), + "parent".into(), + "stem".into(), + "extension".into(), + ], + vals: vec![ + Value::test_string("C:"), + Value::test_string(r"C:\Users"), + Value::test_string("viking"), + Value::test_string("d"), + ], + span: Span::test_data(), + }, + Value::Record { + cols: vec![ + "prefix".into(), + "parent".into(), + "stem".into(), + "extension".into(), + ], + vals: vec![ + Value::test_string("C:"), + Value::test_string(r"C:\Users"), + Value::test_string("spam"), + Value::test_string("txt"), + ], + span: Span::test_data(), + }, + ])), }, ] } @@ -168,9 +190,28 @@ On Windows, an extra 'prefix' column is added."# }), }, Example { - description: "Parse all paths under the 'name' column", - example: r"ls | path parse -c [ name ]", - result: None, + description: "Parse all paths in a list", + example: r"[ /home/viking.d /home/spam.txt ] | path parse", + result: Some(Value::test_list(vec![ + Value::Record { + cols: vec!["parent".into(), "stem".into(), "extension".into()], + vals: vec![ + Value::test_string("/home"), + Value::test_string("viking"), + Value::test_string("d"), + ], + span: Span::test_data(), + }, + Value::Record { + cols: vec!["parent".into(), "stem".into(), "extension".into()], + vals: vec![ + Value::test_string("/home"), + Value::test_string("spam"), + Value::test_string("txt"), + ], + span: Span::test_data(), + }, + ])), }, ] } diff --git a/crates/nu-command/src/path/relative_to.rs b/crates/nu-command/src/path/relative_to.rs index 6b7f531cf3..f56e86c1af 100644 --- a/crates/nu-command/src/path/relative_to.rs +++ b/crates/nu-command/src/path/relative_to.rs @@ -13,14 +13,9 @@ use super::PathSubcommandArguments; struct Arguments { path: Spanned, - columns: Option>, } -impl PathSubcommandArguments for Arguments { - fn get_columns(&self) -> Option> { - self.columns.clone() - } -} +impl PathSubcommandArguments for Arguments {} #[derive(Clone)] pub struct SubCommand; @@ -32,18 +27,18 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("path relative-to") - .input_output_types(vec![(Type::String, Type::String)]) + .input_output_types(vec![ + (Type::String, Type::String), + ( + Type::List(Box::new(Type::String)), + Type::List(Box::new(Type::String)), + ), + ]) .required( "path", SyntaxShape::String, "Parent shared with the input path", ) - .named( - "columns", - SyntaxShape::Table(vec![]), - "For a record or table input, convert strings at the given columns", - Some('c'), - ) } fn usage(&self) -> &str { @@ -66,7 +61,6 @@ path."# let head = call.head; let args = Arguments { path: call.req(engine_state, stack, 0)?, - columns: call.get_flag(engine_state, stack, "columns")?, }; // This doesn't match explicit nulls @@ -88,9 +82,12 @@ path."# result: Some(Value::test_string(r"viking")), }, Example { - description: "Find a relative path from two absolute paths in a column", - example: "ls ~ | path relative-to ~ -c [ name ]", - result: None, + description: "Find a relative path from absolute paths in list", + example: r"[ C:\Users\viking, C:\Users\spam ] | path relative-to C:\Users", + result: Some(Value::test_list(vec![ + Value::test_string("viking"), + Value::test_string("spam"), + ])), }, Example { description: "Find a relative path from two relative paths", @@ -109,9 +106,12 @@ path."# result: Some(Value::test_string(r"viking")), }, Example { - description: "Find a relative path from two absolute paths in a column", - example: "ls ~ | path relative-to ~ -c [ name ]", - result: None, + description: "Find a relative path from absolute paths in list", + example: r"[ /home/viking, /home/spam ] | path relative-to '/home'", + result: Some(Value::test_list(vec![ + Value::test_string("viking"), + Value::test_string("spam"), + ])), }, Example { description: "Find a relative path from two relative paths", diff --git a/crates/nu-command/src/path/split.rs b/crates/nu-command/src/path/split.rs index a76d8c33e8..bbce5baebf 100644 --- a/crates/nu-command/src/path/split.rs +++ b/crates/nu-command/src/path/split.rs @@ -1,23 +1,16 @@ use std::path::{Component, Path}; -use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::engine::{EngineState, Stack}; use nu_protocol::{ - engine::Command, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, + engine::Command, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use super::PathSubcommandArguments; -struct Arguments { - columns: Option>, -} +struct Arguments; -impl PathSubcommandArguments for Arguments { - fn get_columns(&self) -> Option> { - self.columns.clone() - } -} +impl PathSubcommandArguments for Arguments {} #[derive(Clone)] pub struct SubCommand; @@ -28,14 +21,13 @@ impl Command for SubCommand { } fn signature(&self) -> Signature { - Signature::build("path split") - .input_output_types(vec![(Type::String, Type::List(Box::new(Type::String)))]) - .named( - "columns", - SyntaxShape::Table(vec![]), - "For a record or table input, split strings at the given columns", - Some('c'), - ) + Signature::build("path split").input_output_types(vec![ + (Type::String, Type::List(Box::new(Type::String))), + ( + Type::List(Box::new(Type::String)), + Type::List(Box::new(Type::List(Box::new(Type::String)))), + ), + ]) } fn usage(&self) -> &str { @@ -45,14 +37,12 @@ impl Command for SubCommand { fn run( &self, engine_state: &EngineState, - stack: &mut Stack, + _stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { let head = call.head; - let args = Arguments { - columns: call.get_flag(engine_state, stack, "columns")?, - }; + let args = Arguments; // This doesn't match explicit nulls if matches!(input, PipelineData::Empty) { @@ -81,9 +71,25 @@ impl Command for SubCommand { }), }, Example { - description: "Split all paths under the 'name' column", - example: r"ls ('.' | path expand) | path split -c [ name ]", - result: None, + description: "Split paths in list into parts", + example: r"[ C:\Users\viking\spam.txt C:\Users\viking\eggs.txt ] | path split", + result: Some(Value::List { + vals: vec![ + Value::test_list(vec![ + Value::test_string(r"C:\"), + Value::test_string("Users"), + Value::test_string("viking"), + Value::test_string("spam.txt"), + ]), + Value::test_list(vec![ + Value::test_string(r"C:\"), + Value::test_string("Users"), + Value::test_string("viking"), + Value::test_string("eggs.txt"), + ]), + ], + span: Span::test_data(), + }), }, ] } @@ -105,9 +111,25 @@ impl Command for SubCommand { }), }, Example { - description: "Split all paths under the 'name' column", - example: r"ls ('.' | path expand) | path split -c [ name ]", - result: None, + description: "Split paths in list into parts", + example: r"[ /home/viking/spam.txt /home/viking/eggs.txt ] | path split", + result: Some(Value::List { + vals: vec![ + Value::test_list(vec![ + Value::test_string("/"), + Value::test_string("home"), + Value::test_string("viking"), + Value::test_string("spam.txt"), + ]), + Value::test_list(vec![ + Value::test_string("/"), + Value::test_string("home"), + Value::test_string("viking"), + Value::test_string("eggs.txt"), + ]), + ], + span: Span::test_data(), + }), }, ] } diff --git a/crates/nu-command/src/path/type.rs b/crates/nu-command/src/path/type.rs index 7c9c412c4a..6061aee604 100644 --- a/crates/nu-command/src/path/type.rs +++ b/crates/nu-command/src/path/type.rs @@ -1,23 +1,16 @@ use std::path::Path; -use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::engine::{EngineState, Stack}; use nu_protocol::{ - engine::Command, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, + engine::Command, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use super::PathSubcommandArguments; -struct Arguments { - columns: Option>, -} +struct Arguments; -impl PathSubcommandArguments for Arguments { - fn get_columns(&self) -> Option> { - self.columns.clone() - } -} +impl PathSubcommandArguments for Arguments {} #[derive(Clone)] pub struct SubCommand; @@ -29,13 +22,14 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("path type") - .input_output_types(vec![(Type::String, Type::String)]) - .named( - "columns", - SyntaxShape::Table(vec![]), - "For a record or table input, check strings at the given columns, and replace with result", - Some('c'), - ) + .input_output_types(vec![ + (Type::String, Type::String), + ( + Type::List(Box::new(Type::String)), + Type::List(Box::new(Type::String)), + ), + ]) + .allow_variants_without_examples(true) } fn usage(&self) -> &str { @@ -50,14 +44,12 @@ If nothing is found, an empty string will be returned."# fn run( &self, engine_state: &EngineState, - stack: &mut Stack, + _stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { let head = call.head; - let args = Arguments { - columns: call.get_flag(engine_state, stack, "columns")?, - }; + let args = Arguments; // This doesn't match explicit nulls if matches!(input, PipelineData::Empty) { @@ -77,8 +69,8 @@ If nothing is found, an empty string will be returned."# result: Some(Value::test_string("dir")), }, Example { - description: "Show type of a filepath in a column", - example: "ls | path type -c [ name ]", + description: "Show type of a filepaths in a list", + example: "ls | get name | path type", result: None, }, ] diff --git a/crates/nu-command/tests/commands/path/join.rs b/crates/nu-command/tests/commands/path/join.rs index c4d5999709..b7f5f0781f 100644 --- a/crates/nu-command/tests/commands/path/join.rs +++ b/crates/nu-command/tests/commands/path/join.rs @@ -2,21 +2,6 @@ use nu_test_support::{nu, pipeline}; use super::join_path_sep; -#[test] -fn returns_path_joined_with_column_path() { - let actual = nu!( - cwd: "tests", pipeline( - r#" - echo [ [name]; [eggs] ] - | path join spam.txt -c [ name ] - | get name.0 - "# - )); - - let expected = join_path_sep(&["eggs", "spam.txt"]); - assert_eq!(actual.out, expected); -} - #[test] fn returns_path_joined_from_list() { let actual = nu!( diff --git a/crates/nu-command/tests/commands/path/parse.rs b/crates/nu-command/tests/commands/path/parse.rs index 68fc706f95..b1607556c6 100644 --- a/crates/nu-command/tests/commands/path/parse.rs +++ b/crates/nu-command/tests/commands/path/parse.rs @@ -99,21 +99,6 @@ fn parses_ignoring_extension_gets_stem() { assert_eq!(actual.out, "spam.tar.gz"); } -#[test] -fn parses_column_path_extension() { - let actual = nu!( - cwd: "tests", pipeline( - r#" - echo [[home, barn]; ['home/viking/spam.txt', 'barn/cow/moo.png']] - | path parse -c [ home barn ] - | get barn - | get extension.0 - "# - )); - - assert_eq!(actual.out, "png"); -} - #[test] fn parses_into_correct_number_of_columns() { let actual = nu!( diff --git a/crates/nu-command/tests/commands/path/split.rs b/crates/nu-command/tests/commands/path/split.rs index 67adf6fa62..b6a0c22959 100644 --- a/crates/nu-command/tests/commands/path/split.rs +++ b/crates/nu-command/tests/commands/path/split.rs @@ -25,24 +25,3 @@ fn splits_correctly_single_path() { assert_eq!(actual.out, "spam.txt"); } - -#[test] -fn splits_correctly_with_column_path() { - let actual = nu!( - cwd: "tests", pipeline( - r#" - echo [ - [home, barn]; - - ['home/viking/spam.txt', 'barn/cow/moo.png'] - ['home/viking/eggs.txt', 'barn/goat/cheese.png'] - ] - | path split -c [ home barn ] - | get barn - | flatten - | length - "# - )); - - assert_eq!(actual.out, "6"); -} diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs index 0303a2b0bf..e6c128ab66 100644 --- a/crates/nu-protocol/src/value/mod.rs +++ b/crates/nu-protocol/src/value/mod.rs @@ -1740,6 +1740,15 @@ impl Value { } } + /// Note: Only use this for test data, *not* live data, as it will point into unknown source + /// when used in errors. + pub fn test_list(vals: Vec) -> Value { + Value::List { + vals, + span: Span::test_data(), + } + } + /// Note: Only use this for test data, *not* live data, as it will point into unknown source /// when used in errors. pub fn test_date(val: DateTime) -> Value {