Trim quotes when shelling out to cmd.exe (#7740)

Closes #6337 and #5366. Prior to this PR, when "shelling out" to cmd.exe
on Windows we were not trimming quotes correctly:

```bash
〉^echo "foo"
\"foo\"
```
After this change, we do:
```bash
〉^echo "foo"
foo
```

### Breaking Change

I ended up removing `dir` from the list of supported cmd.exe internal
commands as part of this PR.

For this PR, I extracted the argument-cleaning-and-expanding code from
`spawn_simple_command()` for reuse in `spawn_cmd_command()`. This means
that we now expand globs, which broke some tests for the `dir` cmd.exe
internal command.

I probably could have kept the tests working, but... tbh, I don't think
it's worth it. I don't want to make the `cmd.exe` functionality any more
complicated than it already is, and calling `dir` from Nu is always
going to be weird+hacky compared to `ls`.
This commit is contained in:
Reilly Wood
2023-01-13 11:00:30 -08:00
committed by GitHub
parent 3dd21c635a
commit 49ab559992
3 changed files with 95 additions and 118 deletions

View File

@ -20,7 +20,7 @@ fn redirect_err() {
Playground::setup("redirect_err_test", |dirs, _sandbox| {
let output = nu!(
cwd: dirs.test(),
"dir missingapplication err> a; (open a | size).bytes >= 16"
"vol missingdrive err> a; (open a | size).bytes >= 16"
);
assert!(output.out.contains("true"));
@ -46,7 +46,7 @@ fn redirect_outerr() {
Playground::setup("redirect_outerr_test", |dirs, _sandbox| {
let output = nu!(
cwd: dirs.test(),
"dir missingapplication out+err> a; (open a | size).bytes >= 16"
"vol missingdrive out+err> a; (open a | size).bytes >= 16"
);
assert!(output.out.contains("true"));

View File

@ -1,3 +1,4 @@
#[cfg(not(windows))]
use nu_test_support::fs::Stub::EmptyFile;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
@ -212,49 +213,6 @@ fn external_command_not_expand_tilde_with_quotes() {
)
}
#[cfg(windows)]
#[test]
fn explicit_glob_windows() {
Playground::setup("external with explicit glob", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("D&D_volume_1.txt"),
EmptyFile("D&D_volume_2.txt"),
EmptyFile("foo.sh"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
^dir | glob '*.txt' | length
"#
));
assert_eq!(actual.out, "2");
})
}
#[cfg(windows)]
#[test]
fn bare_word_expand_path_glob_windows() {
Playground::setup("bare word should do the expansion", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("D&D_volume_1.txt"),
EmptyFile("D&D_volume_2.txt"),
EmptyFile("foo.sh"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
^dir *.txt
"#
));
assert!(actual.out.contains("D&D_volume_1.txt"));
assert!(actual.out.contains("D&D_volume_2.txt"));
})
}
#[cfg(windows)]
#[test]
fn failed_command_with_semicolon_will_not_execute_following_cmds_windows() {
@ -329,3 +287,16 @@ fn can_run_batch_files_without_bat_extension() {
},
);
}
#[cfg(windows)]
#[test]
fn quotes_trimmed_when_shelling_out() {
// regression test for a bug where we weren't trimming quotes around string args before shelling out to cmd.exe
let actual = nu!(cwd: ".", pipeline(
r#"
^echo "foo"
"#
));
assert_eq!(actual.out, "foo");
}