mirror of
https://github.com/mikefarah/yq.git
synced 2026-07-07 22:35:37 +00:00
Compare commits
2 Commits
30451c67d7
...
d1aad0293a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1aad0293a | ||
|
|
6f90af1569 |
@ -438,7 +438,7 @@ You can customize the colors used in YAML output by setting these environment va
|
|||||||
- `YQ_COLOR_STRING` - Color for string values (default: green)
|
- `YQ_COLOR_STRING` - Color for string values (default: green)
|
||||||
- `YQ_COLOR_COMMENT` - Color for comments (default: hi-black)
|
- `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`).
|
Supported color values: `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`, and their `hi-` prefixed variants (e.g., `hi-red`). Numeric color codes are also supported.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@ -11,7 +11,7 @@ var (
|
|||||||
GitDescribe string
|
GitDescribe string
|
||||||
|
|
||||||
// Version is main version number that is being run at the moment.
|
// Version is main version number that is being run at the moment.
|
||||||
Version = "v4.47.2"
|
Version = "v4.47.1"
|
||||||
|
|
||||||
// VersionPrerelease is a pre-release marker for the version. If this is "" (empty string)
|
// VersionPrerelease is a pre-release marker for the version. If this is "" (empty string)
|
||||||
// then it means that it is a final release. Otherwise, this is a pre-release
|
// then it means that it is a final release. Otherwise, this is a pre-release
|
||||||
|
|||||||
4
go.mod
4
go.mod
@ -14,8 +14,8 @@ require (
|
|||||||
github.com/magiconair/properties v1.8.10
|
github.com/magiconair/properties v1.8.10
|
||||||
github.com/pelletier/go-toml/v2 v2.2.4
|
github.com/pelletier/go-toml/v2 v2.2.4
|
||||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e
|
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e
|
||||||
github.com/spf13/cobra v1.10.1
|
github.com/spf13/cobra v1.9.1
|
||||||
github.com/spf13/pflag v1.0.10
|
github.com/spf13/pflag v1.0.7
|
||||||
github.com/yuin/gopher-lua v1.1.1
|
github.com/yuin/gopher-lua v1.1.1
|
||||||
go.yaml.in/yaml/v3 v3.0.4
|
go.yaml.in/yaml/v3 v3.0.4
|
||||||
golang.org/x/net v0.43.0
|
golang.org/x/net v0.43.0
|
||||||
|
|||||||
10
go.sum
10
go.sum
@ -40,11 +40,11 @@ github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsK
|
|||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
|
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||||
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
|
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||||
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
|
||||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
|||||||
@ -2,57 +2,78 @@ package yqlib
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/fatih/color"
|
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ColorConfig struct {
|
type ColorConfig struct {
|
||||||
Bool color.Attribute
|
BoolColor color.Attribute
|
||||||
Number color.Attribute
|
NumberColor color.Attribute
|
||||||
MapKey color.Attribute
|
MapKeyColor color.Attribute
|
||||||
Anchor color.Attribute
|
AnchorColor color.Attribute
|
||||||
Alias color.Attribute
|
AliasColor color.Attribute
|
||||||
String color.Attribute
|
StringColor color.Attribute
|
||||||
Comment color.Attribute
|
CommentColor color.Attribute
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewColorConfig() *ColorConfig {
|
func NewColorConfig() *ColorConfig {
|
||||||
config := &ColorConfig{
|
config := &ColorConfig{
|
||||||
Bool: color.FgHiMagenta,
|
BoolColor: color.FgHiMagenta,
|
||||||
Number: color.FgHiMagenta,
|
NumberColor: color.FgHiMagenta,
|
||||||
MapKey: color.FgCyan,
|
MapKeyColor: color.FgCyan,
|
||||||
Anchor: color.FgHiYellow,
|
AnchorColor: color.FgHiYellow,
|
||||||
Alias: color.FgHiYellow,
|
AliasColor: color.FgHiYellow,
|
||||||
String: color.FgGreen,
|
StringColor: color.FgGreen,
|
||||||
Comment: color.FgHiBlack,
|
CommentColor: color.FgHiBlack,
|
||||||
}
|
}
|
||||||
|
|
||||||
colorMappings := map[string]*color.Attribute{
|
if colorStr := os.Getenv("YQ_COLOR_BOOL"); colorStr != "" {
|
||||||
"YQ_COLOR_BOOL": &config.Bool,
|
if attr, err := parseColorAttribute(colorStr); err == nil {
|
||||||
"YQ_COLOR_NUMBER": &config.Number,
|
config.BoolColor = attr
|
||||||
"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("YQ_COLOR_NUMBER"); colorStr != "" {
|
||||||
if colorStr := os.Getenv(envVar); colorStr != "" {
|
if attr, err := parseColorAttribute(colorStr); err == nil {
|
||||||
if attr, err := parseColorAttribute(colorStr); err == nil {
|
config.NumberColor = attr
|
||||||
*configField = attr
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if colorStr := os.Getenv("YQ_COLOR_MAP_KEY"); colorStr != "" {
|
||||||
|
if attr, err := parseColorAttribute(colorStr); err == nil {
|
||||||
|
config.MapKeyColor = attr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if colorStr := os.Getenv("YQ_COLOR_ANCHOR"); colorStr != "" {
|
||||||
|
if attr, err := parseColorAttribute(colorStr); err == nil {
|
||||||
|
config.AnchorColor = attr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if colorStr := os.Getenv("YQ_COLOR_ALIAS"); colorStr != "" {
|
||||||
|
if attr, err := parseColorAttribute(colorStr); err == nil {
|
||||||
|
config.AliasColor = attr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if colorStr := os.Getenv("YQ_COLOR_STRING"); colorStr != "" {
|
||||||
|
if attr, err := parseColorAttribute(colorStr); err == nil {
|
||||||
|
config.StringColor = attr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if colorStr := os.Getenv("YQ_COLOR_COMMENT"); colorStr != "" {
|
||||||
|
if attr, err := parseColorAttribute(colorStr); err == nil {
|
||||||
|
config.CommentColor = attr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return config
|
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) {
|
func parseColorAttribute(colorStr string) (color.Attribute, error) {
|
||||||
switch colorStr {
|
switch colorStr {
|
||||||
case "black":
|
case "black":
|
||||||
@ -88,6 +109,9 @@ func parseColorAttribute(colorStr string) (color.Attribute, error) {
|
|||||||
case "hi-white":
|
case "hi-white":
|
||||||
return color.FgHiWhite, nil
|
return color.FgHiWhite, nil
|
||||||
default:
|
default:
|
||||||
|
if num, err := strconv.Atoi(colorStr); err == nil {
|
||||||
|
return color.Attribute(num), nil
|
||||||
|
}
|
||||||
return color.Reset, fmt.Errorf("unknown color: %s", colorStr)
|
return color.Reset, fmt.Errorf("unknown color: %s", colorStr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,43 +23,43 @@ func colorizeAndPrint(yamlBytes []byte, writer io.Writer) error {
|
|||||||
var p printer.Printer
|
var p printer.Printer
|
||||||
p.Bool = func() *printer.Property {
|
p.Bool = func() *printer.Property {
|
||||||
return &printer.Property{
|
return &printer.Property{
|
||||||
Prefix: format(config.Bool),
|
Prefix: format(config.BoolColor),
|
||||||
Suffix: format(color.Reset),
|
Suffix: format(color.Reset),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.Number = func() *printer.Property {
|
p.Number = func() *printer.Property {
|
||||||
return &printer.Property{
|
return &printer.Property{
|
||||||
Prefix: format(config.Number),
|
Prefix: format(config.NumberColor),
|
||||||
Suffix: format(color.Reset),
|
Suffix: format(color.Reset),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.MapKey = func() *printer.Property {
|
p.MapKey = func() *printer.Property {
|
||||||
return &printer.Property{
|
return &printer.Property{
|
||||||
Prefix: format(config.MapKey),
|
Prefix: format(config.MapKeyColor),
|
||||||
Suffix: format(color.Reset),
|
Suffix: format(color.Reset),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.Anchor = func() *printer.Property {
|
p.Anchor = func() *printer.Property {
|
||||||
return &printer.Property{
|
return &printer.Property{
|
||||||
Prefix: format(config.Anchor),
|
Prefix: format(config.AnchorColor),
|
||||||
Suffix: format(color.Reset),
|
Suffix: format(color.Reset),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.Alias = func() *printer.Property {
|
p.Alias = func() *printer.Property {
|
||||||
return &printer.Property{
|
return &printer.Property{
|
||||||
Prefix: format(config.Alias),
|
Prefix: format(config.AliasColor),
|
||||||
Suffix: format(color.Reset),
|
Suffix: format(color.Reset),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.String = func() *printer.Property {
|
p.String = func() *printer.Property {
|
||||||
return &printer.Property{
|
return &printer.Property{
|
||||||
Prefix: format(config.String),
|
Prefix: format(config.StringColor),
|
||||||
Suffix: format(color.Reset),
|
Suffix: format(color.Reset),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.Comment = func() *printer.Property {
|
p.Comment = func() *printer.Property {
|
||||||
return &printer.Property{
|
return &printer.Property{
|
||||||
Prefix: format(config.Comment),
|
Prefix: format(config.CommentColor),
|
||||||
Suffix: format(color.Reset),
|
Suffix: format(color.Reset),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -282,13 +282,13 @@ func (dec *tomlDecoder) processTable(currentNode *toml.Node) (bool, error) {
|
|||||||
tableValue = dec.parser.Expression()
|
tableValue = dec.parser.Expression()
|
||||||
// next expression is not table data, so we are done
|
// next expression is not table data, so we are done
|
||||||
if tableValue.Kind != toml.KeyValue {
|
if tableValue.Kind != toml.KeyValue {
|
||||||
log.Debug("got an empty table")
|
log.Debug("got an empty table, returning")
|
||||||
runAgainstCurrentExp = true
|
return true, nil
|
||||||
} else {
|
}
|
||||||
runAgainstCurrentExp, err = dec.decodeKeyValuesIntoMap(tableNodeValue, tableValue)
|
|
||||||
if err != nil && !errors.Is(err, io.EOF) {
|
runAgainstCurrentExp, err = dec.decodeKeyValuesIntoMap(tableNodeValue, tableValue)
|
||||||
return false, err
|
if err != nil && !errors.Is(err, io.EOF) {
|
||||||
}
|
return false, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,6 @@ street = "first street"
|
|||||||
[owner]
|
[owner]
|
||||||
name = "Tom Preston-Werner"
|
name = "Tom Preston-Werner"
|
||||||
`
|
`
|
||||||
|
|
||||||
var expectedTableArrayBeforeOwners = `owner:
|
var expectedTableArrayBeforeOwners = `owner:
|
||||||
addresses:
|
addresses:
|
||||||
- street: first street
|
- street: first street
|
||||||
@ -68,29 +67,6 @@ var emptyTable = `
|
|||||||
|
|
||||||
var emptyTableExpected = "dependencies: {}\n"
|
var emptyTableExpected = "dependencies: {}\n"
|
||||||
|
|
||||||
var multipleEmptyTables = `
|
|
||||||
[firstEmptyTable]
|
|
||||||
[firstTableWithContent]
|
|
||||||
key = "value"
|
|
||||||
[secondEmptyTable]
|
|
||||||
[thirdEmptyTable]
|
|
||||||
[secondTableWithContent]
|
|
||||||
key = "value"
|
|
||||||
[fourthEmptyTable]
|
|
||||||
[fifthEmptyTable]
|
|
||||||
`
|
|
||||||
|
|
||||||
var expectedMultipleEmptyTables = `firstEmptyTable: {}
|
|
||||||
firstTableWithContent:
|
|
||||||
key: value
|
|
||||||
secondEmptyTable: {}
|
|
||||||
thirdEmptyTable: {}
|
|
||||||
secondTableWithContent:
|
|
||||||
key: value
|
|
||||||
fourthEmptyTable: {}
|
|
||||||
fifthEmptyTable: {}
|
|
||||||
`
|
|
||||||
|
|
||||||
var sampleWithHeader = `
|
var sampleWithHeader = `
|
||||||
[servers]
|
[servers]
|
||||||
|
|
||||||
@ -262,13 +238,6 @@ var tomlScenarios = []formatScenario{
|
|||||||
expected: expectedSampleWithHeader,
|
expected: expectedSampleWithHeader,
|
||||||
scenarioType: "decode",
|
scenarioType: "decode",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
description: "Parse: multiple empty tables",
|
|
||||||
skipDoc: true,
|
|
||||||
input: multipleEmptyTables,
|
|
||||||
expected: expectedMultipleEmptyTables,
|
|
||||||
scenarioType: "decode",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testTomlScenario(t *testing.T, s formatScenario) {
|
func testTomlScenario(t *testing.T, s formatScenario) {
|
||||||
|
|||||||
@ -1,7 +1,3 @@
|
|||||||
4.47.2:
|
|
||||||
- Conversion from TOML to JSON no longer omits empty tables #2459 (thanks @louislouislouislouis)
|
|
||||||
- Bumped dependencies
|
|
||||||
|
|
||||||
4.47.1:
|
4.47.1:
|
||||||
- Fixed merge anchor behaviour (`<<`); #2404, #2110, #2386, #2178 Huge thanks to @stevenwdv!
|
- Fixed merge anchor behaviour (`<<`); #2404, #2110, #2386, #2178 Huge thanks to @stevenwdv!
|
||||||
Note that you will need to set --yaml-fix-merge-anchor-to-spec to see the fixes
|
Note that you will need to set --yaml-fix-merge-anchor-to-spec to see the fixes
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
name: yq
|
name: yq
|
||||||
version: 'v4.47.2'
|
version: 'v4.47.1'
|
||||||
summary: A lightweight and portable command-line data file processor
|
summary: A lightweight and portable command-line data file processor
|
||||||
description: |
|
description: |
|
||||||
`yq` uses [jq](https://github.com/stedolan/jq) like syntax but works with yaml, json, xml, csv, properties and TOML files.
|
`yq` uses [jq](https://github.com/stedolan/jq) like syntax but works with yaml, json, xml, csv, properties and TOML files.
|
||||||
@ -27,6 +27,6 @@ parts:
|
|||||||
build-environment:
|
build-environment:
|
||||||
- CGO_ENABLED: 0
|
- CGO_ENABLED: 0
|
||||||
source: https://github.com/mikefarah/yq.git
|
source: https://github.com/mikefarah/yq.git
|
||||||
source-tag: v4.47.2
|
source-tag: v4.47.1
|
||||||
build-snaps:
|
build-snaps:
|
||||||
- go/latest/stable
|
- go/latest/stable
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user