-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve fatal and color packages (#4)
* feat!: Add ability to register func to run before exiting in fatal BREAKING CHANGE: fatal.ShowStackTraces is now a function * feat: Improve color methods to strip reset values and add tests * Oops
- Loading branch information
Showing
4 changed files
with
402 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,75 @@ | ||
package color | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"regexp" | ||
) | ||
|
||
const ( | ||
red = "\x1b[31m" | ||
green = "\x1b[32m" | ||
yellow = "\x1b[33m" | ||
blue = "\x1b[34m" | ||
magenta = "\x1b[35m" | ||
cyan = "\x1b[36m" | ||
reset = "\x1b[0m" | ||
ansiFgRed = 31 | ||
ansiFgGreen = 32 | ||
ansiFgYellow = 33 | ||
ansiFgBlue = 34 | ||
ansiFgMagenta = 35 | ||
ansiFgCyan = 36 | ||
asnsiFgWhite = 37 | ||
ansiResetFg = 39 | ||
) | ||
|
||
// Support for NO_COLOR env var | ||
// https://no-color.org/ | ||
var noColor = false | ||
|
||
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 | ||
} | ||
} | ||
|
||
func apply(str string, start, end int) string { | ||
if noColor { | ||
return str | ||
} | ||
|
||
regex := regexp.MustCompile(fmt.Sprintf("\\x1b\\[%dm", end)) | ||
// Remove any occurrences of reset to make sure color isn't messed up | ||
sanitized := regex.ReplaceAllString(str, "") | ||
return fmt.Sprintf("\x1b[%dm%s\x1b[%dm", start, sanitized, end) | ||
} | ||
|
||
// Red creates a red colored string | ||
func Red(str string) string { | ||
return red + str + reset | ||
return apply(str, ansiFgRed, ansiResetFg) | ||
} | ||
|
||
// Green creates a green colored string | ||
func Green(str string) string { | ||
return green + str + reset | ||
return apply(str, ansiFgGreen, ansiResetFg) | ||
} | ||
|
||
// Yellow creates a yellow colored string | ||
func Yellow(str string) string { | ||
return yellow + str + reset | ||
return apply(str, ansiFgYellow, ansiResetFg) | ||
} | ||
|
||
// Blue creates a blue colored string | ||
func Blue(str string) string { | ||
return blue + str + reset | ||
return apply(str, ansiFgBlue, ansiResetFg) | ||
} | ||
|
||
// Magenta creates a magenta colored string | ||
func Magenta(str string) string { | ||
return magenta + str + reset | ||
return apply(str, ansiFgMagenta, ansiResetFg) | ||
} | ||
|
||
// Cyan creates a cyan colored string | ||
func Cyan(str string) string { | ||
return cyan + str + reset | ||
return apply(str, ansiFgCyan, ansiResetFg) | ||
} | ||
|
||
// White creates a white colored string | ||
func White(str string) string { | ||
return apply(str, asnsiFgWhite, ansiResetFg) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package color | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestColors(t *testing.T) { | ||
noColor = false | ||
|
||
tests := []struct { | ||
name string | ||
colorFn func(string) string | ||
input string | ||
expected string | ||
}{ | ||
{ | ||
"Red() test", | ||
Red, | ||
"foo bar", | ||
"\x1b[31mfoo bar\x1b[39m", | ||
}, | ||
{ | ||
"Green() test", | ||
Green, | ||
"foo bar", | ||
"\x1b[32mfoo bar\x1b[39m", | ||
}, | ||
{ | ||
"Yellow() test", | ||
Yellow, | ||
"foo bar", | ||
"\x1b[33mfoo bar\x1b[39m", | ||
}, | ||
{ | ||
"Blue() test", | ||
Blue, | ||
"foo bar", | ||
"\x1b[34mfoo bar\x1b[39m", | ||
}, | ||
{ | ||
"Magenta() test", | ||
Magenta, | ||
"foo bar", | ||
"\x1b[35mfoo bar\x1b[39m", | ||
}, | ||
{ | ||
"Cyan() test", | ||
Cyan, | ||
"foo bar", | ||
"\x1b[36mfoo bar\x1b[39m", | ||
}, | ||
{ | ||
"White() test", | ||
White, | ||
"foo bar", | ||
"\x1b[37mfoo bar\x1b[39m", | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
received := tt.colorFn(tt.input) | ||
assert.Equal(t, tt.expected, received) | ||
}) | ||
} | ||
} | ||
|
||
func TestStripReset(t *testing.T) { | ||
noColor = false | ||
|
||
received := Red("foo \x1b[39mbar") | ||
assert.Equal(t, "\x1b[31mfoo bar\x1b[39m", received) | ||
} | ||
|
||
func TestNoColor(t *testing.T) { | ||
noColor = true | ||
|
||
received := Red("foo bar") | ||
assert.Equal(t, "foo bar", received) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.