git-commit-vandalism/t/t1800-hook.sh
Emily Shaffer 96e7225b31 hook: add 'run' subcommand
In order to enable hooks to be run as an external process, by a
standalone Git command, or by tools which wrap Git, provide an external
means to run all configured hook commands for a given hook event.

Most of our hooks require more complex functionality than this, but
let's start with the bare minimum required to support our simplest
hooks.

In terms of implementation the usage_with_options() and "goto usage"
pattern here mirrors that of
builtin/{commit-graph,multi-pack-index}.c.

Some of the implementation here, such as a function being named
run_hooks_opt() when it's tasked with running one hook, to using the
run_processes_parallel_tr2() API to run with jobs=1 is somewhere
between a bit odd and and an overkill for the current features of this
"hook run" command and the hook.[ch] API.

This code will eventually be able to run multiple hooks declared in
config in parallel, by starting out with these names and APIs we
reduce the later churn of renaming functions, switching from the
run_command() to run_processes_parallel_tr2() API etc.

Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Acked-by: Emily Shaffer <emilyshaffer@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-07 15:19:34 -08:00

130 lines
2.9 KiB
Bash
Executable File

#!/bin/sh
test_description='git-hook command'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'git hook usage' '
test_expect_code 129 git hook &&
test_expect_code 129 git hook run &&
test_expect_code 129 git hook run -h &&
test_expect_code 129 git hook run --unknown 2>err &&
grep "unknown option" err
'
test_expect_success 'git hook run: nonexistent hook' '
cat >stderr.expect <<-\EOF &&
error: cannot find a hook named test-hook
EOF
test_expect_code 1 git hook run test-hook 2>stderr.actual &&
test_cmp stderr.expect stderr.actual
'
test_expect_success 'git hook run: basic' '
write_script .git/hooks/test-hook <<-EOF &&
echo Test hook
EOF
cat >expect <<-\EOF &&
Test hook
EOF
git hook run test-hook 2>actual &&
test_cmp expect actual
'
test_expect_success 'git hook run: stdout and stderr both write to our stderr' '
write_script .git/hooks/test-hook <<-EOF &&
echo >&1 Will end up on stderr
echo >&2 Will end up on stderr
EOF
cat >stderr.expect <<-\EOF &&
Will end up on stderr
Will end up on stderr
EOF
git hook run test-hook >stdout.actual 2>stderr.actual &&
test_cmp stderr.expect stderr.actual &&
test_must_be_empty stdout.actual
'
test_expect_success 'git hook run: exit codes are passed along' '
write_script .git/hooks/test-hook <<-EOF &&
exit 1
EOF
test_expect_code 1 git hook run test-hook &&
write_script .git/hooks/test-hook <<-EOF &&
exit 2
EOF
test_expect_code 2 git hook run test-hook &&
write_script .git/hooks/test-hook <<-EOF &&
exit 128
EOF
test_expect_code 128 git hook run test-hook &&
write_script .git/hooks/test-hook <<-EOF &&
exit 129
EOF
test_expect_code 129 git hook run test-hook
'
test_expect_success 'git hook run arg u ments without -- is not allowed' '
test_expect_code 129 git hook run test-hook arg u ments
'
test_expect_success 'git hook run -- pass arguments' '
write_script .git/hooks/test-hook <<-\EOF &&
echo $1
echo $2
EOF
cat >expect <<-EOF &&
arg
u ments
EOF
git hook run test-hook -- arg "u ments" 2>actual &&
test_cmp expect actual
'
test_expect_success 'git hook run -- out-of-repo runs excluded' '
write_script .git/hooks/test-hook <<-EOF &&
echo Test hook
EOF
nongit test_must_fail git hook run test-hook
'
test_expect_success 'git -c core.hooksPath=<PATH> hook run' '
mkdir my-hooks &&
write_script my-hooks/test-hook <<-\EOF &&
echo Hook ran $1 >>actual
EOF
cat >expect <<-\EOF &&
Test hook
Hook ran one
Hook ran two
Hook ran three
Hook ran four
EOF
# Test various ways of specifying the path. See also
# t1350-config-hooks-path.sh
>actual &&
git hook run test-hook -- ignored 2>>actual &&
git -c core.hooksPath=my-hooks hook run test-hook -- one 2>>actual &&
git -c core.hooksPath=my-hooks/ hook run test-hook -- two 2>>actual &&
git -c core.hooksPath="$PWD/my-hooks" hook run test-hook -- three 2>>actual &&
git -c core.hooksPath="$PWD/my-hooks/" hook run test-hook -- four 2>>actual &&
test_cmp expect actual
'
test_done