mod common;
use indoc::indoc;
use crate::common::{TestEnv, cmd_snapshot};
fn config() -> &'static str {
indoc! {r#"
repos:
- repo: local
hooks:
- id: exec-test
name: Exec test
entry: command-that-must-not-run
language: system
args: [argument-that-must-not-be-passed]
env:
GIT_AUTHOR_NAME: Prek Exec
GIT_AUTHOR_EMAIL: exec@prek.dev
GIT_AUTHOR_DATE: "2000-01-01T00:00:00+00:00"
"#}
}
fn context_with_config() -> TestEnv {
TestEnv::new().with_config(config()).init_git()
}
#[test]
fn exec_inherits_stdin_and_stdout() {
let context = context_with_config();
cmd_snapshot!(context, context.exec()
.args(["exec-test", "--", "git", "stripspace"])
.pass_stdin("hello from prek exec\n"), @r"
success: true
exit_code: 0
----- stdout -----
hello from prek exec
----- stderr -----
");
}
#[test]
fn exec_applies_hook_environment_without_entry_or_args() {
let context = context_with_config();
cmd_snapshot!(context, context.exec().args([
"exec-test",
"--",
"git",
"var",
"GIT_AUTHOR_IDENT",
]), @r"
success: true
exit_code: 0
----- stdout -----
Prek Exec <exec@prek.dev> 946684800 +0000
----- stderr -----
");
}
#[test]
fn exec_explicit_selector_ignores_skip_environment() {
let context = context_with_config();
cmd_snapshot!(context, context.exec()
.env("PREK_SKIP", "exec-test")
.args([
"exec-test",
"--",
"git",
"rev-parse",
"--is-inside-work-tree",
]), @r"
success: true
exit_code: 0
----- stdout -----
true
----- stderr -----
");
}
#[test]
fn exec_propagates_child_exit_status() {
let context = context_with_config();
cmd_snapshot!(context, context.exec().args([
"exec-test",
"--",
"git",
"-c",
"alias.exit-42=!exit 42",
"exit-42",
]), @r"
success: false
exit_code: 42
----- stdout -----
----- stderr -----
");
}
#[test]
fn exec_rejects_ambiguous_hook_selector() {
let context = TestEnv::new()
.with_workspace(["frontend"], config())
.init_git();
cmd_snapshot!(context, context.exec().args([
"exec-test",
"--",
"git",
"rev-parse",
"--is-inside-work-tree",
]), @r"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: Hook selector `exec-test` matched multiple hooks:
- frontend:exec-test
- .:exec-test
Use a `project-path:hook-id` selector to select one hook
");
}
#[test]
fn exec_keeps_current_working_directory() {
let context = TestEnv::new()
.with_workspace(["frontend"], config())
.init_git();
cmd_snapshot!(context, context.exec().args([
"frontend:exec-test",
"--",
"git",
"rev-parse",
"--show-prefix",
]), @r"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
");
}
#[cfg(unix)]
#[test]
fn exec_resolves_relative_command_from_current_working_directory() {
let context = TestEnv::new()
.with_workspace(["frontend"], config())
.with_executable_file("exec-tool", "#!/bin/sh\necho relative command ok\n")
.init_git();
cmd_snapshot!(context, context.exec().args([
"frontend:exec-test",
"--",
"./exec-tool",
]), @r"
success: true
exit_code: 0
----- stdout -----
relative command ok
----- stderr -----
");
}
#[test]
fn exec_rejects_unsupported_language_before_install() {
let context = TestEnv::new()
.with_config(indoc::indoc! {r"
repos:
- repo: local
hooks:
- id: julia-hook
name: Julia hook
entry: hook.jl
language: julia
"})
.init_git();
cmd_snapshot!(context, context.exec().args([
"julia-hook",
"--",
"git",
"rev-parse",
"--is-inside-work-tree",
]), @r"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: `prek exec` does not support hooks with language `julia`
");
}