From 9c491b16fe7d406aa04bb3aa4901be64b99d0473 Mon Sep 17 00:00:00 2001 From: Charlie Drage Date: Tue, 12 Apr 2022 09:41:45 -0400 Subject: [PATCH] Updates odo init output, fixes colorized output for tests. (#5613) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update vendoring for coloring to add NO_COLOR * Updates odo init output / adds logo **What type of PR is this:** /kind feature **What does this PR do / why we need it:** We have the logo appearing in `odo dev` and `odo deploy` Those 3 commands are the most used with `odo`, and the ones that are most used. All three should have similar and consistent output that contains: * What the component is doing (first line) * What's detected (in odo init, it's the files, in odo deploy and dev it's the component name) * odo version that is being used / outputted. ```sh $ odo init __ / \__ Initializing a new component \__/ \ Files: No source code detected, a starter project will be created in the current directory / \__/ odo version: v2.5.0 \__/ Interactive mode enabled, please answer the following questions: ? Select language: javascript ? Select project type: Next.js ✓ Downloading devfile "nodejs-nextjs" from registry "DefaultDevfileRegistry" [450ms] ? Which starter project do you want to use? nodejs-nextjs-starter ? Enter component name: my-nodejs-nextjs-app ✓ Downloading starter project "nodejs-nextjs-starter" [516ms] Your new component 'my-nodejs-nextjs-app' is ready in the current directory. To start editing your component, use 'odo dev' and open this folder in your favorite IDE. Changes will be directly reflected on the cluster. ``` **Which issue(s) this PR fixes:** N/A **PR acceptance criteria:** - [X] Unit test - [X] Integration test - [X] Documentation **How to test changes / Special notes to the reviewer:** N/A Signed-off-by: Charlie Drage * Update based on reviews Signed-off-by: Charlie Drage * Update based on review Signed-off-by: Charlie Drage --- Makefile | 4 ++ go.mod | 6 +-- go.sum | 9 +++-- pkg/log/status.go | 7 +++- pkg/odo/cli/init/init.go | 21 +++++++---- pkg/odo/cli/messages/messages.go | 7 ++++ tests/helper/helper_interactive.go | 1 + tests/interactive/cmd_init_test.go | 37 +++++++++++-------- vendor/github.com/fatih/color/README.md | 19 ++++++---- vendor/github.com/fatih/color/color.go | 25 ++++++++++--- vendor/github.com/fatih/color/doc.go | 2 + vendor/github.com/fatih/color/go.mod | 4 +- vendor/github.com/fatih/color/go.sum | 10 +++-- .../mattn/go-colorable/noncolorable.go | 5 ++- vendor/github.com/mattn/go-isatty/.travis.yml | 14 ------- vendor/github.com/mattn/go-isatty/go.mod | 2 +- .../github.com/mattn/go-isatty/isatty_bsd.go | 1 + .../mattn/go-isatty/isatty_others.go | 3 +- .../mattn/go-isatty/isatty_plan9.go | 1 + .../mattn/go-isatty/isatty_solaris.go | 9 ++--- .../mattn/go-isatty/isatty_tcgets.go | 3 +- .../mattn/go-isatty/isatty_windows.go | 6 +-- .../github.com/mattn/go-isatty/renovate.json | 8 ---- vendor/modules.txt | 6 +-- 24 files changed, 126 insertions(+), 84 deletions(-) create mode 100644 pkg/odo/cli/messages/messages.go delete mode 100644 vendor/github.com/mattn/go-isatty/.travis.yml delete mode 100644 vendor/github.com/mattn/go-isatty/renovate.json diff --git a/Makefile b/Makefile index 20b473ee5..5ab77ffed 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,10 @@ PKGS := $(shell go list $(COMMON_GOFLAGS) ./... | grep -v $(PROJECT)/vendor | g FILES := odo dist TIMEOUT ?= 14400s +# We should NOT output any color when running interactive tests +# or else we may have issues with regards to comparing coloured output strings +NO_COLOR = true + # Env variable TEST_EXEC_NODES is used to pass spec execution type # (parallel or sequential) for ginkgo tests. To run the specs sequentially use # TEST_EXEC_NODES=1, otherwise by default the specs are run in parallel on 4 ginkgo test node if running on PSI cluster or 24 nodes if running on IBM Cloud cluster. diff --git a/go.mod b/go.mod index 41138c236..0991f7b1c 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/devfile/library v1.2.1-0.20220217161036-0f5995513e92 github.com/devfile/registry-support/index/generator v0.0.0-20211012185733-0a73f866043f github.com/devfile/registry-support/registry-library v0.0.0-20211125162259-d7edf148d3e2 - github.com/fatih/color v1.10.0 + github.com/fatih/color v1.13.0 github.com/frapposelli/wwhrd v0.4.0 github.com/fsnotify/fsnotify v1.5.1 github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 @@ -23,7 +23,7 @@ require ( github.com/kr/pty v1.1.5 github.com/kubernetes-sigs/service-catalog v0.3.1 github.com/kylelemons/godebug v1.1.0 - github.com/mattn/go-colorable v0.1.8 + github.com/mattn/go-colorable v0.1.9 github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/olekukonko/tablewriter v0.0.5 github.com/onsi/ginkgo v4.7.0-origin.0+incompatible @@ -61,7 +61,7 @@ require ( k8s.io/kubectl v0.22.1 k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a sigs.k8s.io/controller-runtime v0.10.2 - sigs.k8s.io/yaml v1.3.0 // indirect + sigs.k8s.io/yaml v1.3.0 ) diff --git a/go.sum b/go.sum index 02007854e..2923e17bb 100644 --- a/go.sum +++ b/go.sum @@ -332,8 +332,9 @@ github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0 github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= @@ -767,15 +768,17 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= diff --git a/pkg/log/status.go b/pkg/log/status.go index fcdd4aece..3380f1614 100644 --- a/pkg/log/status.go +++ b/pkg/log/status.go @@ -286,8 +286,13 @@ func Swarningf(format string, a ...interface{}) string { // \__/ // func Title(firstLine, secondLine, thirdLine string) { + fmt.Fprint(GetStdout(), Stitle(firstLine, secondLine, thirdLine)) +} + +// Stitle is the same as Title but returns the string instead +func Stitle(firstLine, secondLine, thirdLine string) string { blue := color.New(color.FgBlue).SprintFunc() - fmt.Fprintf(GetStdout(), ` __ + return fmt.Sprintf(` __ / \__ %s \__/ \ %s / \__/ %s diff --git a/pkg/odo/cli/init/init.go b/pkg/odo/cli/init/init.go index d5ebb49e1..30999b801 100644 --- a/pkg/odo/cli/init/init.go +++ b/pkg/odo/cli/init/init.go @@ -15,11 +15,13 @@ import ( "github.com/redhat-developer/odo/pkg/devfile/location" "github.com/redhat-developer/odo/pkg/init/backend" "github.com/redhat-developer/odo/pkg/log" + "github.com/redhat-developer/odo/pkg/odo/cli/messages" "github.com/redhat-developer/odo/pkg/odo/cmdline" "github.com/redhat-developer/odo/pkg/odo/genericclioptions" "github.com/redhat-developer/odo/pkg/odo/genericclioptions/clientset" odoutil "github.com/redhat-developer/odo/pkg/odo/util" scontext "github.com/redhat-developer/odo/pkg/segment/context" + "github.com/redhat-developer/odo/pkg/version" "k8s.io/kubectl/pkg/util/templates" "k8s.io/utils/pointer" @@ -129,12 +131,17 @@ func (o *InitOptions) Run(ctx context.Context) (err error) { if err != nil { return err } + + // Show a welcome message for when you initially run `odo init`. + + var infoOutput string if isEmptyDir && len(o.flags) == 0 { - fmt.Println("The current directory is empty. odo will help you start a new project.") + infoOutput = messages.NoSourceCodeDetected } else if len(o.flags) == 0 { - fmt.Println("The current directory already contains source code. " + - "odo will try to autodetect the language and project type in order to select the best suited Devfile for your project.") + infoOutput = messages.SourceCodeDetected } + log.Title(messages.InitializingNewComponent, infoOutput, "odo version: "+version.VERSION) + log.Info("\nInteractive mode enabled, please answer the following questions:") devfileObj, devfilePath, err := o.clientset.InitClient.SelectAndPersonalizeDevfile(o.flags, o.contextDir) if err != nil { @@ -179,8 +186,8 @@ func (o *InitOptions) Run(ctx context.Context) (err error) { scontext.SetDevfileName(ctx, devfileObj.GetMetadataName()) exitMessage := fmt.Sprintf(` -Your new component %q is ready in the current directory. -To start editing your component, use "odo dev" and open this folder in your favorite IDE. +Your new component '%s' is ready in the current directory. +To start editing your component, use 'odo dev' and open this folder in your favorite IDE. Changes will be directly reflected on the cluster.`, devfileObj.Data.GetMetadata().Name) // show information about `odo deploy` command only if the devfile has kind: deploy command defined. @@ -215,8 +222,8 @@ func NewCmdInit(name, fullName string) *cobra.Command { initCmd.Flags().String(backend.FLAG_NAME, "", "name of the component to create") initCmd.Flags().String(backend.FLAG_DEVFILE, "", "name of the devfile in devfile registry") - initCmd.Flags().String(backend.FLAG_DEVFILE_REGISTRY, "", "name of the devfile registry (as configured in \"odo registry list\"). It can be used in combination with --devfile, but not with --devfile-path") - initCmd.Flags().String(backend.FLAG_STARTER, "", "name of the starter project. Available starter projects can be found with \"odo catalog describe component \"") + initCmd.Flags().String(backend.FLAG_DEVFILE_REGISTRY, "", "name of the devfile registry (as configured in \"odo preference registry list\"). It can be used in combination with --devfile, but not with --devfile-path") + initCmd.Flags().String(backend.FLAG_STARTER, "", "name of the starter project") initCmd.Flags().String(backend.FLAG_DEVFILE_PATH, "", "path to a devfile. This is an alternative to using devfile from Devfile registry. It can be local filesystem path or http(s) URL") // Add a defined annotation in order to appear in the help menu diff --git a/pkg/odo/cli/messages/messages.go b/pkg/odo/cli/messages/messages.go new file mode 100644 index 000000000..144b179d5 --- /dev/null +++ b/pkg/odo/cli/messages/messages.go @@ -0,0 +1,7 @@ +package messages + +// Below are various "outputs" that we use in both the CLI and test cases, so we must +// put them in a common place +const InitializingNewComponent = "Initializing new component" +const SourceCodeDetected = "Files: Source code detected, a Devfile will be determined based upon source code autodetection" +const NoSourceCodeDetected = "Files: No source code detected, a starter project will be created in the current directory" diff --git a/tests/helper/helper_interactive.go b/tests/helper/helper_interactive.go index 59bfdb440..c5fb332b1 100644 --- a/tests/helper/helper_interactive.go +++ b/tests/helper/helper_interactive.go @@ -57,6 +57,7 @@ func RunInteractive(command []string, env []string, tester Tester) (string, erro term := vt10x.New(vt10x.WithWriter(pts)) + // Set to 1 MINUTE timeout, since the command may take a while to start c, err := expect.NewConsole(expect.WithStdin(ptm), expect.WithStdout(term), expect.WithCloser(pts, ptm), expect.WithDefaultTimeout(3*time.Minute)) if err != nil { log.Fatal(err) diff --git a/tests/interactive/cmd_init_test.go b/tests/interactive/cmd_init_test.go index 48e1b5138..7d2293bf7 100644 --- a/tests/interactive/cmd_init_test.go +++ b/tests/interactive/cmd_init_test.go @@ -6,11 +6,17 @@ package interactive import ( "fmt" "log" + "os" "path/filepath" + "strings" + + odolog "github.com/redhat-developer/odo/pkg/log" + "github.com/redhat-developer/odo/pkg/odo/cli/messages" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "github.com/redhat-developer/odo/pkg/version" "github.com/redhat-developer/odo/tests/helper" ) @@ -22,6 +28,10 @@ var _ = Describe("odo init interactive command tests", func() { var _ = BeforeEach(func() { commonVar = helper.CommonBeforeEach() helper.Chdir(commonVar.Context) + + // We make EXPLICITLY sure that we are outputting with NO COLOR + // this is because in some cases we are comparing the output with a colorized one + os.Setenv("NO_COLOR", "true") }) // Clean up after the test @@ -46,11 +56,11 @@ var _ = Describe("odo init interactive command tests", func() { helper.ExpectString(ctx, "Enter component name") helper.SendLine(ctx, "my-go-app") - helper.ExpectString(ctx, "Your new component \"my-go-app\" is ready in the current directory.") + helper.ExpectString(ctx, "Your new component 'my-go-app' is ready in the current directory") }) Expect(err).To(BeNil()) - Expect(output).To(ContainSubstring("Your new component \"my-go-app\" is ready in the current directory.")) + Expect(output).To(ContainSubstring("Your new component 'my-go-app' is ready in the current directory")) Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) }) @@ -71,12 +81,12 @@ var _ = Describe("odo init interactive command tests", func() { helper.ExpectString(ctx, "Enter component name") helper.SendLine(ctx, "my-go-app") - helper.ExpectString(ctx, "Your new component \"my-go-app\" is ready in the current directory.") + helper.ExpectString(ctx, "Your new component 'my-go-app' is ready in the current directory") }) Expect(err).To(BeNil()) - Expect(output).To(ContainSubstring("Your new component \"my-go-app\" is ready in the current directory.")) + Expect(output).To(ContainSubstring("Your new component 'my-go-app' is ready in the current directory")) Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) }) @@ -100,7 +110,7 @@ var _ = Describe("odo init interactive command tests", func() { helper.SendLine(ctx, fmt.Sprintf("my-%s-app", language)) helper.ExpectString(ctx, - fmt.Sprintf("Your new component \"my-%s-app\" is ready in the current directory.", language)) + fmt.Sprintf("Your new component 'my-%s-app' is ready in the current directory", language)) } } @@ -114,7 +124,7 @@ var _ = Describe("odo init interactive command tests", func() { Expect(len(lines)).To(BeNumerically(">", len(msgs))) Expect(lines[0:len(msgs)]).To(Equal(msgs)) Expect(lines).To( - ContainElement(fmt.Sprintf("Your new component \"my-%s-app\" is ready in the current directory.", language))) + ContainElement(fmt.Sprintf("Your new component 'my-%s-app' is ready in the current directory", language))) Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) @@ -141,9 +151,9 @@ var _ = Describe("odo init interactive command tests", func() { It("should display appropriate welcoming messages", func() { language := "java" - welcomingMsgs := []string{ - "The current directory is empty. odo will help you start a new project.", - } + + // The first output is welcoming message / paragraph / banner output + welcomingMsgs := strings.Split(odolog.Stitle(messages.InitializingNewComponent, messages.NoSourceCodeDetected, "odo version: "+version.VERSION), "\n") output, err := testRunner(language, welcomingMsgs, func(ctx helper.InteractiveContext) { helper.ExpectString(ctx, "Select language") @@ -172,10 +182,7 @@ var _ = Describe("odo init interactive command tests", func() { It("should display appropriate welcoming messages", func() { language := "python" - welcomingMsgs := []string{ - "The current directory already contains source code. " + - "odo will try to autodetect the language and project type in order to select the best suited Devfile for your project.", - } + welcomingMsgs := strings.Split(odolog.Stitle(messages.InitializingNewComponent, messages.SourceCodeDetected, "odo version: "+version.VERSION), "\n") output, err := testRunner(language, welcomingMsgs, func(ctx helper.InteractiveContext) { helper.ExpectString(ctx, "Based on the files in the current directory odo detected") @@ -221,7 +228,7 @@ var _ = Describe("odo init interactive command tests", func() { helper.ExpectString(ctx, "Enter component name") helper.SendLine(ctx, "my-dotnet-app") - helper.ExpectString(ctx, "Your new component \"my-dotnet-app\" is ready in the current directory.") + helper.ExpectString(ctx, "Your new component 'my-dotnet-app' is ready in the current directory") }) Expect(err).To(BeNil()) @@ -229,7 +236,7 @@ var _ = Describe("odo init interactive command tests", func() { lines, err := helper.ExtractLines(output) Expect(err).To(BeNil()) Expect(len(lines)).To(BeNumerically(">", 2)) - Expect(lines[len(lines)-1]).To(Equal("Your new component \"my-dotnet-app\" is ready in the current directory.")) + Expect(lines[len(lines)-1]).To(Equal("Your new component 'my-dotnet-app' is ready in the current directory")) componentNameQuestionIdx, ok := helper.FindFirstElementIndexMatchingRegExp(lines, ".*Enter component name:.*") Expect(ok).To(BeTrue()) diff --git a/vendor/github.com/fatih/color/README.md b/vendor/github.com/fatih/color/README.md index d62e4024a..5152bf59b 100644 --- a/vendor/github.com/fatih/color/README.md +++ b/vendor/github.com/fatih/color/README.md @@ -78,7 +78,7 @@ notice("Don't forget this...") ### Custom fprint functions (FprintFunc) ```go -blue := color.New(FgBlue).FprintfFunc() +blue := color.New(color.FgBlue).FprintfFunc() blue(myWriter, "important notice: %s", stars) // Mix up with multiple attributes @@ -127,14 +127,16 @@ fmt.Println("All text will now be bold magenta.") There might be a case where you want to explicitly disable/enable color output. the `go-isatty` package will automatically disable color output for non-tty output streams -(for example if the output were piped directly to `less`) +(for example if the output were piped directly to `less`). -`Color` has support to disable/enable colors both globally and for single color -definitions. For example suppose you have a CLI app and a `--no-color` bool flag. You -can easily disable the color output with: +The `color` package also disables color output if the [`NO_COLOR`](https://no-color.org) environment +variable is set (regardless of its value). + +`Color` has support to disable/enable colors programatically both globally and +for single color definitions. For example suppose you have a CLI app and a +`--no-color` bool flag. You can easily disable the color output with: ```go - var flagNoColor = flag.Bool("no-color", false, "Disable color output") if *flagNoColor { @@ -156,6 +158,10 @@ c.EnableColor() c.Println("This prints again cyan...") ``` +## GitHub Actions + +To output color in GitHub Actions (or other CI systems that support ANSI colors), make sure to set `color.NoColor = false` so that it bypasses the check for non-tty output streams. + ## Todo * Save/Return previous values @@ -170,4 +176,3 @@ c.Println("This prints again cyan...") ## License The MIT License (MIT) - see [`LICENSE.md`](https://github.com/fatih/color/blob/master/LICENSE.md) for more details - diff --git a/vendor/github.com/fatih/color/color.go b/vendor/github.com/fatih/color/color.go index 91c8e9f06..98a60f3c8 100644 --- a/vendor/github.com/fatih/color/color.go +++ b/vendor/github.com/fatih/color/color.go @@ -15,9 +15,11 @@ import ( var ( // NoColor defines if the output is colorized or not. It's dynamically set to // false or true based on the stdout's file descriptor referring to a terminal - // or not. This is a global option and affects all colors. For more control - // over each color block use the methods DisableColor() individually. - NoColor = os.Getenv("TERM") == "dumb" || + // or not. It's also set to true if the NO_COLOR environment variable is + // set (regardless of its value). This is a global option and affects all + // colors. For more control over each color block use the methods + // DisableColor() individually. + NoColor = noColorExists() || os.Getenv("TERM") == "dumb" || (!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd())) // Output defines the standard output of the print functions. By default @@ -33,6 +35,12 @@ var ( colorsCacheMu sync.Mutex // protects colorsCache ) +// noColorExists returns true if the environment variable NO_COLOR exists. +func noColorExists() bool { + _, exists := os.LookupEnv("NO_COLOR") + return exists +} + // Color defines a custom color object which is defined by SGR parameters. type Color struct { params []Attribute @@ -108,7 +116,14 @@ const ( // New returns a newly created color object. func New(value ...Attribute) *Color { - c := &Color{params: make([]Attribute, 0)} + c := &Color{ + params: make([]Attribute, 0), + } + + if noColorExists() { + c.noColor = boolPtr(true) + } + c.Add(value...) return c } @@ -387,7 +402,7 @@ func (c *Color) EnableColor() { } func (c *Color) isNoColorSet() bool { - // check first if we have user setted action + // check first if we have user set action if c.noColor != nil { return *c.noColor } diff --git a/vendor/github.com/fatih/color/doc.go b/vendor/github.com/fatih/color/doc.go index cf1e96500..04541de78 100644 --- a/vendor/github.com/fatih/color/doc.go +++ b/vendor/github.com/fatih/color/doc.go @@ -118,6 +118,8 @@ the color output with: color.NoColor = true // disables colorized output } +You can also disable the color by setting the NO_COLOR environment variable to any value. + It also has support for single color definitions (local). You can disable/enable color output on the fly: diff --git a/vendor/github.com/fatih/color/go.mod b/vendor/github.com/fatih/color/go.mod index 78872815e..c9b3cd59a 100644 --- a/vendor/github.com/fatih/color/go.mod +++ b/vendor/github.com/fatih/color/go.mod @@ -3,6 +3,6 @@ module github.com/fatih/color go 1.13 require ( - github.com/mattn/go-colorable v0.1.8 - github.com/mattn/go-isatty v0.0.12 + github.com/mattn/go-colorable v0.1.9 + github.com/mattn/go-isatty v0.0.14 ) diff --git a/vendor/github.com/fatih/color/go.sum b/vendor/github.com/fatih/color/go.sum index 54f7c46e8..cbbcfb644 100644 --- a/vendor/github.com/fatih/color/go.sum +++ b/vendor/github.com/fatih/color/go.sum @@ -1,7 +1,9 @@ -github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/vendor/github.com/mattn/go-colorable/noncolorable.go b/vendor/github.com/mattn/go-colorable/noncolorable.go index 95f2c6be2..2dcb09aab 100644 --- a/vendor/github.com/mattn/go-colorable/noncolorable.go +++ b/vendor/github.com/mattn/go-colorable/noncolorable.go @@ -27,7 +27,10 @@ loop: } if c1 != 0x1b { bw[0] = c1 - w.out.Write(bw[:]) + _, err = w.out.Write(bw[:]) + if err != nil { + break loop + } continue } c2, err := er.ReadByte() diff --git a/vendor/github.com/mattn/go-isatty/.travis.yml b/vendor/github.com/mattn/go-isatty/.travis.yml deleted file mode 100644 index 604314dd4..000000000 --- a/vendor/github.com/mattn/go-isatty/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: go -sudo: false -go: - - 1.13.x - - tip - -before_install: - - go get -t -v ./... - -script: - - ./go.test.sh - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/mattn/go-isatty/go.mod b/vendor/github.com/mattn/go-isatty/go.mod index 605c4c221..c9a20b7f3 100644 --- a/vendor/github.com/mattn/go-isatty/go.mod +++ b/vendor/github.com/mattn/go-isatty/go.mod @@ -2,4 +2,4 @@ module github.com/mattn/go-isatty go 1.12 -require golang.org/x/sys v0.0.0-20200116001909-b77594299b42 +require golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c diff --git a/vendor/github.com/mattn/go-isatty/isatty_bsd.go b/vendor/github.com/mattn/go-isatty/isatty_bsd.go index 711f28808..39bbcf00f 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_bsd.go +++ b/vendor/github.com/mattn/go-isatty/isatty_bsd.go @@ -1,3 +1,4 @@ +//go:build (darwin || freebsd || openbsd || netbsd || dragonfly) && !appengine // +build darwin freebsd openbsd netbsd dragonfly // +build !appengine diff --git a/vendor/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go index ff714a376..31503226f 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_others.go +++ b/vendor/github.com/mattn/go-isatty/isatty_others.go @@ -1,4 +1,5 @@ -// +build appengine js nacl +//go:build appengine || js || nacl || wasm +// +build appengine js nacl wasm package isatty diff --git a/vendor/github.com/mattn/go-isatty/isatty_plan9.go b/vendor/github.com/mattn/go-isatty/isatty_plan9.go index c5b6e0c08..bae7f9bb3 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_plan9.go +++ b/vendor/github.com/mattn/go-isatty/isatty_plan9.go @@ -1,3 +1,4 @@ +//go:build plan9 // +build plan9 package isatty diff --git a/vendor/github.com/mattn/go-isatty/isatty_solaris.go b/vendor/github.com/mattn/go-isatty/isatty_solaris.go index bdd5c79a0..0c3acf2dc 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_solaris.go +++ b/vendor/github.com/mattn/go-isatty/isatty_solaris.go @@ -1,5 +1,5 @@ -// +build solaris -// +build !appengine +//go:build solaris && !appengine +// +build solaris,!appengine package isatty @@ -8,10 +8,9 @@ import ( ) // IsTerminal returns true if the given file descriptor is a terminal. -// see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c +// see: https://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libc/port/gen/isatty.c func IsTerminal(fd uintptr) bool { - var termio unix.Termio - err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio) + _, err := unix.IoctlGetTermio(int(fd), unix.TCGETA) return err == nil } diff --git a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go index 31a1ca973..67787657f 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go +++ b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go @@ -1,4 +1,5 @@ -// +build linux aix +//go:build (linux || aix || zos) && !appengine +// +build linux aix zos // +build !appengine package isatty diff --git a/vendor/github.com/mattn/go-isatty/isatty_windows.go b/vendor/github.com/mattn/go-isatty/isatty_windows.go index 1fa869154..8e3c99171 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_windows.go +++ b/vendor/github.com/mattn/go-isatty/isatty_windows.go @@ -1,5 +1,5 @@ -// +build windows -// +build !appengine +//go:build windows && !appengine +// +build windows,!appengine package isatty @@ -76,7 +76,7 @@ func isCygwinPipeName(name string) bool { } // getFileNameByHandle use the undocomented ntdll NtQueryObject to get file full name from file handler -// since GetFileInformationByHandleEx is not avilable under windows Vista and still some old fashion +// since GetFileInformationByHandleEx is not available under windows Vista and still some old fashion // guys are using Windows XP, this is a workaround for those guys, it will also work on system from // Windows vista to 10 // see https://stackoverflow.com/a/18792477 for details diff --git a/vendor/github.com/mattn/go-isatty/renovate.json b/vendor/github.com/mattn/go-isatty/renovate.json deleted file mode 100644 index 5ae9d96b7..000000000 --- a/vendor/github.com/mattn/go-isatty/renovate.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": [ - "config:base" - ], - "postUpdateOptions": [ - "gomodTidy" - ] -} diff --git a/vendor/modules.txt b/vendor/modules.txt index fa52483b5..19d3f7c73 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -143,7 +143,7 @@ github.com/emirpasic/gods/utils github.com/evanphx/json-patch # github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d github.com/exponent-io/jsonpath -# github.com/fatih/color v1.10.0 +# github.com/fatih/color v1.13.0 ## explicit github.com/fatih/color # github.com/form3tech-oss/jwt-go v3.2.3+incompatible @@ -341,10 +341,10 @@ github.com/liggitt/tabwriter github.com/mailru/easyjson/buffer github.com/mailru/easyjson/jlexer github.com/mailru/easyjson/jwriter -# github.com/mattn/go-colorable v0.1.8 +# github.com/mattn/go-colorable v0.1.9 ## explicit github.com/mattn/go-colorable -# github.com/mattn/go-isatty v0.0.12 +# github.com/mattn/go-isatty v0.0.14 github.com/mattn/go-isatty # github.com/mattn/go-runewidth v0.0.13 github.com/mattn/go-runewidth