Replace logger raw ANSI namespace colors with Lipgloss adaptive styles#32347
Conversation
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Replaces the logger's hand-rolled ANSI 256-color palette and TTY gating with a Lipgloss-based adaptive style palette sourced from pkg/styles, and writes log lines via lipgloss.Fprintf so the colorprofile machinery governs whether colors are emitted.
Changes:
- Swap the raw
\033[38;5;*mpalette andcolorResetfor a[]lipgloss.Stylepalette usingstyles.Color*adaptive colors. - Drop the
tty.IsStderrTerminal()check; rely on Lipgloss/colorprofile (includingNO_COLOR) for color suppression, keepingDEBUG_COLORS=0as an explicit opt-out. - Update
selectColorto return either the plain namespace or a pre-rendered styled namespace, and update tests (removingTestColorDisabling, addingTestNoColorEnvironment).
Show a summary per file
| File | Description |
|---|---|
| pkg/logger/logger.go | Replaces raw ANSI palette with Lipgloss adaptive styles, removes TTY gating, and switches output to lipgloss.Fprintf. |
| pkg/logger/logger_test.go | Adapts color tests to the new rendered-namespace contract and adds a NO_COLOR=1 ANSI-absence check. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 2/2 changed files
- Comments generated: 3
| lipgloss.NewStyle().Foreground(styles.ColorBackground), | ||
| lipgloss.NewStyle().Foreground(styles.ColorTableAltRow), |
| lipgloss.NewStyle().Foreground(styles.ColorBorder), | ||
| lipgloss.NewStyle().Foreground(styles.ColorBackground), | ||
| lipgloss.NewStyle().Foreground(styles.ColorTableAltRow), | ||
| lipgloss.NewStyle().Foreground(lipgloss.Color("33")), |
| func selectColor(namespace string) string { | ||
| if !debugColors || !isTTY { | ||
| return "" | ||
| if !debugColors { | ||
| return namespace | ||
| } | ||
|
|
||
| // Use FNV-1a hash for consistent color assignment | ||
| h := fnv.New32a() | ||
| // hash.Hash.Write never returns an error in practice, but check to satisfy gosec G104 | ||
| if _, err := h.Write([]byte(namespace)); err != nil { | ||
| // Return empty string (no color) if write somehow fails | ||
| return "" | ||
| // Return plain namespace (no color) if write somehow fails | ||
| return namespace | ||
| } | ||
| hash := h.Sum32() | ||
|
|
||
| // Select color from palette based on hash | ||
| return colorPalette[hash%uint32(len(colorPalette))] | ||
| // Select color from palette based on hash and render namespace with it. | ||
| return colorPalette[hash%uint32(len(colorPalette))].Render(namespace) |
🧪 Test Quality Sentinel ReportTest Quality Score: 97/100✅ Excellent test quality
Test Classification Details
Quality Highlights
Language SupportTests analyzed:
Verdict
📖 Understanding Test ClassificationsDesign Tests (High Value) verify what the system does:
Implementation Tests (Low Value) verify how the system does it:
Goal: Shift toward tests that describe the system's behavioral contract — the promises it makes to its users and collaborators.
|
There was a problem hiding this comment.
Skills-Based Review 🧠
Applied /zoom-out and /tdd — this is a clean refactor with accompanying test updates, both skills apply directly.
Key Themes
- Naming drift (zoom-out): the
colorfield andselectColorfunction no longer describe what they hold/return after the migration. Both now carry the fully-rendered namespace label, not a raw color code. Small rename = big clarity gain. - One stray raw color (zoom-out):
lipgloss.Color("33")in the palette sits alongside 11 semanticstyles.Color*entries — partially defeats the purpose of the migration. - Test fragility (tdd): the
\x1b[assertion inTestColorSelectiontests the internal encoding, not the behaviour; Lipgloss strips ANSI in no-TTY environments (CI), so this will fail there. TheTestNoColorEnvironmentpattern already shows the right approach. - Test isolation bug (tdd):
debugEnvis mutated inTestNoColorEnvironmentwithout a corresponding restore — onlydebugColorsis cleaned up.
Positive Highlights
- ✅ Removing
tty.IsStderrTerminal()gating in favour of Lipgloss's own adaptive output is the right architectural move — centralises TTY detection. - ✅
TestNoColorEnvironmentis a well-structured end-to-end behavioural test (Arrange → Act → Assert through the publicPrintfAPI). - ✅ The PR description is clear and the before/after code sample helps reviewers quickly understand the change.
Verdict
The core approach is solid. The naming issues and the \x1b[ test are the most important things to address before merge.
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · ● 6.9M
|
@copilot review comments |
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Addressed in commit Updated the logger palette to only use readable foreground-oriented adaptive colors (removed |
✨ Enhancement
What does this improve?
The debug logger in
pkg/logger/logger.gono longer hardcodes ANSI 256-color escape sequences; namespace coloring now uses Lipgloss styles aligned with the sharedpkg/stylescolor system. This keeps hash-based namespace color assignment while moving color rendering to adaptive styling.Logger color model migration
\033[38;5;*mpalette entries and reset code with a Lipgloss style palette.Terminal/color behavior
tty.IsStderrTerminal()gating from logger color selection.lipgloss.Fprintf(os.Stderr, ...)so color output follows Lipgloss/colorprofile behavior.DEBUG_COLORS=0as an explicit opt-out path (plain namespace output).Coverage updates
pkg/logger/logger_test.goassertions to reflect styled namespace rendering.NO_COLOR=1.