From eaedb30a8c9887e216a6107d6e48c4e5882389f0 Mon Sep 17 00:00:00 2001 From: Wind Date: Wed, 28 Feb 2024 23:05:09 +0800 Subject: [PATCH] Don't expanding globs if user pass variables. (#11946) # Description Fixes: #11912 # User-Facing Changes After this change: ``` let x = '*.nu'; ^echo $x ``` will no longer expand glob. If users still want to expand glob, there are also 3 ways to do this: ``` # 1. use spread operation with `glob` command let x = '*.nu'; ^echo ...(glob $x) ``` # Tests + Formatting Done # After Submitting NaN --- crates/nu-command/src/system/run_external.rs | 4 ++- tests/shell/pipeline/commands/external.rs | 31 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/crates/nu-command/src/system/run_external.rs b/crates/nu-command/src/system/run_external.rs index 3f0406f8a8..94ea488322 100644 --- a/crates/nu-command/src/system/run_external.rs +++ b/crates/nu-command/src/system/run_external.rs @@ -711,9 +711,11 @@ fn trim_expand_and_apply_arg( // if arg is quoted, like "aa", 'aa', `aa`, or: // if arg is a variable or String interpolation, like: $variable_name, $"($variable_name)" // `as_a_whole` will be true, so nu won't remove the inner quotes. - let (trimmed_args, run_glob_expansion, mut keep_raw) = trim_enclosing_quotes(&arg.item); + let (trimmed_args, mut run_glob_expansion, mut keep_raw) = trim_enclosing_quotes(&arg.item); if *arg_keep_raw { keep_raw = true; + // it's a list or a variable, don't run glob expansion either + run_glob_expansion = false; } let mut arg = Spanned { item: if keep_raw { diff --git a/tests/shell/pipeline/commands/external.rs b/tests/shell/pipeline/commands/external.rs index 103766e52f..54e1dd639b 100644 --- a/tests/shell/pipeline/commands/external.rs +++ b/tests/shell/pipeline/commands/external.rs @@ -1,4 +1,6 @@ +use nu_test_support::fs::Stub::EmptyFile; use nu_test_support::nu; +use nu_test_support::playground::Playground; use pretty_assertions::assert_eq; #[cfg(feature = "which-support")] @@ -166,6 +168,35 @@ fn err_pipe_with_failed_external_works() { assert_eq!(actual.out, "4"); } +#[test] +fn dont_run_glob_if_pass_variable_to_external() { + Playground::setup("dont_run_glob", |dirs, sandbox| { + sandbox.with_files(vec![ + EmptyFile("jt_likes_cake.txt"), + EmptyFile("andres_likes_arepas.txt"), + ]); + + let actual = nu!(cwd: dirs.test(), r#"let f = "*.txt"; nu --testbin nonu $f"#); + + assert_eq!(actual.out, "*.txt"); + }) +} + +#[test] +fn run_glob_if_pass_variable_to_external() { + Playground::setup("run_glob_on_external", |dirs, sandbox| { + sandbox.with_files(vec![ + EmptyFile("jt_likes_cake.txt"), + EmptyFile("andres_likes_arepas.txt"), + ]); + + let actual = nu!(cwd: dirs.test(), r#"let f = "*.txt"; nu --testbin nonu ...(glob $f)"#); + + assert!(actual.out.contains("jt_likes_cake.txt")); + assert!(actual.out.contains("andres_likes_arepas.txt")); + }) +} + mod it_evaluation { use super::nu; use nu_test_support::fs::Stub::{EmptyFile, FileWithContent, FileWithContentToBeTrimmed};