Skip to content

Commit

Permalink
add some tests to be clearer about the kind of command that is created (
Browse files Browse the repository at this point in the history
#1103)

Note that for a moment, there was the idea about using `shell-words`
split certain invocations ourselves to avoid having to use a shell.

This is great on windows, where a shell might not be available.
On linux though this also means that some shell-builtins might
not be not be found if this is used, which limits the approach
to windows, and even there it might reduce compatibility.

Thus, let's not do it.
  • Loading branch information
Byron committed Nov 14, 2023
1 parent 3ff1827 commit 1ff26b9
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
3 changes: 2 additions & 1 deletion gix-command/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ mod prepare {

/// Builder
impl Prepare {
/// If called, the command will not be executed directly, but with `sh`.
/// If called, the command will not be executed directly, but with `sh`, but ony if the
/// command passed to [`prepare`](super::prepare()) requires this.
///
/// This also allows to pass shell scripts as command, or use commands that contain arguments which are subsequently
/// parsed by `sh`.
Expand Down
51 changes: 51 additions & 0 deletions gix-command/tests/command.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,65 @@
use gix_testtools::Result;

mod prepare {
#[cfg(windows)]
const SH: &str = "sh";
#[cfg(not(windows))]
const SH: &str = "/bin/sh";

fn quoted(input: &[&str]) -> String {
input.iter().map(|s| format!("\"{s}\"")).collect::<Vec<_>>().join(" ")
}

#[test]
fn empty() {
let cmd = std::process::Command::from(gix_command::prepare(""));
assert_eq!(format!("{cmd:?}"), "\"\"");
}
#[test]
fn single_and_multiple_arguments() {
let cmd = std::process::Command::from(gix_command::prepare("ls").arg("first").args(["second", "third"]));
assert_eq!(format!("{cmd:?}"), quoted(&["ls", "first", "second", "third"]));
}

#[test]
fn single_and_multiple_arguments_as_part_of_command() {
let cmd = std::process::Command::from(gix_command::prepare("ls first second third"));
assert_eq!(
format!("{cmd:?}"),
quoted(&["ls first second third"]),
"without shell, this is an invalid command"
);
}

#[test]
fn single_and_multiple_arguments_as_part_of_command_with_shell() {
let cmd = std::process::Command::from(gix_command::prepare("ls first second third").with_shell());
assert_eq!(
format!("{cmd:?}"),
quoted(&[SH, "-c", "ls first second third", "--"]),
"with shell, this works as it performs word splitting"
);
}

#[test]
fn single_and_complex_arguments_as_part_of_command_with_shell() {
let cmd = std::process::Command::from(gix_command::prepare("ls --foo \"a b\"").arg("additional").with_shell());
assert_eq!(
format!("{cmd:?}"),
format!("\"{SH}\" \"-c\" \"ls --foo \\\"a b\\\" \\\"$@\\\"\" \"--\" \"additional\""),
"with shell, this works as it performs word splitting"
);
}

#[test]
fn tilde_path_and_multiple_arguments_as_part_of_command_with_shell() {
let cmd = std::process::Command::from(gix_command::prepare("~/bin/exe --foo \"a b\"").with_shell());
assert_eq!(
format!("{cmd:?}"),
format!("\"{SH}\" \"-c\" \"~/bin/exe --foo \\\"a b\\\"\" \"--\""),
"this always needs a shell as we need tilde expansion"
);
}
}

mod spawn {
Expand Down

0 comments on commit 1ff26b9

Please sign in to comment.