Uh oh!
There was an error while loading. Please reload this page.
Replace nwidger/jsoncolor with an in-tree colorizer - #5170
Conversation
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
simonfaltum
left a comment
There was a problem hiding this comment.
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.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- 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
Uh oh!
There was an error while loading. Please reload this page.
## Summary - Drops `github.com/fatih/color` as a direct dependency by migrating its ~14 call sites (bundle render, bundle run, cfgpickers, logstream, cmd/labs, experimental/aitools, experimental/ssh, python_mutator) to a small ANSI helper set. - Adds `libs/cmdio/color.go` with `cmdio.Red(ctx, msg)`-style helpers and a `RenderFuncMap(ctx)` for templates. The gate matches fatih/color's historical stdout-TTY decision and degrades to plain text when ctx has no cmdIO attached. - Stacks on top of #5170. ANSI constants shared across both colorizers now live in `libs/cmdio/color.go`. No user-visible output changes — the new helpers emit byte-identical SGR sequences. ## Test plan - [ ] Manual smoke: `databricks bundle validate` against a bundle with errors and warnings (colored summary on TTY, uncolored when piped) and `databricks current-user me -o json` (colored on TTY, uncolored when piped through `jq`). This pull request and its description were written by Isaac.
#5227) Since #5170 the CLI's JSON output uses the standard `: ` separator (via `json.MarshalIndent`) rather than the compact `":"` form produced by the previous `nwidger/jsoncolor` dependency. `TestClustersGet`'s substring assertion still expected the compact form and has been failing in every nightly environment; updating it to match the new output. This pull request and its description were written by Isaac.
Since #5170 the CLI's JSON output uses the standard `: ` separator (via `json.MarshalIndent`) rather than the compact `":"` form produced by the previous `nwidger/jsoncolor` dependency. The acceptance output for `bundle/resources/volumes/recreate` still captured the compact form for one `grants get` line and has been failing on UCWS nightlies since #5170 merged. #5227 picked up the same staleness in `TestClustersGet`; this picks up the missed acceptance output. This pull request and its description were written by Isaac.
## 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._
## Summary - Drops `github.com/fatih/color` as a direct dependency by migrating its ~14 call sites (bundle render, bundle run, cfgpickers, logstream, cmd/labs, experimental/aitools, experimental/ssh, python_mutator) to a small ANSI helper set. - Adds `libs/cmdio/color.go` with `cmdio.Red(ctx, msg)`-style helpers and a `RenderFuncMap(ctx)` for templates. The gate matches fatih/color's historical stdout-TTY decision and degrades to plain text when ctx has no cmdIO attached. - Stacks on top of #5170. ANSI constants shared across both colorizers now live in `libs/cmdio/color.go`. No user-visible output changes — the new helpers emit byte-identical SGR sequences. ## Test plan - [ ] Manual smoke: `databricks bundle validate` against a bundle with errors and warnings (colored summary on TTY, uncolored when piped) and `databricks current-user me -o json` (colored on TTY, uncolored when piped through `jq`). This pull request and its description were written by Isaac.
#5227) Since #5170 the CLI's JSON output uses the standard `: ` separator (via `json.MarshalIndent`) rather than the compact `":"` form produced by the previous `nwidger/jsoncolor` dependency. `TestClustersGet`'s substring assertion still expected the compact form and has been failing in every nightly environment; updating it to match the new output. This pull request and its description were written by Isaac.
Since #5170 the CLI's JSON output uses the standard `: ` separator (via `json.MarshalIndent`) rather than the compact `":"` form produced by the previous `nwidger/jsoncolor` dependency. The acceptance output for `bundle/resources/volumes/recreate` still captured the compact form for one `grants get` line and has been failing on UCWS nightlies since #5170 merged. #5227 picked up the same staleness in `TestClustersGet`; this picks up the missed acceptance output. This pull request and its description were written by Isaac.
## 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._
## Summary - Drops `github.com/fatih/color` as a direct dependency by migrating its ~14 call sites (bundle render, bundle run, cfgpickers, logstream, cmd/labs, experimental/aitools, experimental/ssh, python_mutator) to a small ANSI helper set. - Adds `libs/cmdio/color.go` with `cmdio.Red(ctx, msg)`-style helpers and a `RenderFuncMap(ctx)` for templates. The gate matches fatih/color's historical stdout-TTY decision and degrades to plain text when ctx has no cmdIO attached. - Stacks on top of databricks#5170. ANSI constants shared across both colorizers now live in `libs/cmdio/color.go`. No user-visible output changes — the new helpers emit byte-identical SGR sequences. ## Test plan - [ ] Manual smoke: `databricks bundle validate` against a bundle with errors and warnings (colored summary on TTY, uncolored when piped) and `databricks current-user me -o json` (colored on TTY, uncolored when piped through `jq`). This pull request and its description were written by Isaac.
databricks#5227) Since databricks#5170 the CLI's JSON output uses the standard `: ` separator (via `json.MarshalIndent`) rather than the compact `":"` form produced by the previous `nwidger/jsoncolor` dependency. `TestClustersGet`'s substring assertion still expected the compact form and has been failing in every nightly environment; updating it to match the new output. This pull request and its description were written by Isaac.
…cks#5245) Since databricks#5170 the CLI's JSON output uses the standard `: ` separator (via `json.MarshalIndent`) rather than the compact `":"` form produced by the previous `nwidger/jsoncolor` dependency. The acceptance output for `bundle/resources/volumes/recreate` still captured the compact form for one `grants get` line and has been failing on UCWS nightlies since databricks#5170 merged. databricks#5227 picked up the same staleness in `TestClustersGet`; this picks up the missed acceptance output. This pull request and its description were written by Isaac.
Changes
Drop
github.com/nwidger/jsoncolorand replacefancyJSONwith a small in-tree colorizer overjson.MarshalIndentoutput. Same ANSI palette as before (green strings, cyan numbers, bold-greentrue, redfalse, magentanull, bold-blue keys).defaultRenderer.renderJsonnow gates colorization on cmdio TTY/color capabilities;pretty_jsontemplate helper stays on!color.NoColorfor parity with the other helpers inrenderFuncMap.Why
fancyJSONwas the last caller ofnwidger/jsoncolor, and it was the only thing forcingfatih/color.Colorvalues across a package boundary. Removing it unblocks a futurefatih/colormigration 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
libs/cmdio/jsoncolor_test.gocover string/number/literal tokens, escape sequences, key vs value, empty containers, and a round-trip property test (stripping ANSI yields the original bytes).databricks current-user me -o jsonon a TTY shows the same colors as before; piped orNO_COLOR=1produces plain JSON.PR description drafted with Claude Code.