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@xxxxxxxxxx> --- hook.c | 19 +++++++++++++++++++ hook.h | 10 ++++++++++ 2 files changed, 29 insertions(+) diff --git a/hook.c b/hook.c index b631da659b..008167dbe5 100644 --- a/hook.c +++ b/hook.c @@ -248,6 +248,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 fb5132305f..5f770b53ed 100644 --- a/hook.h +++ b/hook.h @@ -23,6 +23,7 @@ struct list_head* hook_list(const char *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'. -- 2.31.1.818.g46aad6cb9e-goog