mirror of
https://github.com/taigrr/yq
synced 2025-01-18 04:53:17 -08:00
Compare commits
20 Commits
risentvebe
...
3.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4dc70cc84 | ||
|
|
8ade1275e2 | ||
|
|
e1e05d85e3 | ||
|
|
b99467432e | ||
|
|
6b07143af7 | ||
|
|
ed234e37ce | ||
|
|
c0e4917d52 | ||
|
|
2713893f87 | ||
|
|
6bb221e973 | ||
|
|
7eb01a81da | ||
|
|
5c117204fa | ||
|
|
a4fa8f1341 | ||
|
|
69caccd2d3 | ||
|
|
67fb924e0e | ||
|
|
b64187fe32 | ||
|
|
8e6ceba2ac | ||
|
|
6ef04e1e77 | ||
|
|
10029420a5 | ||
|
|
f91093d5fe | ||
|
|
090432d241 |
@@ -79,8 +79,10 @@ yq() {
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
- Written in portable go, so you can download a lovely dependency free binary
|
- Written in portable go, so you can download a lovely dependency free binary
|
||||||
|
- [Colorize the output](https://mikefarah.gitbook.io/yq/usage/output-format#colorize-output)
|
||||||
- [Deep read a yaml file with a given path expression](https://mikefarah.gitbook.io/yq/commands/read#basic)
|
- [Deep read a yaml file with a given path expression](https://mikefarah.gitbook.io/yq/commands/read#basic)
|
||||||
- [List matching paths of a given path expression](https://mikefarah.gitbook.io/yq/commands/read#path-only)
|
- [List matching paths of a given path expression](https://mikefarah.gitbook.io/yq/commands/read#path-only)
|
||||||
|
- [Return the lengths of arrays/object/scalars](https://mikefarah.gitbook.io/yq/commands/read#printing-length-of-the-results)
|
||||||
- Update a yaml file given a [path expression](https://mikefarah.gitbook.io/yq/commands/write-update#basic) or [script file](https://mikefarah.gitbook.io/yq/commands/write-update#basic)
|
- Update a yaml file given a [path expression](https://mikefarah.gitbook.io/yq/commands/write-update#basic) or [script file](https://mikefarah.gitbook.io/yq/commands/write-update#basic)
|
||||||
- Update creates any missing entries in the path on the fly
|
- Update creates any missing entries in the path on the fly
|
||||||
- Deeply [compare](https://mikefarah.gitbook.io/yq/commands/compare) yaml files
|
- Deeply [compare](https://mikefarah.gitbook.io/yq/commands/compare) yaml files
|
||||||
@@ -114,6 +116,7 @@ Available Commands:
|
|||||||
write yq w [--inplace/-i] [--script/-s script_file] [--doc/-d index] sample.yaml 'b.e(name==fr*).value' newValue
|
write yq w [--inplace/-i] [--script/-s script_file] [--doc/-d index] sample.yaml 'b.e(name==fr*).value' newValue
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
|
-C, --colors print using colors
|
||||||
-h, --help help for yq
|
-h, --help help for yq
|
||||||
-I, --indent int sets indent level for output (default 2)
|
-I, --indent int sets indent level for output (default 2)
|
||||||
-P, --prettyPrint pretty print
|
-P, --prettyPrint pretty print
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
name: 'YAML processor'
|
name: 'yq - portable yaml processor'
|
||||||
description: 'YAML processor for running in Github action'
|
description: 'create, read, update, delete, merge, validate and do more with yaml'
|
||||||
|
icon: command
|
||||||
|
color: gray-dark
|
||||||
inputs:
|
inputs:
|
||||||
cmd:
|
cmd:
|
||||||
description: 'The Command which should be run'
|
description: 'The Command which should be run'
|
||||||
|
|||||||
@@ -94,12 +94,21 @@ func TestReadCmd(t *testing.T) {
|
|||||||
test.AssertResult(t, "2\n", result.Output)
|
test.AssertResult(t, "2\n", result.Output)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompareCmd(t *testing.T) {
|
func TestCompareSameCmd(t *testing.T) {
|
||||||
cmd := getRootCommand()
|
cmd := getRootCommand()
|
||||||
result := test.RunCmd(cmd, "compare ../examples/data1.yaml ../examples/data3.yaml")
|
result := test.RunCmd(cmd, "compare ../examples/data1.yaml ../examples/data1.yaml")
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
t.Error(result.Error)
|
t.Error(result.Error)
|
||||||
}
|
}
|
||||||
|
expectedOutput := ``
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareDifferentCmd(t *testing.T) {
|
||||||
|
forceOsExit = false
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "compare ../examples/data1.yaml ../examples/data3.yaml")
|
||||||
|
|
||||||
expectedOutput := `-a: simple # just the best
|
expectedOutput := `-a: simple # just the best
|
||||||
-b: [1, 2]
|
-b: [1, 2]
|
||||||
+a: "simple" # just the best
|
+a: "simple" # just the best
|
||||||
@@ -111,6 +120,7 @@ func TestCompareCmd(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestComparePrettyCmd(t *testing.T) {
|
func TestComparePrettyCmd(t *testing.T) {
|
||||||
|
forceOsExit = false
|
||||||
cmd := getRootCommand()
|
cmd := getRootCommand()
|
||||||
result := test.RunCmd(cmd, "compare -P ../examples/data1.yaml ../examples/data3.yaml")
|
result := test.RunCmd(cmd, "compare -P ../examples/data1.yaml ../examples/data3.yaml")
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
@@ -128,6 +138,7 @@ func TestComparePrettyCmd(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestComparePathsCmd(t *testing.T) {
|
func TestComparePathsCmd(t *testing.T) {
|
||||||
|
forceOsExit = false
|
||||||
cmd := getRootCommand()
|
cmd := getRootCommand()
|
||||||
result := test.RunCmd(cmd, "compare -P -ppv ../examples/data1.yaml ../examples/data3.yaml **")
|
result := test.RunCmd(cmd, "compare -P -ppv ../examples/data1.yaml ../examples/data3.yaml **")
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
@@ -190,6 +201,293 @@ func TestReadArrayCmd(t *testing.T) {
|
|||||||
test.AssertResult(t, "b.e.[1].name: sam\n", result.Output)
|
test.AssertResult(t, "b.e.[1].name: sam\n", result.Output)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReadArrayLengthCmd(t *testing.T) {
|
||||||
|
content := `- things
|
||||||
|
- whatever
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read -l %s", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
test.AssertResult(t, "2\n", result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadArrayLengthDeepCmd(t *testing.T) {
|
||||||
|
content := `holder:
|
||||||
|
- things
|
||||||
|
- whatever
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read -l %s holder", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
test.AssertResult(t, "2\n", result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadArrayLengthDeepMultipleCmd(t *testing.T) {
|
||||||
|
content := `holderA:
|
||||||
|
- things
|
||||||
|
- whatever
|
||||||
|
skipMe:
|
||||||
|
- yep
|
||||||
|
holderB:
|
||||||
|
- other things
|
||||||
|
- cool
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read -l -c %s holder*", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
test.AssertResult(t, "2\n", result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadCollectCmd(t *testing.T) {
|
||||||
|
content := `holderA: yep
|
||||||
|
skipMe: not me
|
||||||
|
holderB: me too
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read -c %s holder*", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `- yep
|
||||||
|
- me too
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadCollectArrayCmd(t *testing.T) {
|
||||||
|
content := `- name: fred
|
||||||
|
value: 32
|
||||||
|
- name: sam
|
||||||
|
value: 67
|
||||||
|
- name: fernie
|
||||||
|
value: 103
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read -c %s (name==f*)", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `- name: fred
|
||||||
|
value: 32
|
||||||
|
- name: fernie
|
||||||
|
value: 103
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadArrayLengthDeepMultipleWithPathCmd(t *testing.T) {
|
||||||
|
content := `holderA:
|
||||||
|
- things
|
||||||
|
- whatever
|
||||||
|
holderB:
|
||||||
|
- other things
|
||||||
|
- cool
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read -l %s -ppv holder*", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
test.AssertResult(t, "holderA: 2\nholderB: 2\n", result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadObjectLengthCmd(t *testing.T) {
|
||||||
|
content := `cat: meow
|
||||||
|
dog: bark
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read -l %s", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
test.AssertResult(t, "2\n", result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadObjectLengthDeepCmd(t *testing.T) {
|
||||||
|
content := `holder:
|
||||||
|
cat: meow
|
||||||
|
dog: bark
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read -l %s holder", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
test.AssertResult(t, "2\n", result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadObjectLengthDeepMultipleCmd(t *testing.T) {
|
||||||
|
content := `holderA:
|
||||||
|
cat: meow
|
||||||
|
dog: bark
|
||||||
|
holderB:
|
||||||
|
elephant: meow
|
||||||
|
zebra: bark
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read -l -c %s holder*", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
test.AssertResult(t, "2\n", result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadObjectLengthDeepMultipleWithPathsCmd(t *testing.T) {
|
||||||
|
content := `holderA:
|
||||||
|
cat: meow
|
||||||
|
dog: bark
|
||||||
|
holderB:
|
||||||
|
elephant: meow
|
||||||
|
zebra: bark
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read -l -ppv %s holder*", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
test.AssertResult(t, "holderA: 2\nholderB: 2\n", result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadScalarLengthCmd(t *testing.T) {
|
||||||
|
content := `meow`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read -l %s", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
test.AssertResult(t, "4\n", result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadDoubleQuotedStringCmd(t *testing.T) {
|
||||||
|
content := `name: "meow face"`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read %s name", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
test.AssertResult(t, "meow face\n", result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadSingleQuotedStringCmd(t *testing.T) {
|
||||||
|
content := `name: 'meow face'`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read %s name", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
test.AssertResult(t, "meow face\n", result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadQuotedMultinlineStringCmd(t *testing.T) {
|
||||||
|
content := `test: |
|
||||||
|
abcdefg
|
||||||
|
hijklmno
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read %s test", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `abcdefg
|
||||||
|
hijklmno
|
||||||
|
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadQuotedMultinlineNoNewLineStringCmd(t *testing.T) {
|
||||||
|
content := `test: |-
|
||||||
|
abcdefg
|
||||||
|
hijklmno
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read %s test", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `abcdefg
|
||||||
|
hijklmno
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadBooleanCmd(t *testing.T) {
|
||||||
|
content := `name: true`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read %s name", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
test.AssertResult(t, "true\n", result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadNumberCmd(t *testing.T) {
|
||||||
|
content := `name: 32.13`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read %s name", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
test.AssertResult(t, "32.13\n", result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
func TestReadDeepSplatCmd(t *testing.T) {
|
func TestReadDeepSplatCmd(t *testing.T) {
|
||||||
cmd := getRootCommand()
|
cmd := getRootCommand()
|
||||||
result := test.RunCmd(cmd, "read -p pv ../examples/sample.yaml b.**")
|
result := test.RunCmd(cmd, "read -p pv ../examples/sample.yaml b.**")
|
||||||
@@ -1809,6 +2107,75 @@ func TestDeleteYamlArrayCmd(t *testing.T) {
|
|||||||
test.AssertResult(t, expectedOutput, result.Output)
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReadExpression(t *testing.T) {
|
||||||
|
content := `name: value`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("r %s (x==f)", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := ``
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadFindValueArrayCmd(t *testing.T) {
|
||||||
|
content := `- cat
|
||||||
|
- dog
|
||||||
|
- rat
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("r %s (.==dog)", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := `dog
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadFindValueDeepArrayCmd(t *testing.T) {
|
||||||
|
content := `animals:
|
||||||
|
- cat
|
||||||
|
- dog
|
||||||
|
- rat
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("r %s animals(.==dog)", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := `dog
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadFindValueDeepObjectCmd(t *testing.T) {
|
||||||
|
content := `animals:
|
||||||
|
great: yes
|
||||||
|
small: sometimes
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("r %s animals(.==yes) -ppv", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := `animals.great: yes
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
func TestDeleteYamlArrayExpressionCmd(t *testing.T) {
|
func TestDeleteYamlArrayExpressionCmd(t *testing.T) {
|
||||||
content := `- name: fred
|
content := `- name: fred
|
||||||
- name: cat
|
- name: cat
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/kylelemons/godebug/diff"
|
"github.com/kylelemons/godebug/diff"
|
||||||
@@ -11,6 +12,9 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// turn off for unit tests :(
|
||||||
|
var forceOsExit = true
|
||||||
|
|
||||||
func createCompareCmd() *cobra.Command {
|
func createCompareCmd() *cobra.Command {
|
||||||
var cmdCompare = &cobra.Command{
|
var cmdCompare = &cobra.Command{
|
||||||
Use: "compare [yaml_file_a] [yaml_file_b]",
|
Use: "compare [yaml_file_a] [yaml_file_b]",
|
||||||
@@ -70,7 +74,14 @@ func compareDocuments(cmd *cobra.Command, args []string) error {
|
|||||||
return errorDoingThings
|
return errorDoingThings
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Print(diff.Diff(strings.TrimSuffix(dataBufferA.String(), "\n"), strings.TrimSuffix(dataBufferB.String(), "\n")))
|
diffString := diff.Diff(strings.TrimSuffix(dataBufferA.String(), "\n"), strings.TrimSuffix(dataBufferB.String(), "\n"))
|
||||||
cmd.Print("\n")
|
|
||||||
|
if len(diffString) > 1 {
|
||||||
|
cmd.Print(diffString)
|
||||||
|
cmd.Print("\n")
|
||||||
|
if forceOsExit {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,15 @@ import (
|
|||||||
|
|
||||||
var customTag = ""
|
var customTag = ""
|
||||||
var printMode = "v"
|
var printMode = "v"
|
||||||
|
var printLength = false
|
||||||
|
var collectIntoArray = false
|
||||||
var writeInplace = false
|
var writeInplace = false
|
||||||
var writeScript = ""
|
var writeScript = ""
|
||||||
var sourceYamlFile = ""
|
var sourceYamlFile = ""
|
||||||
var outputToJSON = false
|
var outputToJSON = false
|
||||||
var prettyPrint = false
|
var prettyPrint = false
|
||||||
var explodeAnchors = false
|
var explodeAnchors = false
|
||||||
|
var colorsEnabled = false
|
||||||
var defaultValue = ""
|
var defaultValue = ""
|
||||||
var indent = 2
|
var indent = 2
|
||||||
var overwriteFlag = false
|
var overwriteFlag = false
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/mikefarah/yq/v3/pkg/yqlib"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
yaml "gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func createNewCmd() *cobra.Command {
|
func createNewCmd() *cobra.Command {
|
||||||
@@ -46,9 +46,6 @@ func newProperty(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var encoder = yaml.NewEncoder(cmd.OutOrStdout())
|
var encoder = yqlib.NewYamlEncoder(cmd.OutOrStdout(), indent, colorsEnabled)
|
||||||
encoder.SetIndent(2)
|
return encoder.Encode(&newNode)
|
||||||
errorEncoding := encoder.Encode(&newNode)
|
|
||||||
encoder.Close()
|
|
||||||
return errorEncoding
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ yq r -- things.yaml '--key-starting-with-dashes.blah'
|
|||||||
cmdRead.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
cmdRead.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||||
cmdRead.PersistentFlags().StringVarP(&printMode, "printMode", "p", "v", "print mode (v (values, default), p (paths), pv (path and value pairs)")
|
cmdRead.PersistentFlags().StringVarP(&printMode, "printMode", "p", "v", "print mode (v (values, default), p (paths), pv (path and value pairs)")
|
||||||
cmdRead.PersistentFlags().StringVarP(&defaultValue, "defaultValue", "D", "", "default value printed when there are no results")
|
cmdRead.PersistentFlags().StringVarP(&defaultValue, "defaultValue", "D", "", "default value printed when there are no results")
|
||||||
|
cmdRead.PersistentFlags().BoolVarP(&printLength, "length", "l", false, "print length of results")
|
||||||
|
cmdRead.PersistentFlags().BoolVarP(&collectIntoArray, "collect", "c", false, "collect results into array")
|
||||||
cmdRead.PersistentFlags().BoolVarP(&explodeAnchors, "explodeAnchors", "X", false, "explode anchors")
|
cmdRead.PersistentFlags().BoolVarP(&explodeAnchors, "explodeAnchors", "X", false, "explode anchors")
|
||||||
return cmdRead
|
return cmdRead
|
||||||
}
|
}
|
||||||
@@ -49,6 +51,7 @@ func readProperty(cmd *cobra.Command, args []string) error {
|
|||||||
if errorReadingStream != nil {
|
if errorReadingStream != nil {
|
||||||
return errorReadingStream
|
return errorReadingStream
|
||||||
}
|
}
|
||||||
|
out := cmd.OutOrStdout()
|
||||||
|
|
||||||
return printResults(matchingNodes, cmd.OutOrStdout())
|
return printResults(matchingNodes, out)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ func New() *cobra.Command {
|
|||||||
rootCmd.PersistentFlags().BoolVarP(&prettyPrint, "prettyPrint", "P", false, "pretty print")
|
rootCmd.PersistentFlags().BoolVarP(&prettyPrint, "prettyPrint", "P", false, "pretty print")
|
||||||
rootCmd.PersistentFlags().IntVarP(&indent, "indent", "I", 2, "sets indent level for output")
|
rootCmd.PersistentFlags().IntVarP(&indent, "indent", "I", 2, "sets indent level for output")
|
||||||
rootCmd.Flags().BoolVarP(&version, "version", "V", false, "Print version information and quit")
|
rootCmd.Flags().BoolVarP(&version, "version", "V", false, "Print version information and quit")
|
||||||
|
rootCmd.PersistentFlags().BoolVarP(&colorsEnabled, "colors", "C", false, "print with colors")
|
||||||
|
|
||||||
rootCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
createReadCmd(),
|
createReadCmd(),
|
||||||
|
|||||||
53
cmd/utils.go
53
cmd/utils.go
@@ -77,20 +77,39 @@ func appendDocument(originalMatchingNodes []*yqlib.NodeContext, dataBucket yaml.
|
|||||||
return append(originalMatchingNodes, matchingNodes...), nil
|
return append(originalMatchingNodes, matchingNodes...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func printValue(node *yaml.Node, writer io.Writer) error {
|
func lengthOf(node *yaml.Node) int {
|
||||||
if node.Kind == yaml.ScalarNode {
|
kindToCheck := node.Kind
|
||||||
_, errorWriting := writer.Write([]byte(node.Value + "\n"))
|
if node.Kind == yaml.DocumentNode && len(node.Content) == 1 {
|
||||||
return errorWriting
|
log.Debugf("length of document node, calculating length of child")
|
||||||
|
kindToCheck = node.Content[0].Kind
|
||||||
}
|
}
|
||||||
return printNode(node, writer)
|
switch kindToCheck {
|
||||||
|
case yaml.ScalarNode:
|
||||||
|
return len(node.Value)
|
||||||
|
case yaml.MappingNode:
|
||||||
|
return len(node.Content) / 2
|
||||||
|
default:
|
||||||
|
return len(node.Content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// transforms node before printing, if required
|
||||||
|
func transformNode(node *yaml.Node) *yaml.Node {
|
||||||
|
if printLength {
|
||||||
|
return &yaml.Node{Kind: yaml.ScalarNode, Value: fmt.Sprintf("%v", lengthOf(node))}
|
||||||
|
}
|
||||||
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
func printNode(node *yaml.Node, writer io.Writer) error {
|
func printNode(node *yaml.Node, writer io.Writer) error {
|
||||||
var encoder yqlib.Encoder
|
var encoder yqlib.Encoder
|
||||||
|
if node.Kind == yaml.ScalarNode {
|
||||||
|
return writeString(writer, node.Value+"\n")
|
||||||
|
}
|
||||||
if outputToJSON {
|
if outputToJSON {
|
||||||
encoder = yqlib.NewJsonEncoder(writer, prettyPrint, indent)
|
encoder = yqlib.NewJsonEncoder(writer, prettyPrint, indent)
|
||||||
} else {
|
} else {
|
||||||
encoder = yqlib.NewYamlEncoder(writer, indent)
|
encoder = yqlib.NewYamlEncoder(writer, indent, colorsEnabled)
|
||||||
}
|
}
|
||||||
return encoder.Encode(node)
|
return encoder.Encode(node)
|
||||||
}
|
}
|
||||||
@@ -160,6 +179,9 @@ func printResults(matchingNodes []*yqlib.NodeContext, writer io.Writer) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var errorWriting error
|
var errorWriting error
|
||||||
|
|
||||||
|
var arrayCollection = yaml.Node{Kind: yaml.SequenceNode}
|
||||||
|
|
||||||
for _, mappedDoc := range matchingNodes {
|
for _, mappedDoc := range matchingNodes {
|
||||||
switch printMode {
|
switch printMode {
|
||||||
case "p":
|
case "p":
|
||||||
@@ -172,17 +194,27 @@ func printResults(matchingNodes []*yqlib.NodeContext, writer io.Writer) error {
|
|||||||
var parentNode = yaml.Node{Kind: yaml.MappingNode}
|
var parentNode = yaml.Node{Kind: yaml.MappingNode}
|
||||||
parentNode.Content = make([]*yaml.Node, 2)
|
parentNode.Content = make([]*yaml.Node, 2)
|
||||||
parentNode.Content[0] = &yaml.Node{Kind: yaml.ScalarNode, Value: lib.PathStackToString(mappedDoc.PathStack)}
|
parentNode.Content[0] = &yaml.Node{Kind: yaml.ScalarNode, Value: lib.PathStackToString(mappedDoc.PathStack)}
|
||||||
parentNode.Content[1] = mappedDoc.Node
|
parentNode.Content[1] = transformNode(mappedDoc.Node)
|
||||||
if err := printValue(&parentNode, bufferedWriter); err != nil {
|
if collectIntoArray {
|
||||||
|
arrayCollection.Content = append(arrayCollection.Content, &parentNode)
|
||||||
|
} else if err := printNode(&parentNode, bufferedWriter); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if err := printValue(mappedDoc.Node, bufferedWriter); err != nil {
|
if collectIntoArray {
|
||||||
|
arrayCollection.Content = append(arrayCollection.Content, mappedDoc.Node)
|
||||||
|
} else if err := printNode(transformNode(mappedDoc.Node), bufferedWriter); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if collectIntoArray {
|
||||||
|
if err := printNode(transformNode(&arrayCollection), bufferedWriter); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,8 +364,9 @@ func readAndUpdate(stdOut io.Writer, inputFile string, updateData updateDataFn)
|
|||||||
if outputToJSON {
|
if outputToJSON {
|
||||||
encoder = yqlib.NewJsonEncoder(bufferedWriter, prettyPrint, indent)
|
encoder = yqlib.NewJsonEncoder(bufferedWriter, prettyPrint, indent)
|
||||||
} else {
|
} else {
|
||||||
encoder = yqlib.NewYamlEncoder(bufferedWriter, indent)
|
encoder = yqlib.NewYamlEncoder(bufferedWriter, indent, colorsEnabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
return readStream(inputFile, mapYamlDecoder(updateData, encoder))
|
return readStream(inputFile, mapYamlDecoder(updateData, encoder))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 = "3.1.2"
|
Version = "3.2.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
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -1,6 +1,8 @@
|
|||||||
module github.com/mikefarah/yq/v3
|
module github.com/mikefarah/yq/v3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/fatih/color v1.9.0
|
||||||
|
github.com/goccy/go-yaml v1.3.2
|
||||||
github.com/kr/pretty v0.1.0 // indirect
|
github.com/kr/pretty v0.1.0 // indirect
|
||||||
github.com/kylelemons/godebug v1.1.0
|
github.com/kylelemons/godebug v1.1.0
|
||||||
github.com/pkg/errors v0.8.1
|
github.com/pkg/errors v0.8.1
|
||||||
|
|||||||
29
go.sum
29
go.sum
@@ -4,8 +4,16 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc
|
|||||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
|
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
||||||
|
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||||
|
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||||
|
github.com/goccy/go-yaml v1.3.2 h1:joykVKVARE+kQNoaj0ijjPY7lhgdovyU6etuYEl3hFU=
|
||||||
|
github.com/goccy/go-yaml v1.3.2/go.mod h1:PsEEJ29nIFZL07P/c8dv4P6rQkVFFXafQee85U+ERHA=
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
@@ -16,7 +24,14 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
|
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
|
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||||
|
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
|
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
|
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||||
|
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
|
||||||
|
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
@@ -34,19 +49,33 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
|
|||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||||
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||||
|
gopkg.in/go-playground/validator.v9 v9.30.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||||
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 h1:6D+BvnJ/j6e222UW8s2qTSe3wGBtvo0MbVQG/c5k8RE=
|
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 h1:6D+BvnJ/j6e222UW8s2qTSe3wGBtvo0MbVQG/c5k8RE=
|
||||||
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473/go.mod h1:N1eN2tsCx0Ydtgjl4cqmbRCsY4/+z4cYDeqwZTk6zog=
|
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473/go.mod h1:N1eN2tsCx0Ydtgjl4cqmbRCsY4/+z4cYDeqwZTk6zog=
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 h1:Xe2gvTZUJpsvOWUnvmL/tmhVBZUmHSvLbMjRj6NUUKo=
|
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 h1:Xe2gvTZUJpsvOWUnvmL/tmhVBZUmHSvLbMjRj6NUUKo=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|||||||
61
pkg/yqlib/color_print.go
Normal file
61
pkg/yqlib/color_print.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package yqlib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
"github.com/goccy/go-yaml/lexer"
|
||||||
|
"github.com/goccy/go-yaml/printer"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Thanks @risentveber!
|
||||||
|
|
||||||
|
const escape = "\x1b"
|
||||||
|
|
||||||
|
func format(attr color.Attribute) string {
|
||||||
|
return fmt.Sprintf("%s[%dm", escape, attr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ColorizeAndPrint(bytes []byte, writer io.Writer) error {
|
||||||
|
tokens := lexer.Tokenize(string(bytes))
|
||||||
|
var p printer.Printer
|
||||||
|
p.Bool = func() *printer.Property {
|
||||||
|
return &printer.Property{
|
||||||
|
Prefix: format(color.FgHiMagenta),
|
||||||
|
Suffix: format(color.Reset),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.Number = func() *printer.Property {
|
||||||
|
return &printer.Property{
|
||||||
|
Prefix: format(color.FgHiMagenta),
|
||||||
|
Suffix: format(color.Reset),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.MapKey = func() *printer.Property {
|
||||||
|
return &printer.Property{
|
||||||
|
Prefix: format(color.FgCyan),
|
||||||
|
Suffix: format(color.Reset),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.Anchor = func() *printer.Property {
|
||||||
|
return &printer.Property{
|
||||||
|
Prefix: format(color.FgHiYellow),
|
||||||
|
Suffix: format(color.Reset),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.Alias = func() *printer.Property {
|
||||||
|
return &printer.Property{
|
||||||
|
Prefix: format(color.FgHiYellow),
|
||||||
|
Suffix: format(color.Reset),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.String = func() *printer.Property {
|
||||||
|
return &printer.Property{
|
||||||
|
Prefix: format(color.FgGreen),
|
||||||
|
Suffix: format(color.Reset),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err := writer.Write([]byte(p.PrintTokens(tokens) + "\n"))
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package yqlib
|
package yqlib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
@@ -12,20 +13,45 @@ type Encoder interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type yamlEncoder struct {
|
type yamlEncoder struct {
|
||||||
encoder *yaml.Encoder
|
destination io.Writer
|
||||||
|
indent int
|
||||||
|
colorise bool
|
||||||
|
firstDoc bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewYamlEncoder(destination io.Writer, indent int) Encoder {
|
func NewYamlEncoder(destination io.Writer, indent int, colorise bool) Encoder {
|
||||||
var encoder = yaml.NewEncoder(destination)
|
|
||||||
if indent < 0 {
|
if indent < 0 {
|
||||||
indent = 0
|
indent = 0
|
||||||
}
|
}
|
||||||
encoder.SetIndent(indent)
|
return &yamlEncoder{destination, indent, colorise, true}
|
||||||
return &yamlEncoder{encoder}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ye *yamlEncoder) Encode(node *yaml.Node) error {
|
func (ye *yamlEncoder) Encode(node *yaml.Node) error {
|
||||||
return ye.encoder.Encode(node)
|
|
||||||
|
destination := ye.destination
|
||||||
|
tempBuffer := bytes.NewBuffer(nil)
|
||||||
|
if ye.colorise {
|
||||||
|
destination = tempBuffer
|
||||||
|
}
|
||||||
|
|
||||||
|
var encoder = yaml.NewEncoder(destination)
|
||||||
|
|
||||||
|
encoder.SetIndent(ye.indent)
|
||||||
|
// TODO: work out if the first doc had a separator or not.
|
||||||
|
if ye.firstDoc {
|
||||||
|
ye.firstDoc = false
|
||||||
|
} else if _, err := destination.Write([]byte("---\n")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := encoder.Encode(node); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if ye.colorise {
|
||||||
|
return ColorizeAndPrint(tempBuffer.Bytes(), ye.destination)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type jsonEncoder struct {
|
type jsonEncoder struct {
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
yaml "gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PathParser interface {
|
type PathParser interface {
|
||||||
@@ -45,7 +47,7 @@ func (p *pathParser) MatchesNextPathElement(nodeContext NodeContext, nodeKey str
|
|||||||
}
|
}
|
||||||
var headString = fmt.Sprintf("%v", head)
|
var headString = fmt.Sprintf("%v", head)
|
||||||
|
|
||||||
if strings.Contains(headString, "==") {
|
if strings.Contains(headString, "==") && nodeContext.Node.Kind != yaml.ScalarNode {
|
||||||
log.Debug("ooh deep recursion time")
|
log.Debug("ooh deep recursion time")
|
||||||
result := strings.SplitN(headString, "==", 2)
|
result := strings.SplitN(headString, "==", 2)
|
||||||
path := strings.TrimSpace(result[0])
|
path := strings.TrimSpace(result[0])
|
||||||
@@ -63,6 +65,14 @@ func (p *pathParser) MatchesNextPathElement(nodeContext NodeContext, nodeKey str
|
|||||||
}
|
}
|
||||||
log.Debug("done deep recursing, found %v matches", len(navigationStrategy.GetVisitedNodes()))
|
log.Debug("done deep recursing, found %v matches", len(navigationStrategy.GetVisitedNodes()))
|
||||||
return len(navigationStrategy.GetVisitedNodes()) > 0
|
return len(navigationStrategy.GetVisitedNodes()) > 0
|
||||||
|
} else if strings.Contains(headString, "==") && nodeContext.Node.Kind == yaml.ScalarNode {
|
||||||
|
result := strings.SplitN(headString, "==", 2)
|
||||||
|
path := strings.TrimSpace(result[0])
|
||||||
|
value := strings.TrimSpace(result[1])
|
||||||
|
if path == "." {
|
||||||
|
log.Debug("need to match scalar")
|
||||||
|
return matchesString(value, nodeContext.Node.Value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if head == "+" {
|
if head == "+" {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
find . \( -path ./vendor \) -prune -o -name "*.go" -exec goimports -w {} \;
|
find . \( -path ./vendor \) -prune -o -name "*.go" -exec goimports -w {} \;
|
||||||
|
go mod tidy
|
||||||
|
|||||||
@@ -7,3 +7,6 @@ gox -ldflags "${LDFLAGS}" -output="build/yq_{{.OS}}_{{.Arch}}"
|
|||||||
# include non-default linux builds too
|
# include non-default linux builds too
|
||||||
gox -ldflags "${LDFLAGS}" -os=linux -output="build/yq_{{.OS}}_{{.Arch}}"
|
gox -ldflags "${LDFLAGS}" -os=linux -output="build/yq_{{.OS}}_{{.Arch}}"
|
||||||
|
|
||||||
|
cd build
|
||||||
|
rhash -r -a . -P -o checksums
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: yq
|
name: yq
|
||||||
version: '3.1.2'
|
version: '3.2.1'
|
||||||
summary: A lightweight and portable command-line YAML processor
|
summary: A lightweight and portable command-line YAML processor
|
||||||
description: |
|
description: |
|
||||||
The aim of the project is to be the jq or sed of yaml files.
|
The aim of the project is to be the jq or sed of yaml files.
|
||||||
|
|||||||
Reference in New Issue
Block a user