mirror of
https://github.com/nushell/nushell
synced 2024-12-27 05:23:11 +00:00
run_external: remove inner quotes once nushell gets =
sign (#13073)
# Description Fixes: #13066 nushell should remove argument values' inner quote once it gets `=`. Whatever it's a flag or not, and it also replace from `\"` to `"` before passing it to external commands. # User-Facing Changes Given the shell script: ```shell # test.sh echo $@ ``` ## Before ``` > sh test.sh -ldflags="-s -w" github.com -ldflags="-s -w" github.com > sh test.sh exp='-s -w' github.com exp='-s -w' github.com ``` ## After ``` > sh test.sh -ldflags="-s -w" github.com -ldflags=-s -w github.com > sh test.sh exp='-s -w' github.com exp=-s -w github.com ``` # Tests + Formatting Added some tests
This commit is contained in:
parent
75d5807dcd
commit
5d163c1bcc
2 changed files with 33 additions and 8 deletions
|
@ -218,14 +218,16 @@ impl Command for External {
|
||||||
|
|
||||||
/// Removes surrounding quotes from a string. Doesn't remove quotes from raw
|
/// Removes surrounding quotes from a string. Doesn't remove quotes from raw
|
||||||
/// strings. Returns the original string if it doesn't have matching quotes.
|
/// strings. Returns the original string if it doesn't have matching quotes.
|
||||||
fn remove_quotes(s: &str) -> &str {
|
fn remove_quotes(s: &str) -> Cow<'_, str> {
|
||||||
let quoted_by_double_quotes = s.len() >= 2 && s.starts_with('"') && s.ends_with('"');
|
let quoted_by_double_quotes = s.len() >= 2 && s.starts_with('"') && s.ends_with('"');
|
||||||
let quoted_by_single_quotes = s.len() >= 2 && s.starts_with('\'') && s.ends_with('\'');
|
let quoted_by_single_quotes = s.len() >= 2 && s.starts_with('\'') && s.ends_with('\'');
|
||||||
let quoted_by_backticks = s.len() >= 2 && s.starts_with('`') && s.ends_with('`');
|
let quoted_by_backticks = s.len() >= 2 && s.starts_with('`') && s.ends_with('`');
|
||||||
if quoted_by_double_quotes || quoted_by_single_quotes || quoted_by_backticks {
|
if quoted_by_double_quotes {
|
||||||
&s[1..s.len() - 1]
|
Cow::Owned(s[1..s.len() - 1].to_string().replace(r#"\""#, "\""))
|
||||||
|
} else if quoted_by_single_quotes || quoted_by_backticks {
|
||||||
|
Cow::Borrowed(&s[1..s.len() - 1])
|
||||||
} else {
|
} else {
|
||||||
s
|
Cow::Borrowed(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,10 +402,6 @@ fn expand_glob(
|
||||||
/// with double quotes, single quotes, or backticks. Only removes the outermost
|
/// with double quotes, single quotes, or backticks. Only removes the outermost
|
||||||
/// pair of quotes after the equal sign.
|
/// pair of quotes after the equal sign.
|
||||||
fn remove_inner_quotes(arg: &str) -> Cow<'_, str> {
|
fn remove_inner_quotes(arg: &str) -> Cow<'_, str> {
|
||||||
// Check that `arg` is a long option.
|
|
||||||
if !arg.starts_with("--") {
|
|
||||||
return Cow::Borrowed(arg);
|
|
||||||
}
|
|
||||||
// Split `arg` on the first `=`.
|
// Split `arg` on the first `=`.
|
||||||
let Some((option, value)) = arg.split_once('=') else {
|
let Some((option, value)) = arg.split_once('=') else {
|
||||||
return Cow::Borrowed(arg);
|
return Cow::Borrowed(arg);
|
||||||
|
@ -660,6 +658,7 @@ mod test {
|
||||||
assert_eq!(remove_quotes(r#"`foo '"' bar`"#), r#"foo '"' bar"#);
|
assert_eq!(remove_quotes(r#"`foo '"' bar`"#), r#"foo '"' bar"#);
|
||||||
assert_eq!(remove_quotes(r#"'foo' bar"#), r#"'foo' bar"#);
|
assert_eq!(remove_quotes(r#"'foo' bar"#), r#"'foo' bar"#);
|
||||||
assert_eq!(remove_quotes(r#"r#'foo'#"#), r#"r#'foo'#"#);
|
assert_eq!(remove_quotes(r#"r#'foo'#"#), r#"r#'foo'#"#);
|
||||||
|
assert_eq!(remove_quotes(r#""foo\" bar""#), r#"foo" bar"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -758,6 +757,18 @@ mod test {
|
||||||
let actual = remove_inner_quotes(r#"--option "value""#);
|
let actual = remove_inner_quotes(r#"--option "value""#);
|
||||||
let expected = r#"--option "value""#;
|
let expected = r#"--option "value""#;
|
||||||
assert_eq!(actual, expected);
|
assert_eq!(actual, expected);
|
||||||
|
|
||||||
|
let actual = remove_inner_quotes(r#"-option="value""#);
|
||||||
|
let expected = r#"-option=value"#;
|
||||||
|
assert_eq!(actual, expected);
|
||||||
|
|
||||||
|
let actual = remove_inner_quotes(r#"option="value""#);
|
||||||
|
let expected = r#"option=value"#;
|
||||||
|
assert_eq!(actual, expected);
|
||||||
|
|
||||||
|
let actual = remove_inner_quotes(r#"option="v\"value""#);
|
||||||
|
let expected = r#"option=v"value"#;
|
||||||
|
assert_eq!(actual, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -590,4 +590,18 @@ mod external_command_arguments {
|
||||||
|
|
||||||
assert_eq!(actual.out, "a;&$(hello)");
|
assert_eq!(actual.out, "a;&$(hello)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn remove_quotes_in_shell_arguments() {
|
||||||
|
let actual = nu!("nu --testbin cococo expression='-r -w'");
|
||||||
|
assert_eq!(actual.out, "expression=-r -w");
|
||||||
|
let actual = nu!(r#"nu --testbin cococo expression="-r -w""#);
|
||||||
|
assert_eq!(actual.out, "expression=-r -w");
|
||||||
|
let actual = nu!("nu --testbin cococo expression='-r -w'");
|
||||||
|
assert_eq!(actual.out, "expression=-r -w");
|
||||||
|
let actual = nu!(r#"nu --testbin cococo expression="-r\" -w""#);
|
||||||
|
assert_eq!(actual.out, r#"expression=-r" -w"#);
|
||||||
|
let actual = nu!(r#"nu --testbin cococo expression='-r\" -w'"#);
|
||||||
|
assert_eq!(actual.out, r#"expression=-r\" -w"#);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue