Skip to content

Replace nwidger/jsoncolor with an in-tree colorizer#5170

Open
pietern wants to merge 3 commits intomainfrom
replace-jsoncolor
Open

Replace nwidger/jsoncolor with an in-tree colorizer#5170
pietern wants to merge 3 commits intomainfrom
replace-jsoncolor

Conversation

@pietern
Copy link
Copy Markdown
Contributor

@pietern pietern commented May 4, 2026

Changes

Drop github.com/nwidger/jsoncolor and replace fancyJSON with a small in-tree colorizer over json.MarshalIndent output. Same ANSI palette as before (green strings, cyan numbers, bold-green true, red false, magenta null, bold-blue keys). defaultRenderer.renderJson now gates colorization on cmdio TTY/color capabilities; pretty_json template helper stays on !color.NoColor for parity with the other helpers in renderFuncMap.

Why

fancyJSON was the last caller of nwidger/jsoncolor, and it was the only thing forcing fatih/color.Color values across a package boundary. Removing it unblocks a future fatih/color migration and replaces the incidental "color is off because fatih's package init saw stdout isn't a TTY" gating with explicit cmdio capability checks.

Tests

  • Unit tests in libs/cmdio/jsoncolor_test.go cover string/number/literal tokens, escape sequences, key vs value, empty containers, and a round-trip property test (stripping ANSI yields the original bytes).
  • Manual smoke: databricks current-user me -o json on a TTY shows the same colors as before; piped or NO_COLOR=1 produces plain JSON.

PR description drafted with Claude Code.

fancyJSON was the last caller of nwidger/jsoncolor and was the only thing
forcing fatih/color.Color values across a package boundary. Removing it
unblocks a future fatih/color migration.

Replace it with a small token walker over json.MarshalIndent output that
emits the same ANSI palette (green strings, cyan numbers, bold-green
true, red false, magenta null, bold-blue keys). defaultRenderer.renderJson
gates colorization on cmdio TTY/color capabilities; pretty_json template
helper stays on !color.NoColor for parity with the other helpers in
renderFuncMap.

Acceptance test outputs regenerated: encoding/json.MarshalIndent emits
": " (colon + space) where jsoncolor emitted a bare ":". Bundled with
this change is one test.toml redaction regex update for the new spacing.

Co-authored-by: Isaac
@pietern pietern temporarily deployed to test-trigger-is May 4, 2026 11:40 — with GitHub Actions Inactive
@pietern pietern temporarily deployed to test-trigger-is May 4, 2026 11:40 — with GitHub Actions Inactive
@pietern pietern requested a review from simonfaltum May 4, 2026 11:45
Copy link
Copy Markdown
Member

@simonfaltum simonfaltum left a comment

Choose a reason for hiding this comment

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

Deep review (Isaac + Cursor, 2-round swarm)

Verdict: Approved — 0 Critical, 0 Major, 1 Gap (Suggestion), 5 Nits, 4 Suggestions.

Both reviewers independently concluded the implementation approach is sound: tokenize json.MarshalIndent output byte-by-byte, wrap tokens in ANSI, leave punctuation/whitespace untouched, and gate on cmdio capabilities. The round-trip property test is the right invariant. All findings below are nits or follow-up suggestions; nothing blocks merging.

Inline comments follow. Items note which reviewer surfaced them and whether the other confirmed in cross-review.


[Suggestion] Follow-up: colorize iterator JSON output too (Isaac, acknowledged by Cursor)

Out of scope for this PR, but worth a follow-up task: iteratorRenderer.renderJson (unchanged by this PR, around libs/cmdio/render.go:107) still emits uncolored json.MarshalIndent. After this PR, single-object JSON on a TTY is colorized but list JSON on the same TTY is not — a pre-existing inconsistency. Since colorizeJSON accepts any json.MarshalIndent-shaped bytes, a follow-up is small: run it over per-item bytes plus the surrounding [, ,\n , ] punctuation when stdout capabilities allow color.

Comment thread libs/cmdio/render.go Outdated
Comment thread libs/cmdio/render.go Outdated
Comment thread libs/cmdio/render.go
Comment thread libs/cmdio/jsoncolor.go
Comment thread libs/cmdio/jsoncolor.go Outdated
Comment thread libs/cmdio/jsoncolor.go
Comment thread libs/cmdio/jsoncolor_test.go Outdated
Comment thread libs/cmdio/jsoncolor_test.go
Comment thread NEXT_CHANGELOG.md Outdated
- Add Capabilities.SupportsStdoutColor() helper, use at the call site.
- Add renderer-level test (TestRenderJSONColorGate) covering all 4
  combinations of stdoutIsTTY and color.
- Cite SGR Wikipedia reference above the ANSI const block.
- Bump bytes.Buffer Grow hint from len(b)/4 to len(b)/2 (per-token
  overhead is ~9-11 bytes, dense JSON exceeded the old hint).
- Note in scanNumber doc that it assumes valid JSON.
- Rename TestMarshalJSONWithoutColorMatchesEncodingJSON to ...MarshalIndent.
- Tighten changelog entry: clarify it's the single-object render path
  (iterator output already used encoding/json spacing).

Co-authored-by: Isaac
Copy link
Copy Markdown
Member

@simonfaltum simonfaltum left a comment

Choose a reason for hiding this comment

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

Looks solid.

@pietern pietern temporarily deployed to test-trigger-is May 5, 2026 14:45 — with GitHub Actions Inactive
@pietern pietern temporarily deployed to test-trigger-is May 5, 2026 14:45 — with GitHub Actions Inactive
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.

2 participants