Check if a directory entry should be skipped (hardcoded dirs + gitignore). */
| 488 | |
| 489 | /* Check if a directory entry should be skipped (hardcoded dirs + gitignore). */ |
| 490 | static bool should_skip_directory(const char *entry_name, const char *rel_path, |
| 491 | const cbm_discover_opts_t *opts, const cbm_gitignore_t *gitignore, |
| 492 | const cbm_gitignore_t *global_gi, |
| 493 | const cbm_gitignore_t *cbmignore, const cbm_gitignore_t *local_gi, |
| 494 | const char *local_gi_prefix) { |
| 495 | if (cbm_should_skip_dir(entry_name, opts ? opts->mode : CBM_MODE_FULL)) { |
| 496 | /* #500: a .cbmignore negation (e.g. "!obj/") whose rule is the last |
| 497 | * match for this dir un-skips a built-in skip-list dir — except the |
| 498 | * non-negatable safety core. Fall through so .gitignore/global/local |
| 499 | * rules still apply to the un-skipped dir. */ |
| 500 | bool unskipped = cbmignore && !is_safety_core_dir(entry_name) && |
| 501 | cbm_gitignore_match_result(cbmignore, rel_path, true) < 0; |
| 502 | if (!unskipped) { |
| 503 | return true; |
| 504 | } |
| 505 | } |
| 506 | if (gitignore && cbm_gitignore_matches(gitignore, rel_path, true)) { |
| 507 | return true; |
| 508 | } |
| 509 | bool global_ignored = global_gi && cbm_gitignore_matches(global_gi, rel_path, true); |
| 510 | if (local_gi) { |
| 511 | const char *lrel = local_rel_path(rel_path, local_gi_prefix); |
| 512 | if (cbm_gitignore_matches(local_gi, lrel, true)) { |
| 513 | return true; |
| 514 | } |
| 515 | } |
| 516 | if (cbmignore) { |
| 517 | int cbm_result = cbm_gitignore_match_result(cbmignore, rel_path, true); |
| 518 | if (cbm_result > 0) { |
| 519 | return true; |
| 520 | } |
| 521 | if (cbm_result < 0 && global_ignored) { |
| 522 | return false; |
| 523 | } |
| 524 | } |
| 525 | return global_ignored; |
| 526 | } |
| 527 | |
| 528 | /* Check if a regular file should be skipped (filters + gitignore + size). */ |
| 529 | static bool should_skip_file(const char *entry_name, const char *rel_path, |
no test coverage detected