summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
authorLibravatar Emily Shaffer <emilyshaffer@google.com>2021-12-22 04:59:27 +0100
committerLibravatar Junio C Hamano <gitster@pobox.com>2022-01-07 15:19:34 -0800
commit96e7225b310cb45a9b1198fb7bb1621e638e3329 (patch)
tree549a837a3969d4c60c1bf5b03919d56a56211b66 /t
parentThe fourth batch (diff)
downloadtgif-96e7225b310cb45a9b1198fb7bb1621e638e3329.tar.xz
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>
Diffstat (limited to 't')
-rwxr-xr-xt/t1800-hook.sh129
1 files changed, 129 insertions, 0 deletions
diff --git a/t/t1800-hook.sh b/t/t1800-hook.sh
new file mode 100755
index 0000000000..3aea1b105f
--- /dev/null
+++ b/t/t1800-hook.sh
@@ -0,0 +1,129 @@
+#!/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