From dd84b9d64fb98746a230cd24233ff50a562c39c9 Mon Sep 17 00:00:00 2001 From: 简律纯 Date: Fri, 28 Apr 2023 01:36:44 +0800 Subject: --- cli/internal/ui/ui.go | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 cli/internal/ui/ui.go (limited to 'cli/internal/ui/ui.go') diff --git a/cli/internal/ui/ui.go b/cli/internal/ui/ui.go new file mode 100644 index 0000000..9084c76 --- /dev/null +++ b/cli/internal/ui/ui.go @@ -0,0 +1,121 @@ +package ui + +import ( + "fmt" + "io" + "math" + "os" + "regexp" + "strings" + + "github.com/fatih/color" + "github.com/mattn/go-isatty" + "github.com/mitchellh/cli" + "github.com/vercel/turbo/cli/internal/ci" +) + +const ansiEscapeStr = "[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))" + +// IsTTY is true when stdout appears to be a tty +var IsTTY = isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd()) + +// IsCI is true when we appear to be running in a non-interactive context. +var IsCI = !IsTTY || ci.IsCi() +var gray = color.New(color.Faint) +var bold = color.New(color.Bold) +var ERROR_PREFIX = color.New(color.Bold, color.FgRed, color.ReverseVideo).Sprint(" ERROR ") +var WARNING_PREFIX = color.New(color.Bold, color.FgYellow, color.ReverseVideo).Sprint(" WARNING ") + +// InfoPrefix is a colored string for warning level log messages +var InfoPrefix = color.New(color.Bold, color.FgWhite, color.ReverseVideo).Sprint(" INFO ") + +var ansiRegex = regexp.MustCompile(ansiEscapeStr) + +// Dim prints out dimmed text +func Dim(str string) string { + return gray.Sprint(str) +} + +func Bold(str string) string { + return bold.Sprint(str) +} + +// Adapted from go-rainbow +// Copyright (c) 2017 Raphael Amorim +// Source: https://github.com/raphamorim/go-rainbow +// SPDX-License-Identifier: MIT +func rgb(i int) (int, int, int) { + var f = 0.275 + + return int(math.Sin(f*float64(i)+4*math.Pi/3)*127 + 128), + // int(math.Sin(f*float64(i)+2*math.Pi/3)*127 + 128), + int(45), + int(math.Sin(f*float64(i)+0)*127 + 128) +} + +// Rainbow function returns a formated colorized string ready to print it to the shell/terminal +// +// Adapted from go-rainbow +// Copyright (c) 2017 Raphael Amorim +// Source: https://github.com/raphamorim/go-rainbow +// SPDX-License-Identifier: MIT +func Rainbow(text string) string { + var rainbowStr []string + for index, value := range text { + r, g, b := rgb(index) + str := fmt.Sprintf("\033[1m\033[38;2;%d;%d;%dm%c\033[0m\033[0;1m", r, g, b, value) + rainbowStr = append(rainbowStr, str) + } + + return strings.Join(rainbowStr, "") +} + +type stripAnsiWriter struct { + wrappedWriter io.Writer +} + +func (into *stripAnsiWriter) Write(p []byte) (int, error) { + n, err := into.wrappedWriter.Write(ansiRegex.ReplaceAll(p, []byte{})) + if err != nil { + // The number of bytes returned here isn't directly related to the input bytes + // if ansi color codes were being stripped out, but we are counting on Stdout.Write + // not failing under typical operation as well. + return n, err + } + + // Write must return a non-nil error if it returns n < len(p). Consequently, if the + // wrappedWrite.Write call succeeded we will return len(p) as the number of bytes + // written. + return len(p), nil +} + +// Default returns the default colored ui +func Default() *cli.ColoredUi { + return BuildColoredUi(ColorModeUndefined) +} + +func BuildColoredUi(colorMode ColorMode) *cli.ColoredUi { + colorMode = applyColorMode(colorMode) + + var outWriter, errWriter io.Writer + + if colorMode == ColorModeSuppressed { + outWriter = &stripAnsiWriter{wrappedWriter: os.Stdout} + errWriter = &stripAnsiWriter{wrappedWriter: os.Stderr} + } else { + outWriter = os.Stdout + errWriter = os.Stderr + } + + return &cli.ColoredUi{ + Ui: &cli.BasicUi{ + Reader: os.Stdin, + Writer: outWriter, + ErrorWriter: errWriter, + }, + OutputColor: cli.UiColorNone, + InfoColor: cli.UiColorNone, + WarnColor: cli.UiColor{Code: int(color.FgYellow), Bold: false}, + ErrorColor: cli.UiColorRed, + } +} -- cgit v1.2.3-70-g09d2