Skip to content

Commit

Permalink
fix: properly handle downsampling colors
Browse files Browse the repository at this point in the history
  • Loading branch information
aymanbagabas committed Feb 26, 2025
1 parent a93532d commit c379e29
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 29 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/charmbracelet/log/v2
go 1.19

require (
github.com/charmbracelet/colorprofile v0.2.1
github.com/charmbracelet/colorprofile v0.2.2
github.com/charmbracelet/lipgloss/v2 v2.0.0-alpha.2.0.20250218201041-aa91bd691cf5
github.com/go-logfmt/logfmt v0.6.0
github.com/stretchr/testify v1.10.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/charmbracelet/colorprofile v0.2.1 h1:McnsQTrDVGWyjar35VdXQtDWtx0aVDTMfRcospsvHrk=
github.com/charmbracelet/colorprofile v0.2.1/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
github.com/charmbracelet/colorprofile v0.2.2 h1:Cqkg0GqDd9vCdhRIBsCbeS8kvePcm8PyZLhRP9AwmaU=
github.com/charmbracelet/colorprofile v0.2.2/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
github.com/charmbracelet/lipgloss/v2 v2.0.0-alpha.2.0.20250218201041-aa91bd691cf5 h1:IctsjPxgKr8rEpUzoqwM2TlVhLcxS2TlOe7PFa6U7M4=
github.com/charmbracelet/lipgloss/v2 v2.0.0-alpha.2.0.20250218201041-aa91bd691cf5/go.mod h1:wvhSDGHyThg9IW8ehatv9MkG4YH5MHYcdhQYmsaCITM=
github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
Expand Down
25 changes: 13 additions & 12 deletions logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"sync"
"sync/atomic"
"time"

"github.com/charmbracelet/colorprofile"
)

// ErrMissingValue is returned when a key is missing a value.
Expand All @@ -21,7 +23,7 @@ type LoggerOption = func(*Logger)

// Logger is a Logger that implements Logger.
type Logger struct {
w io.Writer
w colorprofile.Writer
b bytes.Buffer
mu *sync.RWMutex

Expand Down Expand Up @@ -131,7 +133,7 @@ func (l *Logger) handle(level Level, ts time.Time, frames []runtime.Frame, msg i
}

// WriteTo will reset the buffer
if _, err := l.b.WriteTo(l.w); err != nil {
if _, err := l.b.WriteTo(&l.w); err != nil {
if errors.Is(err, io.ErrShortWrite) {
// Reset the buffer even if the lengths don't match up. If we're
// using colorprofile's Writer, it will strip the ansi sequences based on
Expand Down Expand Up @@ -276,21 +278,20 @@ func (l *Logger) SetOutput(w io.Writer) {
if w == nil {
w = os.Stderr
}
l.w = w
l.w.Forward = w
var isDiscard uint32
if w == io.Discard {
isDiscard = 1
}
atomic.StoreUint32(&l.isDiscard, isDiscard)
// Reuse cached renderers
// TODO is this still relevant?
// if v, ok := registry.Load(w); ok {
// l.re = v.(*colorprofile.Writer)
// } else {
// // TODO calculate background color (termenv.colorcache used to do this)
// l.re = colorprofile.NewWriter(w, os.Environ())
// registry.Store(w, l.re)
// }
}

// SetColorProfile force sets the underlying color profile for the
// TextFormatter.
func (l *Logger) SetColorProfile(profile colorprofile.Profile) {
l.mu.Lock()
defer l.mu.Unlock()
l.w.Profile = profile
}

// SetFormatter sets the formatter.
Expand Down
15 changes: 9 additions & 6 deletions pkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"sync"
"sync/atomic"
"time"

"github.com/charmbracelet/colorprofile"
)

var (
Expand Down Expand Up @@ -60,6 +62,8 @@ func NewWithOptions(w io.Writer, o Options) *Logger {
}

l.SetOutput(w)
// Detect color profile from the writer and environment.
l.SetColorProfile(colorprofile.Detect(w, os.Environ()))
l.SetLevel(Level(l.level))
l.SetStyles(DefaultStyles())

Expand Down Expand Up @@ -133,12 +137,11 @@ func SetPrefix(prefix string) {
Default().SetPrefix(prefix)
}

// TODO
// SetColorProfile force sets the underlying Lip Gloss renderer color profile
// for the TextFormatter.
// func SetColorProfile(profile colorprofile.Profile) {
// Default().SetColorProfile(profile)
// }
// SetColorProfile force sets the underlying color profile for the
// TextFormatter.
func SetColorProfile(profile colorprofile.Profile) {
Default().SetColorProfile(profile)
}

// SetStyles sets the logger styles for the TextFormatter.
func SetStyles(s *Styles) {
Expand Down
22 changes: 12 additions & 10 deletions text_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ func _zeroTime(time.Time) time.Time {

func TestNilStyles(t *testing.T) {
st := DefaultStyles()
l := New(colorprofile.NewWriter(io.Discard, os.Environ()))
l := New(io.Discard)
l.SetColorProfile(colorprofile.TrueColor)
l.SetStyles(nil)
assert.Equal(t, st, l.styles)
}

func TestTextCaller(t *testing.T) {
var buf bytes.Buffer
logger := New(colorprofile.NewWriter(&buf, os.Environ()))
logger := New(&buf)
logger.SetReportCaller(true)
// We calculate the caller offset based on the caller line number.
_, file, line, _ := runtime.Caller(0)
Expand Down Expand Up @@ -100,7 +101,7 @@ func TestTextCaller(t *testing.T) {

func TestTextLogger(t *testing.T) {
var buf bytes.Buffer
logger := New(colorprofile.NewWriter(&buf, os.Environ()))
logger := New(&buf)
cases := []struct {
name string
expected string
Expand Down Expand Up @@ -211,7 +212,7 @@ func TestTextLogger(t *testing.T) {

func TestTextHelper(t *testing.T) {
var buf bytes.Buffer
logger := New(colorprofile.NewWriter(&buf, os.Environ()))
logger := New(&buf)
logger.SetReportCaller(true)
helper := func() {
logger.Helper()
Expand All @@ -226,7 +227,8 @@ func TestTextHelper(t *testing.T) {

func TestTextFatal(t *testing.T) {
var buf bytes.Buffer
logger := New(colorprofile.NewWriter(&buf, os.Environ()))
logger := New(&buf)
logger.SetColorProfile(colorprofile.TrueColor)
logger.SetReportCaller(true)
if os.Getenv("FATAL") == "1" {
logger.Fatal("i'm dead")
Expand All @@ -244,9 +246,8 @@ func TestTextFatal(t *testing.T) {

func TestTextValueStyles(t *testing.T) {
var buf bytes.Buffer
w := colorprofile.NewWriter(&buf, os.Environ())
w.Profile = colorprofile.ANSI256
logger := New(w)
logger := New(&buf)
logger.SetColorProfile(colorprofile.ANSI256)
st := DefaultStyles()
st.Value = lipgloss.NewStyle().Bold(true)
st.Values["key3"] = st.Value.Underline(true)
Expand Down Expand Up @@ -411,12 +412,13 @@ func TestTextValueStyles(t *testing.T) {

func TestCustomLevelStyle(t *testing.T) {
var buf bytes.Buffer
l := New(colorprofile.NewWriter(&buf, os.Environ()))
l := New(&buf)
l.SetColorProfile(colorprofile.TrueColor)
st := DefaultStyles()
lvl := Level(1234)
st.Levels[lvl] = lipgloss.NewStyle().Bold(true).SetString("FUNKY")
l.SetStyles(st)
l.SetLevel(lvl)
l.Log(lvl, "foobar")
assert.Equal(t, "FUNKY foobar\n", buf.String())
assert.Equal(t, "\x1b[1mFUNKY\x1b[m foobar\n", buf.String())
}

0 comments on commit c379e29

Please sign in to comment.