Skip to content

Commit

Permalink
feat(text): use lipgloss renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
aymanbagabas committed Mar 8, 2023
1 parent 9519a70 commit a2100d4
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 86 deletions.
2 changes: 1 addition & 1 deletion context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ func TestLogContext_fields(t *testing.T) {
l = FromContext(ctx)
require.NotNil(t, l)
l.Debug("test")
require.Equal(t, "DEBUG test foo=bar\n", buf.String())
require.Equal(t, "DEBU test foo=bar\n", buf.String())
}
17 changes: 15 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
module github.com/charmbracelet/log

go 1.15
go 1.17

require (
github.com/charmbracelet/lipgloss v0.6.0
github.com/charmbracelet/lipgloss v0.7.0
github.com/go-logfmt/logfmt v0.6.0
github.com/mattn/go-isatty v0.0.17
github.com/stretchr/testify v1.8.2
)

require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.15.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
golang.org/x/sys v0.6.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
25 changes: 13 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
github.com/charmbracelet/lipgloss v0.6.0 h1:1StyZB9vBSOyuZxQUcUwGr17JmojPNm87inij9N3wJY=
github.com/charmbracelet/lipgloss v0.6.0/go.mod h1:tHh2wr34xcHjC2HCXIlGSG1jaDF0S0atAUvBMP6Ppuk=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/charmbracelet/lipgloss v0.7.0 h1:cezqy7Ca4XaO4xWQ+uRmsFKyitFnC88GFwce+yCNWos=
github.com/charmbracelet/lipgloss v0.7.0/go.mod h1:uLUJKOkkcdPmrrE60+ZVpe3Fiz0aekJ02eqL2NrpOTs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 h1:y1p/ycavWjGT9FnmSjdbWUlLGvcxrY0Rw3ATltrxOhk=
github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ=
github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0 h1:STjmj0uFfRryL9fzRA/OupNppeAID6QJYPMavTL7jtY=
github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
github.com/muesli/termenv v0.15.0 h1:ZYfCF4CZGhAA4meilZ5pd7tfUX4QLH4zB7OBie4RMS8=
github.com/muesli/termenv v0.15.0/go.mod h1:HeAQPTzpfs016yGtA4g00CsdYnVLJvxsS4ANqrZs2sQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
Expand All @@ -29,9 +30,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
9 changes: 4 additions & 5 deletions logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"strings"
"sync"
"sync/atomic"

"github.com/charmbracelet/lipgloss"
)

var (
Expand All @@ -25,6 +27,7 @@ type Logger struct {
w io.Writer
b bytes.Buffer
mu *sync.RWMutex
re *lipgloss.Renderer

isDiscard uint32

Expand All @@ -35,7 +38,6 @@ type Logger struct {
callerOffset int
formatter Formatter

noStyles bool
reportCaller bool
reportTimestamp bool

Expand Down Expand Up @@ -242,10 +244,7 @@ func (l *Logger) SetOutput(w io.Writer) {
isDiscard = 1
}
atomic.StoreUint32(&l.isDiscard, isDiscard)
if !isTerminal(w) {
// This only affects the TextFormatter
l.noStyles = true
}
l.re = lipgloss.NewRenderer(w)
}

// SetFormatter sets the formatter.
Expand Down
2 changes: 1 addition & 1 deletion pkg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestGlobal(t *testing.T) {
},
{
name: "default logger error with timestamp",
expected: "0001/01/01 00:00:00 ERROR info\n",
expected: "0001/01/01 00:00:00 ERRO info\n",
msg: "info",
kvs: nil,
f: Error,
Expand Down
6 changes: 3 additions & 3 deletions stdlog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestStdLog(t *testing.T) {
},
{
name: "error level",
expected: "ERROR coffee\n",
expected: "ERRO coffee\n",
f: func(l *log.Logger) { l.Print("ERROR coffee") },
},
}
Expand Down Expand Up @@ -67,7 +67,7 @@ func TestStdLog_forceLevel(t *testing.T) {
},
{
name: "error",
expected: "ERROR coffee\n",
expected: "ERRO coffee\n",
level: ErrorLevel,
},
}
Expand Down Expand Up @@ -104,7 +104,7 @@ func TestStdLog_writer(t *testing.T) {
},
{
name: "error",
expected: fmt.Sprintf("ERROR <log/%s:%d> coffee\n", filepath.Base(file), line+27),
expected: fmt.Sprintf("ERRO <log/%s:%d> coffee\n", filepath.Base(file), line+27),
level: ErrorLevel,
},
}
Expand Down
16 changes: 10 additions & 6 deletions styles.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package log

import "github.com/charmbracelet/lipgloss"
import (
"strings"

"github.com/charmbracelet/lipgloss"
)

var (
// TimestampStyle is the style for timestamps.
Expand All @@ -26,7 +30,7 @@ var (

// DebugLevel is the style for debug level.
DebugLevelStyle = lipgloss.NewStyle().
SetString("DEBUG").
SetString(strings.ToUpper(DebugLevel.String())).
Bold(true).
MaxWidth(4).
Foreground(lipgloss.AdaptiveColor{
Expand All @@ -36,7 +40,7 @@ var (

// InfoLevel is the style for info level.
InfoLevelStyle = lipgloss.NewStyle().
SetString("INFO").
SetString(strings.ToUpper(InfoLevel.String())).
Bold(true).
MaxWidth(4).
Foreground(lipgloss.AdaptiveColor{
Expand All @@ -46,7 +50,7 @@ var (

// WarnLevel is the style for warn level.
WarnLevelStyle = lipgloss.NewStyle().
SetString("WARN").
SetString(strings.ToUpper(WarnLevel.String())).
Bold(true).
MaxWidth(4).
Foreground(lipgloss.AdaptiveColor{
Expand All @@ -56,7 +60,7 @@ var (

// ErrorLevel is the style for error level.
ErrorLevelStyle = lipgloss.NewStyle().
SetString("ERROR").
SetString(strings.ToUpper(ErrorLevel.String())).
Bold(true).
MaxWidth(4).
Foreground(lipgloss.AdaptiveColor{
Expand All @@ -66,7 +70,7 @@ var (

// FatalLevel is the style for error level.
FatalLevelStyle = lipgloss.NewStyle().
SetString("FATAL").
SetString(strings.ToUpper(FatalLevel.String())).
Bold(true).
MaxWidth(4).
Foreground(lipgloss.AdaptiveColor{
Expand Down
64 changes: 19 additions & 45 deletions text.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,10 @@ func (l *Logger) writeIndent(w io.Writer, str string, indent string, newline boo
if str != "" {
_, _ = w.Write([]byte(indent))
val := escapeStringForOutput(str, false)
if !l.noStyles {
if valueStyle, ok := ValueStyles[key]; ok {
val = valueStyle.Render(val)
} else {
val = ValueStyle.Render(val)
}
if valueStyle, ok := ValueStyles[key]; ok {
val = valueStyle.Renderer(l.re).Render(val)
} else {
val = ValueStyle.Renderer(l.re).Render(val)
}
_, _ = w.Write([]byte(val))
if newline {
Expand All @@ -40,9 +38,7 @@ func (l *Logger) writeIndent(w io.Writer, str string, indent string, newline boo

_, _ = w.Write([]byte(indent))
val := escapeStringForOutput(str[:nl], false)
if !l.noStyles {
val = ValueStyle.Render(val)
}
val = ValueStyle.Renderer(l.re).Render(val)
_, _ = w.Write([]byte(val))
_, _ = w.Write([]byte{'\n'})
str = str[nl+1:]
Expand Down Expand Up @@ -152,53 +148,40 @@ func (l *Logger) textFormatter(keyvals ...interface{}) {
case TimestampKey:
if t, ok := keyvals[i+1].(time.Time); ok {
ts := t.Format(l.timeFormat)
if !l.noStyles {
ts = TimestampStyle.Render(ts)
}
ts = TimestampStyle.Renderer(l.re).Render(ts)
l.b.WriteString(ts)
l.b.WriteByte(' ')
}
case LevelKey:
if level, ok := keyvals[i+1].(Level); ok {
lvl := strings.ToUpper(level.String())
if !l.noStyles {
lvl = levelStyle(level).String()
}
lvl := levelStyle(level).Renderer(l.re).String()
l.b.WriteString(lvl)
l.b.WriteByte(' ')
}
case CallerKey:
if caller, ok := keyvals[i+1].(string); ok {
caller = fmt.Sprintf("<%s>", caller)
if !l.noStyles {
caller = CallerStyle.Render(caller)
}
caller = CallerStyle.Renderer(l.re).Render(caller)
l.b.WriteString(caller)
l.b.WriteByte(' ')
}
case PrefixKey:
if prefix, ok := keyvals[i+1].(string); ok {
if !l.noStyles {
prefix = PrefixStyle.Render(prefix)
}
prefix = PrefixStyle.Renderer(l.re).Render(prefix)
l.b.WriteString(prefix)
l.b.WriteByte(' ')
}
case MessageKey:
if msg := keyvals[i+1]; msg != nil {
m := fmt.Sprint(msg)
if !l.noStyles {
m = MessageStyle.Render(m)
}
m = MessageStyle.Renderer(l.re).Render(m)
l.b.WriteString(m)
}
default:
sep := separator
indentSep := indentSeparator
if !l.noStyles {
sep = SeparatorStyle.Render(sep)
indentSep = SeparatorStyle.Render(indentSep)
}
sep = SeparatorStyle.Renderer(l.re).Render(sep)
indentSep = SeparatorStyle.Renderer(l.re).Render(indentSep)
moreKeys := i < len(keyvals)-2
key := fmt.Sprint(keyvals[i])
val := fmt.Sprintf("%+v", keyvals[i+1])
Expand All @@ -214,12 +197,10 @@ func (l *Logger) textFormatter(keyvals ...interface{}) {
if vs, ok := ValueStyles[actualKey]; ok {
valueStyle = vs
}
if !l.noStyles {
if keyStyle, ok := KeyStyles[key]; ok {
key = keyStyle.Render(key)
} else {
key = KeyStyle.Render(key)
}
if keyStyle, ok := KeyStyles[key]; ok {
key = keyStyle.Renderer(l.re).Render(key)
} else {
key = KeyStyle.Renderer(l.re).Render(key)
}

// Values may contain multiple lines, and that format
Expand All @@ -242,17 +223,10 @@ func (l *Logger) textFormatter(keyvals ...interface{}) {
l.b.WriteByte(' ')
l.b.WriteString(key)
l.b.WriteString(sep)
if !l.noStyles {
l.b.WriteString(valueStyle.Render(fmt.Sprintf(`"%s"`,
escapeStringForOutput(val, true))))
} else {
l.b.WriteString(fmt.Sprintf(`"%s"`,
escapeStringForOutput(val, true)))
}
l.b.WriteString(valueStyle.Renderer(l.re).Render(fmt.Sprintf(`"%s"`,
escapeStringForOutput(val, true))))
} else {
if !l.noStyles {
val = valueStyle.Render(val)
}
val = valueStyle.Renderer(l.re).Render(val)
l.b.WriteByte(' ')
l.b.WriteString(key)
l.b.WriteString(sep)
Expand Down
Loading

0 comments on commit a2100d4

Please sign in to comment.