Merge branch 'ab/hook-api-with-stdin'
Extend the run-hooks API to allow feeding data from the standard input when running the hook script(s). * ab/hook-api-with-stdin: hook: support a --to-stdin=<path> option sequencer: use the new hook API for the simpler "post-rewrite" call hook API: support passing stdin to hooks, convert am's 'post-rewrite' run-command: allow stdin for run_processes_parallel run-command.c: remove dead assignment in while-loop
This commit is contained in:
commit
5048df67b2
@ -8,7 +8,7 @@ git-hook - Run git hooks
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git hook' run [--ignore-missing] <hook-name> [-- <hook-args>]
|
||||
'git hook' run [--ignore-missing] [--to-stdin=<path>] <hook-name> [-- <hook-args>]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@ -31,6 +31,11 @@ linkgit:githooks[5] for arguments hooks might expect (if any).
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
--to-stdin::
|
||||
For "run"; Specify a file which will be streamed into the
|
||||
hook's stdin. The hook will receive the entire file from
|
||||
beginning to EOF.
|
||||
|
||||
--ignore-missing::
|
||||
Ignore any missing hook by quietly returning zero. Used for
|
||||
tools that want to do a blind one-shot run of a hook that may
|
||||
|
20
builtin/am.c
20
builtin/am.c
@ -495,24 +495,12 @@ static int run_applypatch_msg_hook(struct am_state *state)
|
||||
*/
|
||||
static int run_post_rewrite_hook(const struct am_state *state)
|
||||
{
|
||||
struct child_process cp = CHILD_PROCESS_INIT;
|
||||
const char *hook = find_hook("post-rewrite");
|
||||
int ret;
|
||||
struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
|
||||
|
||||
if (!hook)
|
||||
return 0;
|
||||
strvec_push(&opt.args, "rebase");
|
||||
opt.path_to_stdin = am_path(state, "rewritten");
|
||||
|
||||
strvec_push(&cp.args, hook);
|
||||
strvec_push(&cp.args, "rebase");
|
||||
|
||||
cp.in = xopen(am_path(state, "rewritten"), O_RDONLY);
|
||||
cp.stdout_to_stderr = 1;
|
||||
cp.trace2_hook_name = "post-rewrite";
|
||||
|
||||
ret = run_command(&cp);
|
||||
|
||||
close(cp.in);
|
||||
return ret;
|
||||
return run_hooks_opt("post-rewrite", &opt);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "strvec.h"
|
||||
|
||||
#define BUILTIN_HOOK_RUN_USAGE \
|
||||
N_("git hook run [--ignore-missing] <hook-name> [-- <hook-args>]")
|
||||
N_("git hook run [--ignore-missing] [--to-stdin=<path>] <hook-name> [-- <hook-args>]")
|
||||
|
||||
static const char * const builtin_hook_usage[] = {
|
||||
BUILTIN_HOOK_RUN_USAGE,
|
||||
@ -28,6 +28,8 @@ static int run(int argc, const char **argv, const char *prefix)
|
||||
struct option run_options[] = {
|
||||
OPT_BOOL(0, "ignore-missing", &ignore_missing,
|
||||
N_("silently ignore missing requested <hook-name>")),
|
||||
OPT_STRING(0, "to-stdin", &opt.path_to_stdin, N_("path"),
|
||||
N_("file to read into hooks' stdin")),
|
||||
OPT_END(),
|
||||
};
|
||||
int ret;
|
||||
|
5
hook.c
5
hook.c
@ -55,6 +55,11 @@ static int pick_next_hook(struct child_process *cp,
|
||||
|
||||
cp->no_stdin = 1;
|
||||
strvec_pushv(&cp->env, hook_cb->options->env.v);
|
||||
/* reopen the file for stdin; run_command closes it. */
|
||||
if (hook_cb->options->path_to_stdin) {
|
||||
cp->no_stdin = 0;
|
||||
cp->in = xopen(hook_cb->options->path_to_stdin, O_RDONLY);
|
||||
}
|
||||
cp->stdout_to_stderr = 1;
|
||||
cp->trace2_hook_name = hook_cb->hook_name;
|
||||
cp->dir = hook_cb->options->dir;
|
||||
|
5
hook.h
5
hook.h
@ -30,6 +30,11 @@ struct run_hooks_opt
|
||||
* was invoked.
|
||||
*/
|
||||
int *invoked_hook;
|
||||
|
||||
/**
|
||||
* Path to file which should be piped to stdin for each hook.
|
||||
*/
|
||||
const char *path_to_stdin;
|
||||
};
|
||||
|
||||
#define RUN_HOOKS_OPT_INIT { \
|
||||
|
@ -1586,6 +1586,14 @@ static int pp_start_one(struct parallel_processes *pp,
|
||||
if (i == opts->processes)
|
||||
BUG("bookkeeping is hard");
|
||||
|
||||
/*
|
||||
* By default, do not inherit stdin from the parent process - otherwise,
|
||||
* all children would share stdin! Users may overwrite this to provide
|
||||
* something to the child's stdin by having their 'get_next_task'
|
||||
* callback assign 0 to .no_stdin and an appropriate integer to .in.
|
||||
*/
|
||||
pp->children[i].process.no_stdin = 1;
|
||||
|
||||
code = opts->get_next_task(&pp->children[i].process,
|
||||
opts->ungroup ? NULL : &pp->children[i].err,
|
||||
opts->data,
|
||||
@ -1601,7 +1609,6 @@ static int pp_start_one(struct parallel_processes *pp,
|
||||
pp->children[i].process.err = -1;
|
||||
pp->children[i].process.stdout_to_stderr = 1;
|
||||
}
|
||||
pp->children[i].process.no_stdin = 1;
|
||||
|
||||
if (start_command(&pp->children[i].process)) {
|
||||
if (opts->start_failure)
|
||||
@ -1632,9 +1639,7 @@ static void pp_buffer_stderr(struct parallel_processes *pp,
|
||||
const struct run_process_parallel_opts *opts,
|
||||
int output_timeout)
|
||||
{
|
||||
int i;
|
||||
|
||||
while ((i = poll(pp->pfd, opts->processes, output_timeout) < 0)) {
|
||||
while (poll(pp->pfd, opts->processes, output_timeout) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
pp_cleanup(pp, opts);
|
||||
|
18
sequencer.c
18
sequencer.c
@ -4844,8 +4844,7 @@ cleanup_head_ref:
|
||||
if (!stat(rebase_path_rewritten_list(), &st) &&
|
||||
st.st_size > 0) {
|
||||
struct child_process child = CHILD_PROCESS_INIT;
|
||||
const char *post_rewrite_hook =
|
||||
find_hook("post-rewrite");
|
||||
struct run_hooks_opt hook_opt = RUN_HOOKS_OPT_INIT;
|
||||
|
||||
child.in = open(rebase_path_rewritten_list(), O_RDONLY);
|
||||
child.git_cmd = 1;
|
||||
@ -4855,18 +4854,9 @@ cleanup_head_ref:
|
||||
/* we don't care if this copying failed */
|
||||
run_command(&child);
|
||||
|
||||
if (post_rewrite_hook) {
|
||||
struct child_process hook = CHILD_PROCESS_INIT;
|
||||
|
||||
hook.in = open(rebase_path_rewritten_list(),
|
||||
O_RDONLY);
|
||||
hook.stdout_to_stderr = 1;
|
||||
hook.trace2_hook_name = "post-rewrite";
|
||||
strvec_push(&hook.args, post_rewrite_hook);
|
||||
strvec_push(&hook.args, "rebase");
|
||||
/* we don't care if this hook failed */
|
||||
run_command(&hook);
|
||||
}
|
||||
hook_opt.path_to_stdin = rebase_path_rewritten_list();
|
||||
strvec_push(&hook_opt.args, "rebase");
|
||||
run_hooks_opt("post-rewrite", &hook_opt);
|
||||
}
|
||||
apply_autostash(rebase_path_autostash());
|
||||
|
||||
|
@ -177,4 +177,22 @@ test_expect_success 'git hook run a hook with a bad shebang' '
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'stdin to hooks' '
|
||||
write_script .git/hooks/test-hook <<-\EOF &&
|
||||
echo BEGIN stdin
|
||||
cat
|
||||
echo END stdin
|
||||
EOF
|
||||
|
||||
cat >expect <<-EOF &&
|
||||
BEGIN stdin
|
||||
hello
|
||||
END stdin
|
||||
EOF
|
||||
|
||||
echo hello >input &&
|
||||
git hook run --to-stdin=input test-hook 2>actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_done
|
||||
|
Loading…
Reference in New Issue
Block a user