From 82f3e1497e265649a6f657f03dd33af32684103c Mon Sep 17 00:00:00 2001 From: "mark.barzali" Date: Mon, 1 Sep 2025 10:51:01 +0200 Subject: [PATCH] feat: configure colors of output with env variables Signed-off-by: mark.barzali --- README.md | 24 ++++++++++ pkg/yqlib/color_config.go | 93 +++++++++++++++++++++++++++++++++++++++ pkg/yqlib/color_print.go | 15 ++++--- 3 files changed, 125 insertions(+), 7 deletions(-) create mode 100644 pkg/yqlib/color_config.go diff --git a/README.md b/README.md index 21604ddb..d725ce42 100644 --- a/README.md +++ b/README.md @@ -423,6 +423,30 @@ Flags: Use "yq [command] --help" for more information about a command. ``` + +## Environment Variables + +### Color Customization + +You can customize the colors used in YAML output by setting these environment variables: + +- `YQ_COLOR_BOOL` - Color for boolean values (default: hi-magenta) +- `YQ_COLOR_NUMBER` - Color for numeric values (default: hi-magenta) +- `YQ_COLOR_MAP_KEY` - Color for map keys (default: cyan) +- `YQ_COLOR_ANCHOR` - Color for YAML anchors (default: hi-yellow) +- `YQ_COLOR_ALIAS` - Color for YAML aliases (default: hi-yellow) +- `YQ_COLOR_STRING` - Color for string values (default: green) +- `YQ_COLOR_COMMENT` - Color for comments (default: hi-black) + +Supported color values: `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`, and their `hi-` prefixed variants (e.g., `hi-red`). + +Example: +```bash +export YQ_COLOR_STRING=red +export YQ_COLOR_MAP_KEY=hi-blue +yq -C '.data' file.yaml +``` + ## Known Issues / Missing Features - `yq` attempts to preserve comment positions and whitespace as much as possible, but it does not handle all scenarios (see https://github.com/go-yaml/yaml/tree/v3 for details) - Powershell has its own...[opinions on quoting yq](https://mikefarah.gitbook.io/yq/usage/tips-and-tricks#quotes-in-windows-powershell) diff --git a/pkg/yqlib/color_config.go b/pkg/yqlib/color_config.go new file mode 100644 index 00000000..d0e99646 --- /dev/null +++ b/pkg/yqlib/color_config.go @@ -0,0 +1,93 @@ +package yqlib + +import ( + "fmt" + "github.com/fatih/color" + "os" +) + +type ColorConfig struct { + Bool color.Attribute + Number color.Attribute + MapKey color.Attribute + Anchor color.Attribute + Alias color.Attribute + String color.Attribute + Comment color.Attribute +} + +func NewColorConfig() *ColorConfig { + config := &ColorConfig{ + Bool: color.FgHiMagenta, + Number: color.FgHiMagenta, + MapKey: color.FgCyan, + Anchor: color.FgHiYellow, + Alias: color.FgHiYellow, + String: color.FgGreen, + Comment: color.FgHiBlack, + } + + colorMappings := map[string]*color.Attribute{ + "YQ_COLOR_BOOL": &config.Bool, + "YQ_COLOR_NUMBER": &config.Number, + "YQ_COLOR_MAP_KEY": &config.MapKey, + "YQ_COLOR_ANCHOR": &config.Anchor, + "YQ_COLOR_ALIAS": &config.Alias, + "YQ_COLOR_STRING": &config.String, + "YQ_COLOR_COMMENT": &config.Comment, + } + + for envVar, configField := range colorMappings { + if colorStr := os.Getenv(envVar); colorStr != "" { + if attr, err := parseColorAttribute(colorStr); err == nil { + *configField = attr + } + } + } + + return config +} + +// parseColorAttribute converts a color string to a color.Attribute. +// +// Supports three types of color specifications: +// 1. Standard color names: "red", "green", "blue", "yellow", "magenta", "cyan", "white", "black" +// 2. High-intensity variants: "hi-red", "hi-green", "hi-blue", etc. +func parseColorAttribute(colorStr string) (color.Attribute, error) { + switch colorStr { + case "black": + return color.FgBlack, nil + case "red": + return color.FgRed, nil + case "green": + return color.FgGreen, nil + case "yellow": + return color.FgYellow, nil + case "blue": + return color.FgBlue, nil + case "magenta": + return color.FgMagenta, nil + case "cyan": + return color.FgCyan, nil + case "white": + return color.FgWhite, nil + case "hi-black": + return color.FgHiBlack, nil + case "hi-red": + return color.FgHiRed, nil + case "hi-green": + return color.FgHiGreen, nil + case "hi-yellow": + return color.FgHiYellow, nil + case "hi-blue": + return color.FgHiBlue, nil + case "hi-magenta": + return color.FgHiMagenta, nil + case "hi-cyan": + return color.FgHiCyan, nil + case "hi-white": + return color.FgHiWhite, nil + default: + return color.Reset, fmt.Errorf("unknown color: %s", colorStr) + } +} diff --git a/pkg/yqlib/color_print.go b/pkg/yqlib/color_print.go index 51c0a45d..8881337c 100644 --- a/pkg/yqlib/color_print.go +++ b/pkg/yqlib/color_print.go @@ -19,46 +19,47 @@ func format(attr color.Attribute) string { func colorizeAndPrint(yamlBytes []byte, writer io.Writer) error { tokens := lexer.Tokenize(string(yamlBytes)) + config := NewColorConfig() var p printer.Printer p.Bool = func() *printer.Property { return &printer.Property{ - Prefix: format(color.FgHiMagenta), + Prefix: format(config.Bool), Suffix: format(color.Reset), } } p.Number = func() *printer.Property { return &printer.Property{ - Prefix: format(color.FgHiMagenta), + Prefix: format(config.Number), Suffix: format(color.Reset), } } p.MapKey = func() *printer.Property { return &printer.Property{ - Prefix: format(color.FgCyan), + Prefix: format(config.MapKey), Suffix: format(color.Reset), } } p.Anchor = func() *printer.Property { return &printer.Property{ - Prefix: format(color.FgHiYellow), + Prefix: format(config.Anchor), Suffix: format(color.Reset), } } p.Alias = func() *printer.Property { return &printer.Property{ - Prefix: format(color.FgHiYellow), + Prefix: format(config.Alias), Suffix: format(color.Reset), } } p.String = func() *printer.Property { return &printer.Property{ - Prefix: format(color.FgGreen), + Prefix: format(config.String), Suffix: format(color.Reset), } } p.Comment = func() *printer.Property { return &printer.Property{ - Prefix: format(color.FgHiBlack), + Prefix: format(config.Comment), Suffix: format(color.Reset), } }