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  }