alibaba / alibaba/open-code-review

fix(cli): provider-directory entries flood the preview and break Will review alignment

Closed
#1,236 1 comment 0 reactions 0 assignees View on GitHub
bug good first issue
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.