alibaba / alibaba/open-code-review
fix(cli): provider-directory entries flood the preview and break Will review alignment
- Dominant language
- Go
- Stars
- 24.4k
- Forks
- 1.8k
- Avg merge
- 2d 4m
- Merged PRs (30d)
- 102
Description
## Description
#1223 made `--preview` list provider-directory exclusions. Three presentation problems only became reachable with that change, because those paths could not enter `Preview.Entries` before it.
### 1. The column width is computed globally and shared by both sections
In `outputPreviewText` (`cmd/opencodereview/output.go`):
```go
maxPathLen := 0
for _, e := range p.Entries { // every entry, including excluded ones
if n := len(sanitizeTerminal(e.Path)); n > maxPathLen {
maxPathLen = n
}
}
pathFmt := fmt.Sprintf("%%-%ds", maxPathLen)
```
`pathFmt` is then used for both `Will review` and `Excluded from review`, so a single deep vendored path inflates the padding in the section users actually read:
```console
Preview: 4 file(s) changed | +10 -0
Will review (1):
[A] demo_real.go +3 -0
Excluded from review (3):
[A] target/.pnpm/@scope+some-package@1.2.3/packages/some-package/esm/internal/index.js (provider_directory)
[A] target/demo.go (provider_directory)
[M] internal/diff/git_test.go (default_path)
```
Without that one long path, the same run reads:
```console
Will review (1):
[A] demo_real.go +3 -0
```
On a normal terminal width the insertion/deletion counts are pushed off-screen or wrap. One long path is enough — it does not take many files.
### 2. There is no bound on the excluded list
A repository that commits its vendored tree now gets thousands of lines of paths it cannot act on. `cargo vendor` output is routinely that large, and that is exactly #1197's reporter. The `Excluded from review` section has never had a row cap; before #1223 those files simply never reached it.
### 3. Provider entries are prepended, so the listing no longer follows Git's order
In `internal/agent/preview.go`, `preview` appends the provider-excluded diffs before iterating `selectFiles(a.diffs)`:
```go
for _, d := range providerExcluded { ... } // all provider entries first
for _, dec := range a.selectFiles(a.diffs) { ... } // then everything else
```
So every provider-directory file sorts ahead of the rest regardless of where it sits in the changeset, both in the terminal and in `--output json`'s `files` array. Interleaving them back into Git's order would keep the listing scannable against `git status` / `git diff --stat`. If the fix for problem 2 collapses provider entries into a single line, this still matters for the JSON payload.
## Suggested fix
For problems 1 and 2, aggregating `provider_directory` entries into a single line addresses both, and reads better besides:
```
Excluded from review (3423):
[M] internal/diff/git_test.go (default_path)
[B] assets/logo.png (binary)
3421 file(s) in provider directories (vendor/, target/) — not reviewable
```
It also conveys something the current output loses. `provider_directory` and `default_path` look identical in the terminal, but an `include` rule can override `default_path` and cannot override `provider_directory` — see the comment on `ExcludeProviderDirectory` in `internal/model/preview.go`. Collapsing the non-overridable class into one line says "you cannot act on these" without needing an extra symbol.
Two constraints:
- **Terminal rendering only.** `--output json` must keep every entry in `files`, so script consumers are unaffected.
- The aggregate line should name the directories actually matched, not the whole `providerDirIgnoreDirs` list.
Whatever shape the fix takes, the width calculation has to skip entries that are no longer printed per row, or problem 1 survives.
## Scope
- File(s): `cmd/opencodereview/output.go` (`outputPreviewText`), `internal/agent/preview.go` (`preview`, entry ordering)
- Tests: `cmd/opencodereview/output_helpers_test.go`, `internal/agent/preview_run_test.go`
## Acceptance Criteria
- [ ] A long excluded path no longer affects `Will review` column alignment
- [ ] The excluded section stays bounded when a provider directory holds thousands of files
- [ ] `--output json` output stays complete, and its `files` array follows the changeset order rather than listing provider entries first
- [ ] Tests pass (`make test`)
- [ ] Code check passes (`make check`)
- [ ] Coverage threshold holds (`make coverage`)
## Context
Found while reviewing #1223 after it merged (3bce7ad). The sample output above is from a local build of that commit. `target/` stands in for `vendor/` because `vendor/` is gitignored in this repository; note also that a path containing `dist/` or `node_modules` will not reproduce it, since this repository's `.gitignore` matches those at any depth.
---
*AI/LLM disclosure: the analysis and the reproduction above are my own. Claude Code (Claude Opus 5) was used to polish the English wording and to file this issue via `gh`.*
Contributor guide
Research direction
Start with outputPreviewText in cmd/opencodereview/output.go and preview in internal/agent/preview.go, then run the focused tests in cmd/opencodereview/output_helpers_test.go and internal/agent/preview_run_test.go. Trace how provider_directory entries reach terminal output and the JSON files array. Done means bounded, correctly aligned terminal output, changeset-ordered JSON entries, and passing make test, make check, and make coverage.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, go
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100