Skip to content

feat: ANSI colored terminal output, test coverage boost, CI cleanup - #4

Merged
brucearctor merged 2 commits into
mainfrom
feat/test-coverage-ux-ci-cleanup
Jul 9, 2026
Merged

feat: ANSI colored terminal output, test coverage boost, CI cleanup#4
brucearctor merged 2 commits into
mainfrom
feat/test-coverage-ux-ci-cleanup

Conversation

@brucearctor

@brucearctor brucearctor commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Three improvements in one PR:

🎨 Local Mode UX — Rich Terminal Output

code-reviewer --diff now produces ANSI-colored output:

┌─────────────────────────────────────────────────────┐
│  Code Review: 4 finding(s)                          │
│  🔴 1 critical  🟠 2 high  🟡 1 medium              │
└─────────────────────────────────────────────────────┘

── internal/gitlab/client.go ──────────────────────────

  L157 🔴 CRITICAL  SQL injection via string concat
  │ User input concatenated directly into the query...
  │
  │ Suggestion:
  │   db.Query("SELECT * FROM users WHERE id = ?", userID)
  • Severity colors: red=CRITICAL, orange=HIGH, yellow=MEDIUM, blue=LOW
  • Box-drawn summary with counts
  • File-grouped findings with separators
  • Green suggestion blocks for easy copy-paste
  • Auto-detect TTY: plain text when piped (safe for CI logs)
  • --no-color flag + NO_COLOR env var (no-color.org)

🧪 Test Coverage: 92 → 104 tests

Package Before After
reviewer 44.7% 65.7%
All others unchanged unchanged

New tests:

  • output_test.go: 12 tests — ColorTerminalOutput, formatSummaryNote, severityEmoji, severityColor, formatInlineComment
  • validator_test.go: +10 tests — isInHunkRange boundaries, negative lines, partial path matching

🔧 CI Cleanup

  • Split into 3 parallel jobs: build, test, lint
  • Coverage profiling: go test -coverprofile=coverage.out
  • Coverage summary printed in CI output
  • Coverage artifact uploaded for download
  • Deleted 3 stale branches from remote

104 tests pass, -race clean.

Summary by CodeRabbit

  • New Features
    • Added an optional no-color mode (--no-color / NO_COLOR) and automatic colorized terminal output when supported.
    • Enhanced CI with a dedicated test job including race checks and coverage artifact upload.
  • Bug Fixes
    • Improved terminal review rendering, including consistent “No issues found” and summary/count formatting.
  • Tests
    • Added unit tests for color/ANSI rendering, GitLab-style summaries, and additional finding validation scenarios.

Local Mode UX:
- New ColorTerminalOutput with ANSI colors: red=CRITICAL, orange=HIGH,
  yellow=MEDIUM, blue=LOW
- Box-drawn summary header with severity counts
- File-grouped findings with visual separators
- Indented suggestion blocks with green highlighting
- Auto-detect TTY: falls back to plain text when piped
- --no-color flag and NO_COLOR env var (https://no-color.org/)

Test Coverage (92 → 104 tests):
- output_test.go: ColorTerminalOutput, formatSummaryNote, severityEmoji,
  severityColor, formatInlineComment (12 tests)
- validator_test.go: isInHunkRange boundaries, negative line, partial
  path match (10 tests added)
- Reviewer coverage: 44.7% → 65.7%

CI Cleanup:
- Split into 3 parallel jobs: build, test, lint
- Added coverage profiling (go test -coverprofile)
- Coverage summary printed in CI output
- Coverage artifact uploaded for download
- Deleted 3 stale merged branches from remote
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: da86afa4-944b-48f2-9115-a484cc5d0fd8

📥 Commits

Reviewing files that changed from the base of the PR and between 702a6b3 and 93a2a33.

📒 Files selected for processing (1)
  • internal/reviewer/terminal.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/reviewer/terminal.go

📝 Walkthrough

Walkthrough

Adds a NoColor configuration option and a new colored terminal renderer for review results, wires it into Reviewer.Run, expands output and validator tests, and splits CI into separate build, test, and lint jobs.

Changes

Colorized Terminal Output

Layer / File(s) Summary
NoColor configuration option
internal/config/config.go
Adds NoColor to Config and populates it from NO_COLOR and --no-color.
ColorTerminalOutput rendering
internal/reviewer/terminal.go
Adds ANSI terminal rendering, TTY detection, severity coloring, grouped findings, and boxed summary formatting.
Reviewer.Run wiring
internal/reviewer/reviewer.go
Switches terminal output to ColorTerminalOutput when color is enabled.
Output rendering tests
internal/reviewer/output_test.go
Adds tests for colored output, summary formatting, severity helpers, and inline comment rendering.
Validator test coverage
internal/reviewer/validator_test.go
Adds tests for hunk range checks and finding validation edge cases.

CI Workflow Restructure

Layer / File(s) Summary
Build, test coverage, and lint jobs
.github/workflows/ci.yml
Separates build and test jobs, adds coverage artifact upload, and sets an explicit lint job name.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: ANSI terminal output, added tests, and CI cleanup.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/test-coverage-ux-ci-cleanup

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
internal/reviewer/terminal.go (3)

32-134: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Consider splitting ColorTerminalOutput for readability.

The function mixes header-box rendering, severity counting, and per-file/per-finding rendering in one ~100-line block. Extracting helpers (e.g., writeSummaryBox, writeFindingsByFile) would improve readability without changing behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/reviewer/terminal.go` around lines 32 - 134, `ColorTerminalOutput`
is doing too much in one long block, making the rendering logic hard to read and
maintain. Split the function into small helpers such as `writeSummaryBox` for
the header/severity counts and `writeFindingsByFile` for grouping and rendering
findings, then have `ColorTerminalOutput` orchestrate those helpers while
preserving the existing output exactly.

59-80: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Fragile byte-length-based padding for emoji counts line.

Padding correction (padLen := 53 - len(countsLine) + (len(parts) * 2)) hardcodes a per-emoji byte-width offset that only holds for the four specific single-codepoint emoji currently used. Any change to the emoji set (e.g., adding a variation-selector emoji or a wide-but-different-byte-length one) will silently misalign the box border. Consider computing visual width explicitly (e.g., via a rune/width-aware helper) rather than deriving it from byte length + a magic multiplier.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/reviewer/terminal.go` around lines 59 - 80, The counts-line padding
logic in the terminal box renderer is using a byte-length heuristic with a magic
emoji multiplier, which is brittle for any future emoji changes. Update the
padding calculation around countsLine/countsPadded in the terminal rendering
path to use a visual-width-aware helper instead of len(countsLine) plus a fixed
offset, so the border stays aligned regardless of which severity icons are
appended.

151-156: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Replace the local max helper with the Go builtin. internal/reviewer/terminal.go:105,151-156 — the module targets Go 1.26.1, so this helper is unnecessary; use max(1, 50-len(file)) directly and drop the local function.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/reviewer/terminal.go` around lines 151 - 156, Remove the local max
helper from terminal.go and switch the caller that computes the page size in the
reviewer terminal flow to the Go builtin max instead. Update the logic that
currently relies on the max(a, b int) function to use max(1, 50-len(file))
directly, and then delete the now-unused max helper definition.
.github/workflows/ci.yml (1)

32-53: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider a composite action to dedupe checkout/setup-go across jobs.

Each of the three jobs (build, test, lint) repeats the same actions/checkout + actions/setup-go pair. A composite action or reusable workflow step would reduce duplication and keep the Go version pinned in a single place.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 32 - 53, The build, test, and lint
jobs repeat the same checkout and Go setup steps, so centralize that setup in a
reusable composite action or shared workflow component. Update the test job
alongside the other jobs to call the shared setup instead of duplicating
actions/checkout and actions/setup-go, and keep the Go version pin in one place
for easier maintenance.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 32-53: The checkout steps in the test, build, and lint jobs are
persisting Git credentials by default even though these jobs never push changes.
Update each actions/checkout invocation to disable persisted credentials by
setting persist-credentials to false, so the GITHUB_TOKEN is not written into
.git/config after checkout.

In `@internal/reviewer/terminal.go`:
- Around line 110-114: The lint failure comes from building the formatted line
in terminal.go with sb.WriteString(fmt.Sprintf(...)); update the code in the
terminal rendering path to write the formatted output directly to the
strings.Builder using fmt.Fprintf instead. Keep the same formatting and
variables (including f.Line, sevColor, ansiBold, sevLabel, ansiReset, and
f.Title) so the output stays identical while satisfying staticcheck QF1012.

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 32-53: The build, test, and lint jobs repeat the same checkout and
Go setup steps, so centralize that setup in a reusable composite action or
shared workflow component. Update the test job alongside the other jobs to call
the shared setup instead of duplicating actions/checkout and actions/setup-go,
and keep the Go version pin in one place for easier maintenance.

In `@internal/reviewer/terminal.go`:
- Around line 32-134: `ColorTerminalOutput` is doing too much in one long block,
making the rendering logic hard to read and maintain. Split the function into
small helpers such as `writeSummaryBox` for the header/severity counts and
`writeFindingsByFile` for grouping and rendering findings, then have
`ColorTerminalOutput` orchestrate those helpers while preserving the existing
output exactly.
- Around line 59-80: The counts-line padding logic in the terminal box renderer
is using a byte-length heuristic with a magic emoji multiplier, which is brittle
for any future emoji changes. Update the padding calculation around
countsLine/countsPadded in the terminal rendering path to use a
visual-width-aware helper instead of len(countsLine) plus a fixed offset, so the
border stays aligned regardless of which severity icons are appended.
- Around line 151-156: Remove the local max helper from terminal.go and switch
the caller that computes the page size in the reviewer terminal flow to the Go
builtin max instead. Update the logic that currently relies on the max(a, b int)
function to use max(1, 50-len(file)) directly, and then delete the now-unused
max helper definition.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7ab26677-d3bb-4ca2-a3ef-255865325d1c

📥 Commits

Reviewing files that changed from the base of the PR and between 79b858a and 702a6b3.

⛔ Files ignored due to path filters (2)
  • go.mod is excluded by !go.mod
  • go.sum is excluded by !**/*.sum, !go.sum
📒 Files selected for processing (6)
  • .github/workflows/ci.yml
  • internal/config/config.go
  • internal/reviewer/output_test.go
  • internal/reviewer/reviewer.go
  • internal/reviewer/terminal.go
  • internal/reviewer/validator_test.go

Comment thread .github/workflows/ci.yml
Comment on lines +32 to 53
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-go@v5
with:
go-version: '1.26'

- name: Test with coverage
run: go test ./... -v -count=1 -race -coverprofile=coverage.out -covermode=atomic

- name: Coverage summary
run: go tool cover -func=coverage.out | tail -1

- name: Upload coverage artifact
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage.out

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Add persist-credentials: false to checkout steps that don't need to push.

The actions/checkout step here (and similarly in the build/lint jobs) leaves persist-credentials at its default of true, so the GITHUB_TOKEN is written to .git/config for the remainder of the job. This job also uploads a coverage.out artifact — if the artifact path ever broadens (e.g. workspace archiving) or a subsequent step is compromised, the persisted token could leak. Since none of these jobs push commits, credentials aren't needed post-checkout.

🔒 Proposed fix
       - uses: actions/checkout@v4
+        with:
+          persist-credentials: false

Apply the same change to the checkout steps in the build (line 20) and lint (line 58) jobs.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.26'
- name: Test with coverage
run: go test ./... -v -count=1 -race -coverprofile=coverage.out -covermode=atomic
- name: Coverage summary
run: go tool cover -func=coverage.out | tail -1
- name: Upload coverage artifact
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage.out
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-go@v5
with:
go-version: '1.26'
- name: Test with coverage
run: go test ./... -v -count=1 -race -coverprofile=coverage.out -covermode=atomic
- name: Coverage summary
run: go tool cover -func=coverage.out | tail -1
- name: Upload coverage artifact
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage.out
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 36-36: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 32 - 53, The checkout steps in the
test, build, and lint jobs are persisting Git credentials by default even though
these jobs never push changes. Update each actions/checkout invocation to
disable persisted credentials by setting persist-credentials to false, so the
GITHUB_TOKEN is not written into .git/config after checkout.

Source: Linters/SAST tools

Comment thread internal/reviewer/terminal.go Outdated
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