refactor: replace NoColor with ColorMode for improved color output control

Signed-off-by: Mohammadreza Asadollahifard <mazafard@gmail.com>
pull/31034/head
Mohammadreza Asadollahifard 2 months ago
parent 96c54a2963
commit b72db06c49
No known key found for this signature in database
GPG Key ID: 89C260092433E3CC

@ -89,8 +89,8 @@ type EnvSettings struct {
BurstLimit int
// QPS is queries per second which may be used to avoid throttling.
QPS float32
// NoColor disables colorized output
NoColor bool
// ColorMode controls colorized output (never, auto, always)
ColorMode string
}
func New() *EnvSettings {
@ -111,7 +111,7 @@ func New() *EnvSettings {
RepositoryCache: envOr("HELM_REPOSITORY_CACHE", helmpath.CachePath("repository")),
BurstLimit: envIntOr("HELM_BURST_LIMIT", defaultBurstLimit),
QPS: envFloat32Or("HELM_QPS", defaultQPS),
NoColor: envBoolOr("NO_COLOR", false),
ColorMode: envColorMode(),
}
env.Debug, _ = strconv.ParseBool(os.Getenv("HELM_DEBUG"))
@ -163,7 +163,8 @@ func (s *EnvSettings) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.RepositoryCache, "repository-cache", s.RepositoryCache, "path to the directory containing cached repository indexes")
fs.IntVar(&s.BurstLimit, "burst-limit", s.BurstLimit, "client-side default throttling limit")
fs.Float32Var(&s.QPS, "qps", s.QPS, "queries per second used when communicating with the Kubernetes API, not including bursting")
fs.BoolVar(&s.NoColor, "no-color", s.NoColor, "disable colorized output")
fs.StringVar(&s.ColorMode, "color", s.ColorMode, "use colored output (never, auto, always)")
fs.StringVar(&s.ColorMode, "colour", s.ColorMode, "use colored output (never, auto, always)")
}
func envOr(name, def string) string {
@ -217,6 +218,23 @@ func envCSV(name string) (ls []string) {
return
}
func envColorMode() string {
// Check NO_COLOR environment variable first (standard)
if v, ok := os.LookupEnv("NO_COLOR"); ok && v != "" {
return "never"
}
// Check HELM_COLOR environment variable
if v, ok := os.LookupEnv("HELM_COLOR"); ok {
v = strings.ToLower(v)
switch v {
case "never", "auto", "always":
return v
}
}
// Default to auto
return "auto"
}
func (s *EnvSettings) EnvVars() map[string]string {
envvars := map[string]string{
"HELM_BIN": os.Args[0],
@ -269,3 +287,25 @@ func (s *EnvSettings) SetNamespace(namespace string) {
func (s *EnvSettings) RESTClientGetter() genericclioptions.RESTClientGetter {
return s.config
}
// ColorEnabled returns true if color output should be enabled based on the ColorMode setting
func (s *EnvSettings) ColorEnabled() bool {
switch s.ColorMode {
case "never":
return false
case "always":
return true
case "auto":
// Auto mode is handled by fatih/color's built-in terminal detection
// We just need to not override it
return true
default:
return true
}
}
// ShouldDisableColor returns true if color output should be disabled
// This is the inverse of ColorEnabled for backward compatibility with noColor parameters
func (s *EnvSettings) ShouldDisableColor() bool {
return s.ColorMode == "never"
}

@ -63,7 +63,7 @@ func newGetAllCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
debug: true,
showMetadata: true,
hideNotes: false,
noColor: settings.NoColor,
noColor: settings.ShouldDisableColor(),
})
},
}

@ -168,7 +168,7 @@ func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
debug: settings.Debug,
showMetadata: false,
hideNotes: client.HideNotes,
noColor: settings.NoColor,
noColor: settings.ShouldDisableColor(),
})
},
}

@ -106,7 +106,7 @@ func newListCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
}
}
return outfmt.Write(out, newReleaseListWriter(results, client.TimeFormat, client.NoHeaders, settings.NoColor))
return outfmt.Write(out, newReleaseListWriter(results, client.TimeFormat, client.NoHeaders, settings.ShouldDisableColor()))
},
}

@ -78,7 +78,7 @@ func newReleaseTestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command
debug: settings.Debug,
showMetadata: false,
hideNotes: client.HideNotes,
noColor: settings.NoColor,
noColor: settings.ShouldDisableColor(),
}); err != nil {
return err
}

@ -26,6 +26,7 @@ import (
"os"
"strings"
"github.com/fatih/color"
"github.com/spf13/cobra"
"sigs.k8s.io/yaml"
@ -80,6 +81,8 @@ Environment variables:
| $HELM_KUBETLS_SERVER_NAME | set the server name used to validate the Kubernetes API server certificate |
| $HELM_BURST_LIMIT | set the default burst limit in the case the server contains many CRDs (default 100, -1 to disable) |
| $HELM_QPS | set the Queries Per Second in cases where a high number of calls exceed the option for higher burst values |
| $HELM_COLOR | set color output mode. Allowed values: never, always, auto (default: auto) |
| $NO_COLOR | set to any non-empty value to disable all colored output (overrides $HELM_COLOR) |
Helm stores cache, configuration, and data based on the following configuration order:
@ -129,6 +132,20 @@ func SetupLogging(debug bool) {
slog.SetDefault(logger)
}
// configureColorOutput configures the color output based on the ColorMode setting
func configureColorOutput(settings *cli.EnvSettings) {
switch settings.ColorMode {
case "never":
color.NoColor = true
case "always":
color.NoColor = false
case "auto":
// Let fatih/color handle automatic detection
// It will check if output is a terminal and NO_COLOR env var
// We don't need to do anything here
}
}
func newRootCmdWithConfig(actionConfig *action.Configuration, out io.Writer, args []string, logSetup func(bool)) (*cobra.Command, error) {
cmd := &cobra.Command{
Use: "helm",
@ -161,6 +178,27 @@ func newRootCmdWithConfig(actionConfig *action.Configuration, out io.Writer, arg
logSetup(settings.Debug)
// Validate color mode setting
switch settings.ColorMode {
case "never", "auto", "always":
// Valid color mode
default:
return nil, fmt.Errorf("invalid color mode %q: must be one of: never, auto, always", settings.ColorMode)
}
// Configure color output based on ColorMode setting
configureColorOutput(settings)
// Setup shell completion for the color flag
_ = cmd.RegisterFlagCompletionFunc("color", func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
return []string{"never", "auto", "always"}, cobra.ShellCompDirectiveNoFileComp
})
// Setup shell completion for the colour flag
_ = cmd.RegisterFlagCompletionFunc("colour", func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
return []string{"never", "auto", "always"}, cobra.ShellCompDirectiveNoFileComp
})
// Setup shell completion for the namespace flag
err := cmd.RegisterFlagCompletionFunc("namespace", func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
if client, err := actionConfig.KubernetesClientSet(); err == nil {

@ -84,7 +84,7 @@ func newStatusCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
debug: false,
showMetadata: false,
hideNotes: false,
noColor: settings.NoColor,
noColor: settings.ShouldDisableColor(),
})
},
}

@ -166,7 +166,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
debug: settings.Debug,
showMetadata: false,
hideNotes: instClient.HideNotes,
noColor: settings.NoColor,
noColor: settings.ShouldDisableColor(),
})
} else if err != nil {
return err
@ -258,7 +258,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
debug: settings.Debug,
showMetadata: false,
hideNotes: client.HideNotes,
noColor: settings.NoColor,
noColor: settings.ShouldDisableColor(),
})
},
}

Loading…
Cancel
Save