pkg/iostreams/color.go (77 lines of code) (raw):

package iostreams import ( "fmt" "io" "os" "strings" "github.com/mattn/go-colorable" "github.com/mgutz/ansi" ) var ( _isColorEnabled = true checkedNoColor = false ) type ColorPalette struct { // Magenta outputs ANSI color if stdout is a tty Magenta func(string) string // Cyan outputs ANSI color if stdout is a tty Cyan func(string) string // Red outputs ANSI color if stdout is a tty Red func(string) string // Yellow outputs ANSI color if stdout is a tty Yellow func(string) string // Blue outputs ANSI color if stdout is a tty Blue func(string) string // Green outputs ANSI color if stdout is a tty Green func(string) string // Gray outputs ANSI color if stdout is a tty Gray func(string) string // Bold outputs ANSI color if stdout is a tty Bold func(string) string } func (s *IOStreams) Color() *ColorPalette { return &ColorPalette{ Magenta: makeColorFunc("magenta"), Cyan: makeColorFunc("cyan"), Red: makeColorFunc("red"), Yellow: makeColorFunc("yellow"), Blue: makeColorFunc("blue"), Green: makeColorFunc("green"), Gray: makeColorFunc("black+h"), Bold: makeColorFunc("default+b"), } } // NewColorable returns an output stream that handles ANSI color sequences on Windows func NewColorable(out io.Writer) io.Writer { if outFile, isFile := out.(*os.File); isFile { return colorable.NewColorable(outFile) } return out } func makeColorFunc(color string) func(string) string { isColorfulOutput := isColorEnabled() && isStdoutTerminal() if isColorfulOutput && color == "black+h" && Is256ColorSupported() { return func(t string) string { return fmt.Sprintf("\x1b[%d;5;%dm%s\x1b[m", 38, 242, t) } } cf := ansi.ColorFunc(color) return func(arg string) string { if isColorfulOutput { return cf(arg) } return arg } } func isColorEnabled() bool { if !checkedNoColor { _, _isColorEnabled = os.LookupEnv("NO_COLOR") _isColorEnabled = !_isColorEnabled // Revert the value NO_COLOR disables color if !_isColorEnabled { _isColorEnabled = os.Getenv("COLOR_ENABLED") == "1" || os.Getenv("COLOR_ENABLED") == "true" } checkedNoColor = true } return _isColorEnabled } func Is256ColorSupported() bool { term := os.Getenv("TERM") colorterm := os.Getenv("COLORTERM") return strings.Contains(term, "256") || strings.Contains(term, "24bit") || strings.Contains(term, "truecolor") || strings.Contains(colorterm, "256") || strings.Contains(colorterm, "24bit") || strings.Contains(colorterm, "truecolor") }