Skip to content

Migrate branch-tidy onto core run_pipeline scan seam#197

Merged
jakebromberg merged 1 commit into
mainfrom
117d-scan-pipeline
Jun 21, 2026
Merged

Migrate branch-tidy onto core run_pipeline scan seam#197
jakebromberg merged 1 commit into
mainfrom
117d-scan-pipeline

Conversation

@jakebromberg

Copy link
Copy Markdown
Owner

Migrates git-branch-tidy onto the shared run_pipeline scan seam (core PR B), the first non-trivial tool: it is fetch: true, owns its fetch today, runs nested parallelism, discovers remote-only branches under --include-remote, and carries a per-repo LandedCache. The seam absorbs the orchestration; the domain logic stays in the closure.

What changed

  • types.rs: delete BranchRepoGroup; BranchScanResult becomes ScanResult<BranchInfo> (the core generic). BranchInfo now implements Classified and IntoJsonItem, replacing the hand-rolled FlatJsonItems for BranchScanResult (the orphan-rule-safe shape). JsonBranch and its From<&BranchInfo> are untouched, so the public JSON is identical.
  • scan.rs: run_scan_repos hands its fetch to the seam via ScanOptions { fetch: true } and delegates to run_pipeline. The closure returns Vec<BranchInfo> (empty on skip); the manual parallel_fetch setup, counts/total_scanned fold, and group assembly are gone. --include-remote discovery, LandedCache, the entity filter, and the inner per-branch par_iter stay inside the closure.
  • output.rs / clean.rs / tests/integration_scan.rs: .branches.items field rename; test fixtures use the generic RepoGroup.

Behavior preservation

  • Fetch parity: run_pipeline fetches every repo before classifying and orders fetch warnings ahead of classify warnings — identical to the old parallel_fetch(...) + warnings.extend(scan_warnings). Covered by core seam tests from PR B.
  • Byte-identical output: --json flat array (incl. landed_ratio/landed_total/unmatched_commits), 8-field porcelain rows, and the LANDED_SUMMARY human summary are unchanged; the existing output.rs string-assertion tests pass unchanged save the .branches.items fixture rename.
  • Empty groups already dropped today (the closure returned None when nothing classified), so routing through run_pipeline is a no-op for that case — not the intentional behavior change the offline tools carried. A regression-guard test (run_scan_repos_skips_repo_when_entity_filter_excludes_all_branches) pins the preserved behavior.
  • Item ordering: the closure still sort_by_key(classification.priority()); the seam does not reorder.
  • Audit runner unchanged: inprocess.rs calls the same 7-arg run_scan_repos and reads .counts; the type alias keeps repos/total_scanned/counts/warnings, so audit JSON keys are identical.

Verification

cargo fmt --all --check, cargo clippy --workspace --all-targets -- -D clippy::all, cargo test --workspace, and cargo +1.93.0 check --workspace (MSRV) all pass locally.

Net −20 lines (deleting the manual fetch setup + counts fold + group assembly, minus the added regression test).

Part of #117

Route branch-tidy through the shared `run_pipeline` seam added in PR B, replacing its hand-rolled `BranchRepoGroup`/`BranchScanResult`/orchestration with the generic `RepoGroup<T>`/`ScanResult<T>` and a thin classifier closure. `BranchInfo` now declares `Classified` and `IntoJsonItem` and relies on the core blanket `FlatJsonItems` impl, so the per-tool `--json` flat array (incl. `landed_ratio`/`landed_total`/`unmatched_commits`), the 8-field porcelain rows, and the `LANDED_SUMMARY` human line stay byte-identical.

Unlike the offline tools migrated in PR C, branch-tidy is `fetch: true`: it owned its own `parallel_fetch` call before classification. That fetch is handed to the seam via `ScanOptions { fetch: true }` — `run_pipeline` fetches every repo first and orders fetch warnings ahead of classify warnings, exactly as the old `parallel_fetch(...) + warnings.extend(scan_warnings)` did. The `--include-remote` remote-only discovery, the per-repo `LandedCache`, the entity filter, and the inner per-branch `par_iter` all stay inside the closure as domain logic.

Empty groups are already dropped today (the closure returned `None` when nothing classified), so routing through `run_pipeline` — which also drops empty groups — is a no-op here, not the intentional behavior change the offline tools carried. A regression-guard test (`run_scan_repos_skips_repo_when_entity_filter_excludes_all_branches`) pins the preserved behavior.

The closure has two verbose sites (local branches and remote-only), so `repo_display_name(repo_path)` is inlined at each `if verbose` block rather than bound once, keeping it off the quiet-run path now that `run_pipeline` computes the group name itself.

Part of #117
@jakebromberg jakebromberg merged commit d737513 into main Jun 21, 2026
3 checks passed
@jakebromberg jakebromberg deleted the 117d-scan-pipeline branch June 21, 2026 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant