diff --git a/crates/nu-command/src/system/run_external.rs b/crates/nu-command/src/system/run_external.rs index 43c81eba9b..edd00f4879 100644 --- a/crates/nu-command/src/system/run_external.rs +++ b/crates/nu-command/src/system/run_external.rs @@ -135,29 +135,23 @@ pub fn create_external_command( let mut spanned_args = vec![]; let mut arg_keep_raw = vec![]; for (arg, spread) in call.rest_iter(1) { - // TODO: Disallow automatic spreading entirely later. This match block will - // have to be refactored, and lists will have to be disallowed in the parser too match eval_expression(engine_state, stack, arg)? { Value::List { vals, .. } => { - if !spread { - nu_protocol::report_error_new( - engine_state, - &ShellError::GenericError { - error: "Automatically spreading lists is deprecated".into(), - msg: "Spreading lists automatically when calling external commands is deprecated and will be removed in 0.91.".into(), - span: Some(arg.span), - help: Some("Use the spread operator (put a '...' before the argument)".into()), - inner: vec![], - }, - ); - } - // turn all the strings in the array into params. - // Example: one_arg may be something like ["ls" "-a"] - // convert it to "ls" "-a" - for v in vals { - spanned_args.push(value_as_spanned(v)?); - // for arguments in list, it's always treated as a whole arguments - arg_keep_raw.push(true); + if spread { + // turn all the strings in the array into params. + // Example: one_arg may be something like ["ls" "-a"] + // convert it to "ls" "-a" + for v in vals { + spanned_args.push(value_as_spanned(v)?); + // for arguments in list, it's always treated as a whole arguments + arg_keep_raw.push(true); + } + } else { + return Err(ShellError::CannotPassListToExternal { + arg: String::from_utf8_lossy(engine_state.get_span_contents(arg.span)) + .into(), + span: arg.span, + }); } } val => { diff --git a/crates/nu-protocol/src/shell_error.rs b/crates/nu-protocol/src/shell_error.rs index 664582658e..d4549766b7 100644 --- a/crates/nu-protocol/src/shell_error.rs +++ b/crates/nu-protocol/src/shell_error.rs @@ -1308,6 +1308,22 @@ This is an internal Nushell error, please file an issue https://github.com/nushe span: Span, }, + /// Lists are not automatically spread when calling external commands + /// + /// ## Resolution + /// + /// Use the spread operator (put a '...' before the argument) + #[error("Lists are not automatically spread when calling external commands")] + #[diagnostic( + code(nu::shell::cannot_pass_list_to_external), + help("Either convert the list to a string or use the spread operator, like so: ...{arg}") + )] + CannotPassListToExternal { + arg: String, + #[label = "Spread operator (...) is necessary to spread lists"] + span: Span, + }, + /// Out of bounds. /// /// ## Resolution diff --git a/src/tests/test_spread.rs b/src/tests/test_spread.rs index f031c91988..3dceea7089 100644 --- a/src/tests/test_spread.rs +++ b/src/tests/test_spread.rs @@ -182,13 +182,11 @@ fn explain_spread_args() -> TestResult { } #[test] -fn deprecate_implicit_spread_for_externals() { - // TODO: When automatic spreading is removed, test that list literals fail at parse time - let result = nu!(r#"nu --testbin cococo [1 2]"#); - assert!(result - .err - .contains("Automatically spreading lists is deprecated")); - assert_eq!(result.out, "1 2"); +fn disallow_implicit_spread_for_externals() -> TestResult { + fail_test( + r#"nu --testbin cococo [1 2]"#, + "Lists are not automatically spread", + ) } #[test]