From d941e7324fdac6fe7c497c7850ee53c729b3d99d Mon Sep 17 00:00:00 2001 From: Solomon Date: Thu, 17 Oct 2024 02:25:17 +0000 Subject: [PATCH] run ensure_flag_arg_type for short flag values (#14074) Closes #13654 # User-Facing Changes - Short flags are now fully type-checked, including null and record signatures for literal arguments: ```nushell def test [-v: record] {}; test -v null # error test -v {l: ""} # error def test2 [-v: int] {}; let v = "" test2 -v $v # error ``` - `polars unpivot` `--index`/`--on` and `into value --columns` now accept `list` values --- .../nu-command/src/conversions/into/value.rs | 2 +- crates/nu-parser/src/parser.rs | 23 ++++++++----------- .../src/dataframe/command/data/unpivot.rs | 4 ++-- tests/repl/test_custom_commands.rs | 18 ++++++++++++--- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/crates/nu-command/src/conversions/into/value.rs b/crates/nu-command/src/conversions/into/value.rs index 52e5ab339c..99b1daf4b7 100644 --- a/crates/nu-command/src/conversions/into/value.rs +++ b/crates/nu-command/src/conversions/into/value.rs @@ -18,7 +18,7 @@ impl Command for IntoValue { .input_output_types(vec![(Type::table(), Type::table())]) .named( "columns", - SyntaxShape::Table(vec![]), + SyntaxShape::List(Box::new(SyntaxShape::Any)), "list of columns to update", Some('c'), ) diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index 232fc50b3d..64a5086628 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -1067,30 +1067,27 @@ pub fn parse_internal_call( if let Some(arg_shape) = flag.arg { if let Some(arg) = spans.get(spans_idx + 1) { let arg = parse_value(working_set, *arg, &arg_shape); + let (arg_name, val_expression) = ensure_flag_arg_type( + working_set, + flag.long.clone(), + arg.clone(), + &arg_shape, + spans[spans_idx], + ); if flag.long.is_empty() { if let Some(short) = flag.short { call.add_named(( - Spanned { - item: String::new(), - span: spans[spans_idx], - }, + arg_name, Some(Spanned { item: short.to_string(), span: spans[spans_idx], }), - Some(arg), + Some(val_expression), )); } } else { - call.add_named(( - Spanned { - item: flag.long.clone(), - span: spans[spans_idx], - }, - None, - Some(arg), - )); + call.add_named((arg_name, None, Some(val_expression))); } spans_idx += 1; } else { diff --git a/crates/nu_plugin_polars/src/dataframe/command/data/unpivot.rs b/crates/nu_plugin_polars/src/dataframe/command/data/unpivot.rs index 5235305de2..ffbbd66916 100644 --- a/crates/nu_plugin_polars/src/dataframe/command/data/unpivot.rs +++ b/crates/nu_plugin_polars/src/dataframe/command/data/unpivot.rs @@ -31,13 +31,13 @@ impl PluginCommand for UnpivotDF { Signature::build(self.name()) .required_named( "index", - SyntaxShape::Table(vec![]), + SyntaxShape::List(Box::new(SyntaxShape::Any)), "column names for unpivoting", Some('i'), ) .required_named( "on", - SyntaxShape::Table(vec![]), + SyntaxShape::List(Box::new(SyntaxShape::Any)), "column names used as value columns", Some('o'), ) diff --git a/tests/repl/test_custom_commands.rs b/tests/repl/test_custom_commands.rs index 1710b35913..a93d3fbba8 100644 --- a/tests/repl/test_custom_commands.rs +++ b/tests/repl/test_custom_commands.rs @@ -1,6 +1,7 @@ use crate::repl::tests::{fail_test, run_test, run_test_contains, TestResult}; use nu_test_support::nu; use pretty_assertions::assert_eq; +use rstest::rstest; #[test] fn no_scope_leak1() -> TestResult { @@ -73,10 +74,21 @@ fn custom_switch1() -> TestResult { ) } -#[test] -fn custom_flag_with_type_checking() -> TestResult { +#[rstest] +fn custom_flag_with_type_checking( + #[values( + ("int", "\"3\""), + ("int", "null"), + ("record", "{i: \"\"}"), + ("list", "[\"\"]") + )] + type_sig_value: (&str, &str), + #[values("--dry-run", "-d")] flag: &str, +) -> TestResult { + let (type_sig, value) = type_sig_value; + fail_test( - r#"def florb [--dry-run: int] { $dry_run }; let y = "3"; florb --dry-run=$y"#, + &format!("def florb [{flag}: {type_sig}] {{}}; let y = {value}; florb {flag} $y"), "type_mismatch", ) }