github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/cmd/state/output.go (about) 1 package main 2 3 import ( 4 "errors" 5 "os" 6 7 "github.com/ActiveState/cli/internal/errs" 8 "github.com/ActiveState/cli/internal/logging" 9 "github.com/ActiveState/cli/internal/multilog" 10 "github.com/ActiveState/cli/internal/output" 11 "github.com/ActiveState/cli/internal/rollbar" 12 "github.com/ActiveState/cli/internal/terminal" 13 "github.com/jessevdk/go-flags" 14 "golang.org/x/term" 15 survey "gopkg.in/AlecAivazis/survey.v1/core" 16 ) 17 18 type outputFlags struct { 19 // These should be kept in sync with cmd/state/internal/cmdtree (output flag) 20 Output string `short:"o" long:"output"` 21 Mono bool `long:"mono"` 22 NonInteractive bool `short:"n" long:"non-interactive"` 23 } 24 25 // DisableColor returns whether color output should be disabled 26 // By default it only returns false if stdout is a terminal. This check can be disabled with 27 // the checkTerminal flag 28 func (of outputFlags) DisableColor(checkTerminalFlag ...bool) bool { 29 checkTerminal := true 30 if len(checkTerminalFlag) > 0 { 31 checkTerminal = checkTerminalFlag[0] 32 } 33 _, noColorEnv := os.LookupEnv("NO_COLOR") 34 return of.Mono || noColorEnv || (checkTerminal && !terminal.StdoutSupportsColors()) 35 } 36 37 func parseOutputFlags(args []string) outputFlags { 38 var flagSet outputFlags 39 parser := flags.NewParser(&flagSet, flags.IgnoreUnknown) 40 _, err := parser.ParseArgs(args) 41 if err != nil { 42 logging.Warning("Could not parse output flag: %s", err.Error()) 43 } 44 45 return flagSet 46 } 47 48 func initOutput(flags outputFlags, formatName string, shellName string) (output.Outputer, error) { 49 if formatName == "" { 50 formatName = flags.Output 51 } 52 53 out, err := output.New(formatName, &output.Config{ 54 OutWriter: os.Stdout, 55 ErrWriter: os.Stderr, 56 Colored: !flags.DisableColor(), 57 Interactive: !flags.NonInteractive && term.IsTerminal(int(os.Stdin.Fd())), 58 ShellName: shellName, 59 }) 60 if err != nil { 61 if errors.Is(err, output.ErrNotRecognized) { 62 // The formatter might still be registered, so default to plain for now 63 logging.Warning("Output format not recognized: %s, defaulting to plain output instead", formatName) 64 return initOutput(flags, string(output.PlainFormatName), shellName) 65 } 66 multilog.Log(logging.ErrorNoStacktrace, rollbar.Error)("Could not create outputer, name: %s, error: %s", formatName, err.Error()) 67 return nil, errs.Wrap(err, "output.New %s failed", formatName) 68 } 69 return out, nil 70 } 71 72 // setPrinterColors disables colored output in the printer packages in case the 73 // terminal does not support it, or if requested by the output arguments 74 func setPrinterColors(flags outputFlags) { 75 disableColor := flags.DisableColor() 76 survey.DisableColor = disableColor 77 }