Raw
1 #ifndef HOOK_H
2 #define HOOK_H
3 #include "config.h"
4 #include "run-command.h"
5 #include "string-list.h"
6 #include "strmap.h"
7 #include "strvec.h"
8
9 struct repository;
10
11 typedef void (*hook_data_free_fn)(void *data);
12 typedef void *(*hook_data_alloc_fn)(void *init_ctx);
13
14 /**
15 * Represents a hook command to be run.
16 * Hooks can be:
17 * 1. "traditional" (found in the hooks directory)
18 * 2. "configured" (defined in Git's configuration via hook.<friendly-name>.event).
19 * The 'kind' field determines which part of the union 'u' is valid.
20 */
21 struct hook {
22 enum {
23 HOOK_TRADITIONAL,
24 HOOK_CONFIGURED,
25 } kind;
26 union {
27 struct {
28 const char *path;
29 } traditional;
30 struct {
31 const char *friendly_name;
32 const char *command;
33 enum config_scope scope;
34 bool disabled;
35 bool event_disabled;
36 } configured;
37 } u;
38
39 /**
40 * Whether this hook may run in parallel with other hooks for the same
41 * event. Only useful for configured (named) hooks. Traditional hooks
42 * always default to 0 (serial). Set via `hook.<name>.parallel = true`.
43 */
44 bool parallel;
45
46 /**
47 * Opaque data pointer used to keep internal state across callback calls.
48 *
49 * It can be accessed directly via the third hook callback arg:
50 * struct ... *state = pp_task_cb;
51 *
52 * The caller is responsible for managing the memory for this data by
53 * providing alloc/free callbacks to `run_hooks_opt`.
54 *
55 * Only useful when using `run_hooks_opt.feed_pipe`, otherwise ignore it.
56 */
57 void *feed_pipe_cb_data;
58
59 /**
60 * Callback to free `feed_pipe_cb_data`.
61 *
62 * It is called automatically and points to the `feed_pipe_cb_data_free`
63 * provided via the `run_hook_opt` parameter.
64 */
65 hook_data_free_fn data_free;
66 };
67
68 struct run_hooks_opt {
69 /* Environment vars to be set for each hook */
70 struct strvec env;
71
72 /* Args to be passed to each hook */
73 struct strvec args;
74
75 /* Emit an error if the hook is missing */
76 unsigned int error_if_missing:1;
77
78 /**
79 * Number of processes to parallelize across.
80 *
81 * If > 1, output will be buffered and de-interleaved (ungroup=0).
82 * If == 1, output will be real-time (ungroup=1).
83 * If == 0, the 'hook.jobs' config is used or, if the config is unset,
84 * defaults to 1 (serial execution).
85 */
86 unsigned int jobs;
87
88 /**
89 * An optional initial working directory for the hook,
90 * translates to "struct child_process"'s "dir" member.
91 */
92 const char *dir;
93
94 /**
95 * A pointer which if provided will be set to 1 or 0 depending
96 * on if a hook was started, regardless of whether or not that
97 * was successful. I.e. if the underlying start_command() was
98 * successful this will be set to 1.
99 *
100 * Used for avoiding TOCTOU races in code that would otherwise
101 * call hook_exist() after a "maybe hook run" to see if a hook
102 * was invoked.
103 */
104 int *invoked_hook;
105
106 /**
107 * Send the hook's stdout to stderr.
108 *
109 * This is the default behavior for all hooks except pre-push,
110 * which keeps stdout and stderr separate for backwards compatibility.
111 * When parallel execution is requested (jobs > 1), get_hook_jobs()
112 * overrides this to 1 for all hooks so run-command can de-interleave
113 * their outputs correctly.
114 */
115 unsigned int stdout_to_stderr:1;
116
117 /**
118 * Path to file which should be piped to stdin for each hook.
119 */
120 const char *path_to_stdin;
121
122 /**
123 * Callback used to incrementally feed a child hook stdin pipe.
124 *
125 * Useful especially if a hook consumes large quantities of data
126 * (e.g. a list of all refs in a client push), so feeding it via
127 * in-memory strings or slurping to/from files is inefficient.
128 * While the callback allows piecemeal writing, it can also be
129 * used for smaller inputs, where it gets called only once.
130 *
131 * Add hook callback initialization context to `feed_pipe_ctx`.
132 * Add hook callback internal state to `feed_pipe_cb_data`.
133 *
134 */
135 feed_pipe_fn feed_pipe;
136
137 /**
138 * Opaque data pointer used to pass context to `feed_pipe_fn`.
139 *
140 * It can be accessed via the second callback arg 'pp_cb':
141 * ((struct hook_cb_data *) pp_cb)->hook_cb->options->feed_pipe_ctx;
142 *
143 * The caller is responsible for managing the memory for this data.
144 * Only useful when using `run_hooks_opt.feed_pipe`, otherwise ignore it.
145 */
146 void *feed_pipe_ctx;
147
148 /**
149 * Some hooks need to create a fresh `feed_pipe_cb_data` internal state,
150 * so they can keep track of progress without affecting one another.
151 *
152 * If provided, this function will be called to alloc & initialize the
153 * `feed_pipe_cb_data` for each hook.
154 *
155 * The `feed_pipe_ctx` pointer can be used to pass initialization data.
156 */
157 hook_data_alloc_fn feed_pipe_cb_data_alloc;
158
159 /**
160 * Called to free the memory initialized by `feed_pipe_cb_data_alloc`.
161 *
162 * Must always be provided when `feed_pipe_cb_data_alloc` is provided.
163 */
164 hook_data_free_fn feed_pipe_cb_data_free;
165 };
166
167 /**
168 * Default initializer for hooks. Parallelism is opt-in: .jobs = 0 defers to
169 * the 'hook.jobs' config, falling back to serial (1) if unset.
170 */
171 #define RUN_HOOKS_OPT_INIT { \
172 .env = STRVEC_INIT, \
173 .args = STRVEC_INIT, \
174 .stdout_to_stderr = 1, \
175 .jobs = 0, \
176 }
177
178 /**
179 * Initializer for hooks that must always run sequentially regardless of
180 * 'hook.jobs'. Use this when git knows the hook cannot safely be parallelized
181 * .jobs = 1 is non-overridable.
182 */
183 #define RUN_HOOKS_OPT_INIT_FORCE_SERIAL { \
184 .env = STRVEC_INIT, \
185 .args = STRVEC_INIT, \
186 .stdout_to_stderr = 1, \
187 .jobs = 1, \
188 }
189
190 struct hook_cb_data {
191 /* rc reflects the cumulative failure state */
192 int rc;
193 const char *hook_name;
194
195 /**
196 * A list of hook commands/paths to run for the 'hook_name' event.
197 *
198 * The 'string' member of each item holds the path (for traditional hooks)
199 * or the unique friendly-name for hooks specified in configs.
200 * The 'util' member of each item points to the corresponding struct hook.
201 */
202 struct string_list *hook_command_list;
203
204 /* Iterator/cursor for the above list, pointing to the next hook to run. */
205 size_t hook_to_run_index;
206
207 struct run_hooks_opt *options;
208 };
209
210 /**
211 * Provides a list of hook commands to run for the 'hookname' event.
212 *
213 * This function consolidates hooks from two sources:
214 * 1. The config-based hooks (not yet implemented).
215 * 2. The "traditional" hook found in the repository hooks directory
216 * (e.g., .git/hooks/pre-commit).
217 *
218 * The list is ordered by execution priority.
219 *
220 * The caller is responsible for freeing the memory of the returned list
221 * using string_list_clear() and free().
222 */
223 struct string_list *list_hooks(struct repository *r, const char *hookname,
224 struct run_hooks_opt *options);
225
226 /**
227 * Frees a struct hook stored as the util pointer of a string_list_item.
228 * Suitable for use as a string_list_clear_func_t callback.
229 */
230 void hook_free(void *p, const char *str);
231
232 /**
233 * Frees the hook configuration cache stored in `struct repository`.
234 * Called by repo_clear().
235 */
236 void hook_cache_clear(struct strmap *cache);
237
238 /**
239 * Returns true if `name` is a recognized hook event name
240 * (e.g. "pre-commit", "post-receive").
241 */
242 bool is_known_hook(const char *name);
243
244 /**
245 * Returns the path to the hook file, or NULL if the hook is missing
246 * or disabled. Note that this points to static storage that will be
247 * overwritten by further calls to find_hook and run_hook_*.
248 */
249 const char *find_hook(struct repository *r, const char *name);
250
251 /**
252 * A boolean version of find_hook()
253 */
254 int hook_exists(struct repository *r, const char *hookname);
255
256 /**
257 * Takes a `hook_name`, resolves it to a path with find_hook(), and
258 * runs the hook for you with the options specified in "struct
259 * run_hooks opt". Will free memory associated with the "struct run_hooks_opt".
260 *
261 * Returns the status code of the run hook, or a negative value on
262 * error().
263 */
264 int run_hooks_opt(struct repository *r, const char *hook_name,
265 struct run_hooks_opt *options);
266
267 /**
268 * A wrapper for run_hooks_opt() which provides a dummy "struct
269 * run_hooks_opt" initialized with "RUN_HOOKS_OPT_INIT".
270 */
271 int run_hooks(struct repository *r, const char *hook_name);
272
273 /**
274 * Like run_hooks(), a wrapper for run_hooks_opt().
275 *
276 * In addition to the wrapping behavior provided by run_hooks(), this
277 * wrapper takes a list of strings terminated by a NULL
278 * argument. These things will be used as positional arguments to the
279 * hook. This function behaves like the old run_hook_le() API.
280 */
281 LAST_ARG_MUST_BE_NULL
282 int run_hooks_l(struct repository *r, const char *hook_name, ...);
283 #endif