diff --git a/pkg/util/term/term.go b/pkg/util/term/term.go index 465b771e..6bcda59d 100644 --- a/pkg/util/term/term.go +++ b/pkg/util/term/term.go @@ -19,6 +19,7 @@ package term import ( "io" "os" + "runtime" "github.com/moby/term" @@ -70,6 +71,32 @@ func IsTerminal(i interface{}) bool { return terminal } +// AllowsColorOutput returns true if the specified writer is a terminal and +// the process environment indicates color output is supported and desired. +func AllowsColorOutput(w io.Writer) bool { + if !IsTerminal(w) { + return false + } + + // https://en.wikipedia.org/wiki/Computer_terminal#Dumb_terminals + if os.Getenv("TERM") == "dumb" { + return false + } + + // https://no-color.org/ + if _, nocolor := os.LookupEnv("NO_COLOR"); nocolor { + return false + } + + // On Windows WT_SESSION is set by the modern terminal component. + // Older terminals have poor support for UTF-8, VT escape codes, etc. + if runtime.GOOS == "windows" && os.Getenv("WT_SESSION") == "" { + return false + } + + return true +} + // Safe invokes the provided function and will attempt to ensure that when the // function returns (or a termination signal is sent) that the terminal state // is reset to the condition it was in prior to the function being invoked. If