feat: Shared core-repos allowlist + wire pr-review programs - #36
feat: Shared core-repos allowlist + wire pr-review programs#36rubambiza wants to merge 3 commits into
Conversation
Introduce a single source of truth for which repos the scanner/fixer
programs act on, so coverage is defined in one place instead of being
hardcoded per script.
- config/core-repos.txt: the 8 curated core rossoctl repos (comments
and blanks allowed).
- program-lib.sh REPO SELECTION section:
- get_core_repos(): reads the allowlist; path resolved relative to
the library (not the caller); $CORE_REPOS_FILE override for tests;
fails loud on missing/empty so no program silently scans zero repos.
- core_repo_names(): bare names for clone-dir membership tests.
- canonical_repo_for_dir(): maps pre-rename clone-dir basenames
(kagenti->rossoctl, kagenti-extensions->cortex) to canonical repos,
in one place.
- tests/test-core-repos.sh: covers parsing, comment/blank stripping,
fail-loud paths, name stripping, and the canonical remap.
Additive only; no consumer script is rewired yet (that is Phase 3/4).
Helpers use portable sed/grep/case and BASH_SOURCE (no GNU-only flags).
Part of rossoctl#29 (epic rossoctl#32).
Assisted-By: Claude Code (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: Gloire Rubambiza <gloire@ibm.com>
Rewire the two PR-review programs to derive their repo set from the shared core-repos allowlist via get_core_repos(), replacing the hardcoded 4-repo lists (which rossoctl#33/rossoctl#34 had corrected to rossoctl names but still duplicated in each script). - pr-review-scanner.sh: build REPOS from get_core_repos() with a portable while-read loop (mapfile is bash 4+, absent on macOS 3.2); fail loud on an empty/unloadable allowlist. - pr-review-impact.sh: get_repos() delegates to get_core_repos(); update the FUTURE SEAM comment to reference the allowlist + rossoctl org. - program-lib.sh: fix the helper usage examples to the portable idiom (no mapfile). Coverage expands from 4 to the 8 core repos, both programs now sharing one source of truth. Verified on bash 3.2: fail-loud path fires, success loads 8 repos; full test suite passes. Part of rossoctl#29 (epic rossoctl#32). Assisted-By: Claude Code (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Gloire Rubambiza <gloire@ibm.com>
clawgenti
left a comment
There was a problem hiding this comment.
Clean refactor that consolidates per-script hardcoded repo lists into a single config/core-repos.txt allowlist, with get_core_repos() wired up correctly across both PR-review programs. The implementation is solid — portable shell constructs, fail-loud semantics, path-relative file resolution, and a hermetic test suite covering all the edge cases.
All checks pass. Ready for human review.
Reviewed by clawgenti using github:pr-review
| # remap table in one place so every script agrees. Unknown names pass through | ||
| # unchanged (identity), so non-remapped repos need no special handling. | ||
| # | ||
| # Usage: canon=$(canonical_repo_for_dir "$repo_dir_basename") |
There was a problem hiding this comment.
nit: The doc comment says "canonical repo name" but the function returns the bare name only (e.g. rossoctl, not rossoctl/rossoctl). Callers need to prepend rossoctl/ to build a full API reference. The section header does explain this, but the per-function Usage: line could be clearer — e.g. # Returns: bare repo name (no owner prefix); prepend owner for API use.
There was a problem hiding this comment.
Addressed the nit in bb91bf0: clarified canonical_repo_for_dir's doc comment to state it returns the bare name only (e.g. rossoctl) and that callers prepend the owner (rossoctl/$canon) for a full API reference. Comment-only, no behavior change.
Address review nit on rossoctl#36: the doc comment said 'canonical repo name' but the function returns only the bare name (e.g. rossoctl), not an owner/name pair. Make explicit that callers prepend the owner (rossoctl/$canon) to build a full API reference. No behavior change. Assisted-By: Claude Code (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Gloire Rubambiza <gloire@ibm.com>
mrsabath
left a comment
There was a problem hiding this comment.
Nice refactor — one allowlist, both programs sourcing it, and real tests. I checked this out and ran it on bash 3.2.57: test-core-repos and test-pr-review-impact both pass, the allowlist loads all 8 repos, get_repos delegation returns 8, the scanner's fail-loud fires on a missing file, and there are no leftover hardcoded lists in scripts/. All commits signed-off.
One non-blocking suggestion inline: pr-review-impact.sh doesn't have the scanner's post-loop empty-guard, so on a broken allowlist it exits 0 with a zero-repo report instead of failing loud. Worth closing the parity gap. canonical_repo_for_dir/core_repo_names have no non-test callers yet, which matches your "next change" note.
Areas reviewed: Shell (executed on bash 3.2), tests, config. CI: DCO pass (only check configured). Verdict: LGTM.
| "rossoctl/cortex" \ | ||
| "rossoctl/automation" \ | ||
| "rossoctl/agent-skills" | ||
| get_core_repos |
There was a problem hiding this comment.
suggestion — fail-loud parity with the scanner. get_repos here delegates to get_core_repos, but the consumer at line 165 (done < <(get_repos)) runs it in process substitution, so set -euo pipefail never sees a non-zero return. On a missing/empty allowlist this script prints the stderr ERROR but continues and exits 0 with a zero-repo aggregate — I confirmed this on bash 3.2. That's the exact silent-empty-scan get_core_repos's docstring warns against, and pr-review-scanner.sh guards against it with an explicit post-loop if [ "${#REPOS[@]}" -eq 0 ]; then exit 1. Consider mirroring that check here (build REPOS with the same while-read loop and assert non-empty) so both wired programs fail loud identically. Not blocking.
Summary
Introduces a single source of truth for which repos the scanner/fixer programs act on, and wires the two PR-review programs to it. Replaces per-script hardcoded repo lists with a shared allowlist.
Two commits:
1. Add shared core-repos allowlist and helpers (
feat)config/core-repos.txt— the 8 curated corerossoctlrepos (comments + blanks allowed).program-lib.shREPO SELECTION section:get_core_repos()— reads the allowlist; path resolved relative to the library (not the caller);$CORE_REPOS_FILEoverride for tests; fails loud on missing/empty so no program silently scans zero repos.core_repo_names()— bare names for clone-dir membership tests (used by Phase 4).canonical_repo_for_dir()— maps pre-rename clone-dir basenames (kagenti→rossoctl,kagenti-extensions→cortex) to canonical repos, in one place.tests/test-core-repos.sh— covers parsing, comment/blank stripping, both fail-loud paths, name stripping, and the canonical remap.2. Source pr-review repo list from the shared allowlist (
refactor)pr-review-scanner.sh— buildsREPOSfromget_core_repos()with a portable while-read loop; fails loud on an empty/unloadable allowlist.pr-review-impact.sh—get_repos()delegates toget_core_repos(); FUTURE SEAM comment updated to reference the allowlist and therossoctlorg.Behavior change
PR-review coverage expands from 4 to the 8 core repos, and both programs now share one list instead of each carrying its own. This is intended — the previous 4-repo lists were a rollout subset.
Portability
Helpers and the new loop use only portable constructs (POSIX
sed/grep/case,BASH_SOURCE, while-read) — nomapfile/readarray(bash 4+, absent on macOS bash 3.2). Verified on bash 3.2.Verification
test-core-repos24-case helper tests + existing suites).pr-review-impactdry-run processes the 8 repos and reports a nonzero reviewed count.Part of #29 (epic #32). The local-clone scanners (link-health, dep-bump) and the deferred dep-bump
--authorfix follow in the next change.Assisted-By: Claude Code