Skip to content

Commit

Permalink
feat: Switch to new stdlib log/slog package (#17)
Browse files Browse the repository at this point in the history
* Add color.Colorer to allow disabling colours in a local context

* Add logutil package with various utils for slog

* Switch progress and spinner to use slog and logutils

* Delete log package

* Use go 1.21 in CI

* Force CI

* Fix linting
  • Loading branch information
cszatmary authored Sep 29, 2023
1 parent 7d30e22 commit 167f7ad
Show file tree
Hide file tree
Showing 28 changed files with 1,623 additions and 1,560 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: 2.1
jobs:
lint-test:
docker:
- image: cimg/go:1.18
- image: cimg/go:1.21
steps:
- checkout
- run:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Get all dependencies
setup:
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.50.1
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.54.2
.PHONY: setup

# Clean all build artifacts
Expand Down
113 changes: 84 additions & 29 deletions color/color.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@
//
// There are several functions provided to make it easy to set foreground colors.
//
// // creates a string with a red foreground color
// color.Red("uh oh")
// // creates a string with a red foreground color
// color.Red("uh oh")
//
// Colors can be globally enabled or disabled by using SetEnabled.
// If you wish to control colors in a local scope and not affect the global state,
// create a Colorer instance.
//
// var c color.Colorer
// // Disable colors only for this Colorer
// c.SetEnabled(false)
// s := c.Red("uh oh") // Will not be colored
//
// This package also supports the NO_COLOR environment variable.
// If NO_COLOR is set with any value, colors will be disabled.
Expand Down Expand Up @@ -33,23 +40,76 @@ const (
fgReset
)

// Support for NO_COLOR env var
// https://no-color.org/
var (
noColor = false
enabled bool
noColor = os.Getenv("NO_COLOR") != "" // value doesn't matter, only if it's set
shared Colorer
)

func init() {
// The standard says the value doesn't matter, only whether or not it's set
if _, ok := os.LookupEnv("NO_COLOR"); ok {
noColor = true
}
enabled = !noColor
// IsNoColorEnvSet returns true if the NO_COLOR environment variable is set, regardless of its value.
// See https://no-color.org for more details.
func IsNoColorEnvSet() bool {
return noColor
}

// Colorer allows for creating coloured strings. Using a Colorer instance allows
// for modifying certain attributes that affect output locally instead of globally,
// for example, disable colouring in a local context and not globally.
//
// A zero value Colorer is a valid Colorer ready for use.
// Colors are enabled by default, unless NO_COLOR is set.
type Colorer struct {
disabled bool // disabled so the zero value is enabled
}

// SetEnabled sets whether color is enabled or disabled.
// Note that if NO_COLOR is set this will have no effect.
func (c *Colorer) SetEnabled(e bool) {
c.disabled = !e
}

// Black creates a black colored string.
func (c *Colorer) Black(s string) string {
return c.apply(s, fgBlack, fgReset)
}

// Red creates a red colored string.
func (c *Colorer) Red(s string) string {
return c.apply(s, fgRed, fgReset)
}

// Green creates a green colored string.
func (c *Colorer) Green(s string) string {
return c.apply(s, fgGreen, fgReset)
}

func apply(s string, start, end ansiCode) string {
if !enabled {
// Yellow creates a yellow colored string.
func (c *Colorer) Yellow(s string) string {
return c.apply(s, fgYellow, fgReset)
}

// Blue creates a blue colored string.
func (c *Colorer) Blue(s string) string {
return c.apply(s, fgBlue, fgReset)
}

// Magenta creates a magenta colored string.
func (c *Colorer) Magenta(s string) string {
return c.apply(s, fgMagenta, fgReset)
}

// Cyan creates a cyan colored string.
func (c *Colorer) Cyan(s string) string {
return c.apply(s, fgCyan, fgReset)
}

// White creates a white colored string.
func (c *Colorer) White(s string) string {
return c.apply(s, fgWhite, fgReset)
}

func (c *Colorer) apply(s string, start, end ansiCode) string {
// NO_COLOR always takes precedence.
if noColor || c.disabled {
return s
}

Expand Down Expand Up @@ -84,52 +144,47 @@ func apply(s string, start, end ansiCode) string {
}

// SetEnabled sets whether color is enabled or disabled.
// If the NO_COLOR environment variable is set, this function will
// do nothing as NO_COLOR takes precedence.
// Note that if NO_COLOR is set this will have no effect.
func SetEnabled(e bool) {
// NO_COLOR overrides this
if noColor {
return
}
enabled = e
shared.SetEnabled(e)
}

// Black creates a black colored string.
func Black(s string) string {
return apply(s, fgBlack, fgReset)
return shared.Black(s)
}

// Red creates a red colored string.
func Red(s string) string {
return apply(s, fgRed, fgReset)
return shared.Red(s)
}

// Green creates a green colored string.
func Green(s string) string {
return apply(s, fgGreen, fgReset)
return shared.Green(s)
}

// Yellow creates a yellow colored string.
func Yellow(s string) string {
return apply(s, fgYellow, fgReset)
return shared.Yellow(s)
}

// Blue creates a blue colored string.
func Blue(s string) string {
return apply(s, fgBlue, fgReset)
return shared.Blue(s)
}

// Magenta creates a magenta colored string.
func Magenta(s string) string {
return apply(s, fgMagenta, fgReset)
return shared.Magenta(s)
}

// Cyan creates a cyan colored string.
func Cyan(s string) string {
return apply(s, fgCyan, fgReset)
return shared.Cyan(s)
}

// White creates a white colored string.
func White(s string) string {
return apply(s, fgWhite, fgReset)
return shared.White(s)
}
13 changes: 13 additions & 0 deletions color/color_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,19 @@ func TestColorDisabled(t *testing.T) {
}
}

func TestColorerDisabled(t *testing.T) {
color.SetEnabled(true)
var c color.Colorer
c.SetEnabled(false)
if got, want := c.Red("foo bar"), "foo bar"; got != want {
t.Errorf("got %q, want %q", got, want)
}
// Make sure package functions were not affected
if got, want := color.Red("foo bar"), "\x1b[31mfoo bar\x1b[39m"; got != want {
t.Errorf("got %q, want %q", got, want)
}
}

func BenchmarkRed(b *testing.B) {
color.SetEnabled(true)
b.Run("no strip", func(b *testing.B) {
Expand Down
8 changes: 4 additions & 4 deletions errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ type Kind interface {
// It is recommended to have Op be of the form package.function
// or package.type.method to make it easy to identify the operation.
//
// const op = errors.Op("foo.Bar")
// const op = errors.Op("foo.Bar")
type Op string

// New creates a new error using kind, reason and op.
Expand Down Expand Up @@ -237,7 +237,7 @@ func (e List) Format(s fmt.State, verb rune) {
// However, unlike with errors.New, String allows defining constant error values.
// This can be useful for creating sentinel errors.
//
// const EOF errors.String = "end of file"
// const EOF errors.String = "end of file"
type String string

func (e String) Error() string {
Expand Down Expand Up @@ -277,7 +277,7 @@ func Is(err, target error) bool {
// repeatedly calling Unwrap.
//
// An error matches target if the error's concrete value is assignable to the value
// pointed to by target, or if the error has a method As(interface{}) bool such that
// pointed to by target, or if the error has a method As(any) bool such that
// As(target) returns true. In the latter case, the As method is responsible for
// setting target.
//
Expand All @@ -286,6 +286,6 @@ func Is(err, target error) bool {
//
// As panics if target is not a non-nil pointer to either a type that implements
// error, or to any interface type.
func As(err error, target interface{}) bool {
func As(err error, target any) bool {
return stderrors.As(err, target)
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/TouchBistro/goutils

go 1.18
go 1.21
93 changes: 0 additions & 93 deletions log/entry.go

This file was deleted.

50 changes: 0 additions & 50 deletions log/entry_test.go

This file was deleted.

Loading

0 comments on commit 167f7ad

Please sign in to comment.