diff --git a/crates/nu-command/src/system/run_external.rs b/crates/nu-command/src/system/run_external.rs index 40b79a2805..38bbde7da2 100644 --- a/crates/nu-command/src/system/run_external.rs +++ b/crates/nu-command/src/system/run_external.rs @@ -53,9 +53,9 @@ impl Command for External { ) -> Result { let cwd = engine_state.cwd(Some(stack))?; let rest = call.rest::(engine_state, stack, 0)?; - let name_args = rest.split_first(); + let name_args = rest.split_first().map(|(x, y)| (x, y.to_vec())); - let Some((name, call_args)) = name_args else { + let Some((name, mut call_args)) = name_args else { return Err(ShellError::MissingParameter { param_name: "no command given".into(), span: call.head, @@ -65,6 +65,17 @@ impl Command for External { let name_str: Cow = match &name { Value::Glob { val, .. } => Cow::Borrowed(val), Value::String { val, .. } => Cow::Borrowed(val), + Value::List { vals, .. } => { + let Some((first, args)) = vals.split_first() else { + return Err(ShellError::MissingParameter { + param_name: "external command given as list empty".into(), + span: call.head, + }); + }; + // Prepend elements in command list to the list of arguments except the first + call_args.splice(0..0, args.to_vec()); + first.coerce_str()? + } _ => Cow::Owned(name.clone().coerce_into_string()?), }; @@ -164,7 +175,7 @@ impl Command for External { command.envs(envs); // Configure args. - let args = eval_external_arguments(engine_state, stack, call_args.to_vec())?; + let args = eval_external_arguments(engine_state, stack, call_args)?; #[cfg(windows)] if is_cmd_internal_command(&name_str) || pathext_script_in_windows { // The /D flag disables execution of AutoRun commands from registry. diff --git a/crates/nu-command/tests/commands/run_external.rs b/crates/nu-command/tests/commands/run_external.rs index 5dc68405a9..7c588ad2a8 100644 --- a/crates/nu-command/tests/commands/run_external.rs +++ b/crates/nu-command/tests/commands/run_external.rs @@ -535,3 +535,32 @@ fn can_run_ps1_files(prefix: &str) { assert!(actual.out.contains("Hello World")); }); } + +#[rstest] +#[case("^")] +#[case("run-external ")] +fn expand_command_if_list(#[case] prefix: &str) { + use nu_test_support::fs::Stub::FileWithContent; + Playground::setup("expand command if list", |dirs, sandbox| { + sandbox.with_files(&[FileWithContent("foo.txt", "Hello World")]); + let actual = nu!( + cwd: dirs.test(), + r#" + let cmd = [nu `--testbin`]; {}$cmd meow foo.txt + "#, + prefix + ); + + assert!(actual.out.contains("Hello World")); + }) +} + +#[rstest] +#[case("^")] +#[case("run-external ")] +fn error_when_command_list_empty(#[case] prefix: &str) { + Playground::setup("error when command is list with no items", |dirs, _| { + let actual = nu!(cwd: dirs.test(), "let cmd = []; {}$cmd", prefix); + assert!(actual.err.contains("missing parameter")); + }) +}