Skip to content

Commit 15ecd84

Browse files
committed
feat: allow execution of scripts without 'bash'. (#650)
This works by trying to execute the file directly, and on failure, use 'bash' as interpreter. That way we are finally able to support a wider variety of fixture generators and make the crate more useful to a wieder audience.
1 parent 4eb842c commit 15ecd84

File tree

1 file changed

+42
-27
lines changed

1 file changed

+42
-27
lines changed

tests/tools/src/lib.rs

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ pub fn fixture_bytes(path: impl AsRef<Path>) -> Vec<u8> {
205205
}
206206
}
207207

208-
/// Run the script file `script_name` using `bash`, like `make_repo.sh` to produce a read-only directory to which
208+
/// Run the executable at `script_name`, like `make_repo.sh` or `my_setup.py` to produce a read-only directory to which
209209
/// the path is returned.
210210
///
211211
/// Note that it persists and the script at `script_name` will only be executed once if it ran without error.
@@ -366,32 +366,17 @@ fn scripted_fixture_read_only_with_args_inner(
366366
);
367367
}
368368
let script_absolute_path = std::env::current_dir()?.join(script_path);
369-
let output = std::process::Command::new("bash")
370-
.arg(script_absolute_path)
371-
.args(args)
372-
.stdout(std::process::Stdio::piped())
373-
.stderr(std::process::Stdio::piped())
374-
.current_dir(&script_result_directory)
375-
.env_remove("GIT_DIR")
376-
.env_remove("GIT_ASKPASS")
377-
.env_remove("SSH_ASKPASS")
378-
.env("GIT_TERMINAL_PROMPT", "false")
379-
.env("GIT_AUTHOR_DATE", "2000-01-01 00:00:00 +0000")
380-
.env("GIT_AUTHOR_EMAIL", "[email protected]")
381-
.env("GIT_AUTHOR_NAME", "author")
382-
.env("GIT_COMMITTER_DATE", "2000-01-02 00:00:00 +0000")
383-
.env("GIT_COMMITTER_EMAIL", "[email protected]")
384-
.env("GIT_COMMITTER_NAME", "committer")
385-
.env("GIT_CONFIG_COUNT", "4")
386-
.env("GIT_CONFIG_KEY_0", "commit.gpgsign")
387-
.env("GIT_CONFIG_VALUE_0", "false")
388-
.env("GIT_CONFIG_KEY_1", "tag.gpgsign")
389-
.env("GIT_CONFIG_VALUE_1", "false")
390-
.env("GIT_CONFIG_KEY_2", "init.defaultBranch")
391-
.env("GIT_CONFIG_VALUE_2", "main")
392-
.env("GIT_CONFIG_KEY_3", "protocol.file.allow")
393-
.env("GIT_CONFIG_VALUE_3", "always")
394-
.output()?;
369+
let mut cmd = std::process::Command::new(&script_absolute_path);
370+
let output = match configure_command(&mut cmd, &args, &script_result_directory).output() {
371+
Ok(out) => out,
372+
Err(err)
373+
if err.kind() == std::io::ErrorKind::PermissionDenied || err.raw_os_error() == Some(193) /* windows */ =>
374+
{
375+
cmd = std::process::Command::new("bash");
376+
configure_command(cmd.arg(script_absolute_path), &args, &script_result_directory).output()?
377+
}
378+
Err(err) => return Err(err.into()),
379+
};
395380
if !output.status.success() {
396381
write_failure_marker(&failure_marker);
397382
}
@@ -413,6 +398,36 @@ fn scripted_fixture_read_only_with_args_inner(
413398
Ok(script_result_directory)
414399
}
415400

401+
fn configure_command<'a>(
402+
cmd: &'a mut std::process::Command,
403+
args: &[String],
404+
script_result_directory: &Path,
405+
) -> &'a mut std::process::Command {
406+
cmd.args(args)
407+
.stdout(std::process::Stdio::piped())
408+
.stderr(std::process::Stdio::piped())
409+
.current_dir(script_result_directory)
410+
.env_remove("GIT_DIR")
411+
.env_remove("GIT_ASKPASS")
412+
.env_remove("SSH_ASKPASS")
413+
.env("GIT_TERMINAL_PROMPT", "false")
414+
.env("GIT_AUTHOR_DATE", "2000-01-01 00:00:00 +0000")
415+
.env("GIT_AUTHOR_EMAIL", "[email protected]")
416+
.env("GIT_AUTHOR_NAME", "author")
417+
.env("GIT_COMMITTER_DATE", "2000-01-02 00:00:00 +0000")
418+
.env("GIT_COMMITTER_EMAIL", "[email protected]")
419+
.env("GIT_COMMITTER_NAME", "committer")
420+
.env("GIT_CONFIG_COUNT", "4")
421+
.env("GIT_CONFIG_KEY_0", "commit.gpgsign")
422+
.env("GIT_CONFIG_VALUE_0", "false")
423+
.env("GIT_CONFIG_KEY_1", "tag.gpgsign")
424+
.env("GIT_CONFIG_VALUE_1", "false")
425+
.env("GIT_CONFIG_KEY_2", "init.defaultBranch")
426+
.env("GIT_CONFIG_VALUE_2", "main")
427+
.env("GIT_CONFIG_KEY_3", "protocol.file.allow")
428+
.env("GIT_CONFIG_VALUE_3", "always")
429+
}
430+
416431
fn write_failure_marker(failure_marker: &Path) {
417432
std::fs::write(failure_marker, []).ok();
418433
}

0 commit comments

Comments
 (0)