Populate `cache` with the complete hook configuration */
| 353 | |
| 354 | /* Populate `cache` with the complete hook configuration */ |
| 355 | static void build_hook_config_map(struct repository *r, struct strmap *cache) |
| 356 | { |
| 357 | struct hook_all_config_cb cb_data = { 0 }; |
| 358 | struct hashmap_iter iter; |
| 359 | struct strmap_entry *e; |
| 360 | |
| 361 | strmap_init(&cb_data.commands); |
| 362 | strmap_init(&cb_data.event_hooks); |
| 363 | string_list_init_dup(&cb_data.disabled_hooks); |
| 364 | strmap_init(&cb_data.parallel_hooks); |
| 365 | strmap_init(&cb_data.event_jobs); |
| 366 | |
| 367 | /* Parse all configs in one run, capturing hook.* including hook.jobs. */ |
| 368 | repo_config(r, hook_config_lookup_all, &cb_data); |
| 369 | |
| 370 | warn_jobs_on_friendly_names(&cb_data); |
| 371 | |
| 372 | /* |
| 373 | * Populate disabled_events: names in disabled_hooks that are not |
| 374 | * friendly-names are event-level switches (hook.<event>.enabled = false). |
| 375 | * Names that are friendly-names are already handled per-hook via the |
| 376 | * hook_config_cache_entry.disabled flag below. |
| 377 | */ |
| 378 | if (r) { |
| 379 | string_list_clear(&r->disabled_events, 0); |
| 380 | string_list_init_dup(&r->disabled_events); |
| 381 | for (size_t i = 0; i < cb_data.disabled_hooks.nr; i++) { |
| 382 | const char *n = cb_data.disabled_hooks.items[i].string; |
| 383 | if (!is_friendly_name(&cb_data, n)) |
| 384 | string_list_append(&r->disabled_events, n); |
| 385 | } |
| 386 | } |
| 387 | |
| 388 | /* Construct the cache from parsed configs. */ |
| 389 | strmap_for_each_entry(&cb_data.event_hooks, &iter, e) { |
| 390 | struct string_list *hook_names = e->value; |
| 391 | struct string_list *hooks; |
| 392 | |
| 393 | CALLOC_ARRAY(hooks, 1); |
| 394 | string_list_init_dup(hooks); |
| 395 | |
| 396 | for (size_t i = 0; i < hook_names->nr; i++) { |
| 397 | const char *hname = hook_names->items[i].string; |
| 398 | enum config_scope scope = |
| 399 | (enum config_scope)(uintptr_t)hook_names->items[i].util; |
| 400 | struct hook_config_cache_entry *entry; |
| 401 | char *command; |
| 402 | |
| 403 | bool is_par = !!strmap_get(&cb_data.parallel_hooks, hname); |
| 404 | bool is_disabled = |
| 405 | !!unsorted_string_list_lookup( |
| 406 | &cb_data.disabled_hooks, hname); |
| 407 | |
| 408 | command = strmap_get(&cb_data.commands, hname); |
| 409 | if (!command) { |
| 410 | if (is_disabled) |
| 411 | warning(_("disabled hook '%s' has no " |
| 412 | "command configured"), hname); |
no test coverage detected