refactor(diary): share the console types through internal/consolekit so diary no longer links bonfire (IN-07, quick-261028-rqd)

This commit is contained in:
Jakub Zych
2026-10-28 20:46:32 +01:00
parent 3520d5d480
commit f3f87f3cc4
14 changed files with 364 additions and 169 deletions

View File

@@ -2,61 +2,37 @@ package bonfire
import (
"io"
"os"
"strings"
"charm.land/lipgloss/v2"
"git.golem15.com/golem15/summercms/internal/consolekit"
"github.com/charmbracelet/colorprofile"
)
// ColorMode selects how console output decides on color: from the terminal
// and the environment, always, or never.
type ColorMode int
type ColorMode = consolekit.ColorMode
const (
// ColorAuto colors output when the writer is a terminal and the
// environment allows it (NO_COLOR and TERM=dumb disable color,
// FORCE_COLOR enables it on any writer).
ColorAuto ColorMode = iota
ColorAuto = consolekit.ColorAuto
// ColorAlways colors output whatever the writer is (--ansi).
ColorAlways
ColorAlways = consolekit.ColorAlways
// ColorNever writes no escape codes at all (--no-ansi).
ColorNever
ColorNever = consolekit.ColorNever
)
// Palette is the shared console look: the status styles of list, help,
// widgets and log lines. Render through a writer that applies the color
// profile (DetectProfile), because lipgloss always emits ANSI codes.
type Palette struct {
// Success marks completed work (green).
Success lipgloss.Style
// Current marks the item in progress and informational lines (cyan).
Current lipgloss.Style
// Warning marks warnings (yellow).
Warning lipgloss.Style
// Error marks failures (red).
Error lipgloss.Style
// ErrorBold marks fatal failures and error levels (bold red).
ErrorBold lipgloss.Style
// Muted marks secondary detail such as times and keys (gray).
Muted lipgloss.Style
// Header marks headings and names (bold).
Header lipgloss.Style
}
// widgets and log lines (Success, Current, Warning, Error, ErrorBold, Muted
// and Header). Render through a writer that applies the color profile
// (DetectProfile), because lipgloss always emits ANSI codes.
type Palette = consolekit.Palette
// DefaultPalette returns the console palette, ported from SSU's status
// styles: green success, cyan current, yellow warning, red and bold red
// errors, gray (240) muted text and bold headers.
func DefaultPalette() Palette {
return Palette{
Success: lipgloss.NewStyle().Foreground(lipgloss.Color("2")),
Current: lipgloss.NewStyle().Foreground(lipgloss.Color("6")),
Warning: lipgloss.NewStyle().Foreground(lipgloss.Color("3")),
Error: lipgloss.NewStyle().Foreground(lipgloss.Color("1")),
ErrorBold: lipgloss.NewStyle().Foreground(lipgloss.Color("1")).Bold(true),
Muted: lipgloss.NewStyle().Foreground(lipgloss.Color("240")),
Header: lipgloss.NewStyle().Bold(true),
}
return consolekit.DefaultPalette()
}
// DetectProfile returns the color profile for console output written to w.
@@ -66,35 +42,5 @@ func DefaultPalette() Palette {
// dumb, and otherwise detects the profile from w and environ, which honours
// NO_COLOR and TERM=dumb. A nil environ means os.Environ().
func DetectProfile(w io.Writer, mode ColorMode, environ []string) colorprofile.Profile {
if mode == ColorNever {
return colorprofile.NoTTY
}
if environ == nil {
environ = os.Environ()
}
if mode == ColorAuto && forceColor(environ) {
mode = ColorAlways
}
p := colorprofile.Detect(w, environ)
if mode == ColorAlways && p < colorprofile.ANSI256 {
p = colorprofile.ANSI256
}
return p
}
func forceColor(environ []string) bool {
if envValue(environ, "NO_COLOR") != "" || envValue(environ, "TERM") == "dumb" {
return false
}
return envValue(environ, "FORCE_COLOR") != ""
}
func envValue(environ []string, key string) string {
for i := len(environ) - 1; i >= 0; i-- {
k, v, ok := strings.Cut(environ[i], "=")
if ok && k == key {
return v
}
}
return ""
return consolekit.DetectProfile(w, mode, environ)
}