diff mbox series

[v8,09/37] hook: introduce hook_exists()

Message ID 20210311021037.3001235-10-emilyshaffer@google.com (mailing list archive)
State New, archived
Headers show
Series config-based hooks | expand

Commit Message

Emily Shaffer March 11, 2021, 2:10 a.m. UTC
Add a helper to easily determine whether any hooks exist for a given
hook event.

Many callers want to check whether some state could be modified by a
hook; that check should include the config-based hooks as well. Optimize
by checking the config directly. Since commands which execute hooks
might want to take args to replace 'hook.runHookDir', let
'hook_exists()' take a hookdir_opt to override that config.

In some cases, external callers today use find_hook() to discover the
location of a hook and then run it manually with run-command.h (that is,
not with run_hook_le()). Later, those cases will call hook.h:run_hook()
directly instead.

Once the entire codebase is using hook_exists() instead of find_hook(),
find_hook() can be safely rolled into hook_exists() and removed from
run-command.h.

Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
---
 hook.c | 19 +++++++++++++++++++
 hook.h | 10 ++++++++++
 2 files changed, 29 insertions(+)
diff mbox series

Patch

diff --git a/hook.c b/hook.c
index d166d17fb0..118931f273 100644
--- a/hook.c
+++ b/hook.c
@@ -243,6 +243,25 @@  void run_hooks_opt_init(struct run_hooks_opt *o)
 	o->run_hookdir = configured_hookdir_opt();
 }
 
+int hook_exists(const char *hookname, enum hookdir_opt should_run_hookdir)
+{
+	const char *value = NULL; /* throwaway */
+	struct strbuf hook_key = STRBUF_INIT;
+	int could_run_hookdir;
+
+	if (should_run_hookdir == HOOKDIR_USE_CONFIG)
+		should_run_hookdir = configured_hookdir_opt();
+
+	could_run_hookdir = (should_run_hookdir == HOOKDIR_INTERACTIVE ||
+				should_run_hookdir == HOOKDIR_WARN ||
+				should_run_hookdir == HOOKDIR_YES)
+				&& !!find_hook(hookname);
+
+	strbuf_addf(&hook_key, "hook.%s.command", hookname);
+
+	return (!git_config_get_value(hook_key.buf, &value)) || could_run_hookdir;
+}
+
 void run_hooks_opt_clear(struct run_hooks_opt *o)
 {
 	strvec_clear(&o->env);
diff --git a/hook.h b/hook.h
index c24b2c9ecd..0df785add5 100644
--- a/hook.h
+++ b/hook.h
@@ -23,6 +23,7 @@  struct list_head* hook_list(const struct strbuf *hookname);
 
 enum hookdir_opt
 {
+	HOOKDIR_USE_CONFIG,
 	HOOKDIR_NO,
 	HOOKDIR_ERROR,
 	HOOKDIR_WARN,
@@ -56,6 +57,15 @@  struct run_hooks_opt
 void run_hooks_opt_init(struct run_hooks_opt *o);
 void run_hooks_opt_clear(struct run_hooks_opt *o);
 
+/*
+ * Returns 1 if any hooks are specified in the config or if a hook exists in the
+ * hookdir. Typically, invoke hook_exsts() like:
+ *   hook_exists(hookname, configured_hookdir_opt());
+ * Like with run_hooks, if you take a --run-hookdir flag, reflect that
+ * user-specified behavior here instead.
+ */
+int hook_exists(const char *hookname, enum hookdir_opt should_run_hookdir);
+
 /*
  * Runs all hooks associated to the 'hookname' event in order. Each hook will be
  * passed 'env' and 'args'.