mirror of
https://github.com/mikefarah/yq.git
synced 2026-07-10 16:55:40 +00:00
Merge remote-tracking branch 'source/master' into carolynvs-add-log-accessor
This commit is contained in:
commit
39908ab5ae
@ -3,9 +3,11 @@ run:
|
||||
linters:
|
||||
enable:
|
||||
- errorlint
|
||||
- gci
|
||||
- gofmt
|
||||
- goimports
|
||||
- gosec
|
||||
- misspell
|
||||
issues:
|
||||
exclude-rules:
|
||||
- linters:
|
||||
|
||||
@ -220,6 +220,7 @@ Supported by @rmescandon (https://launchpad.net/~rmescandon/+archive/ubuntu/yq)
|
||||
- [Update yaml inplace](https://mikefarah.gitbook.io/yq/v/v4.x/commands/evaluate#flags)
|
||||
- [Complex expressions to select and update](https://mikefarah.gitbook.io/yq/operators/select#select-and-update-matching-values-in-map)
|
||||
- Keeps yaml formatting and comments when updating (though there are issues with whitespace)
|
||||
- [Load content from other files](https://mikefarah.gitbook.io/yq/operators/load)
|
||||
- [Convert to/from json](https://mikefarah.gitbook.io/yq/v/v4.x/usage/convert)
|
||||
- [Convert to properties](https://mikefarah.gitbook.io/yq/v/v4.x/usage/properties)
|
||||
- [Pipe data in by using '-'](https://mikefarah.gitbook.io/yq/v/v4.x/commands/evaluate)
|
||||
|
||||
@ -25,7 +25,7 @@ func initCommand(cmd *cobra.Command, args []string) (firstFileIndex int, err err
|
||||
firstFileIndex = 1
|
||||
}
|
||||
|
||||
// backwards compatibilty
|
||||
// backwards compatibility
|
||||
if outputToJSON {
|
||||
outputFormat = "json"
|
||||
}
|
||||
|
||||
1
go.sum
1
go.sum
@ -471,7 +471,6 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA=
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
8
merge-array-by-key.sh
Executable file
8
merge-array-by-key.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
# ./yq ea '.[]' examples/data*.yaml
|
||||
|
||||
|
||||
./yq ea '
|
||||
((.[] | {.name: .}) as $item ireduce ({}; . * $item )) as $uniqueMap
|
||||
| ( $uniqueMap | to_entries | .[]) as $item ireduce([]; . + $item.value)
|
||||
' examples/data*.yaml
|
||||
@ -108,7 +108,7 @@ will output
|
||||
a: frog
|
||||
```
|
||||
|
||||
## Two non existant keys are equal
|
||||
## Two non existent keys are equal
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: frog
|
||||
|
||||
@ -234,43 +234,60 @@ will output
|
||||
```
|
||||
|
||||
## Merge arrays of objects together, matching on a key
|
||||
It's a complex command, the trickyness comes from needing to have the right context in the expressions.
|
||||
First we save the second array into a variable '$two' which lets us reference it later.
|
||||
We then need to update the first array. We will use the relative update (|=) because we need to update relative to the current element of the array in the LHS in the RHS expression.
|
||||
We set the current element of the first array as $cur. Now we multiply (merge) $cur with the matching entry in $two, by passing $two through a select filter.
|
||||
There are several parts of the complex expression.
|
||||
The first part is doing the hard work, it creates a map from the arrays keyed by '.a', so that there are no duplicates.
|
||||
Then there's another reduce that converts that map back to an array.
|
||||
Finally, we set the result of the merged array back into the first doc.
|
||||
|
||||
To use this, you will need to update '.myArray' to be the expression to your array (e.g. .my.array), and '.a' to be the key field of your array (e.g. '.name')
|
||||
|
||||
Thanks Kev from [stackoverflow](https://stackoverflow.com/a/70109529/1168223)
|
||||
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- a: apple
|
||||
b: appleB
|
||||
- a: kiwi
|
||||
b: kiwiB
|
||||
- a: banana
|
||||
b: bananaB
|
||||
myArray:
|
||||
- a: apple
|
||||
b: appleB
|
||||
- a: kiwi
|
||||
b: kiwiB
|
||||
- a: banana
|
||||
b: bananaB
|
||||
something: else
|
||||
```
|
||||
And another sample another.yml file of:
|
||||
```yaml
|
||||
- a: banana
|
||||
c: bananaC
|
||||
- a: apple
|
||||
b: appleB2
|
||||
- a: dingo
|
||||
c: dingoC
|
||||
myArray:
|
||||
- a: banana
|
||||
c: bananaC
|
||||
- a: apple
|
||||
b: appleB2
|
||||
- a: dingo
|
||||
c: dingoC
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval-all '(select(fi==1) | .[]) as $two | select(fi==0) | .[] |= (. as $cur | $cur * ($two | select(.a == $cur.a)))' sample.yml another.yml
|
||||
yq eval-all '
|
||||
(
|
||||
((.myArray[] | {.a: .}) as $item ireduce ({}; . * $item )) as $uniqueMap
|
||||
| ( $uniqueMap | to_entries | .[]) as $item ireduce([]; . + $item.value)
|
||||
) as $mergedArray
|
||||
| select(fi == 0) | .myArray = $mergedArray
|
||||
' sample.yml another.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
- a: apple
|
||||
b: appleB2
|
||||
- a: kiwi
|
||||
b: kiwiB
|
||||
- a: banana
|
||||
b: bananaB
|
||||
c: bananaC
|
||||
myArray:
|
||||
- a: apple
|
||||
b: appleB2
|
||||
- a: kiwi
|
||||
b: kiwiB
|
||||
- a: banana
|
||||
b: bananaB
|
||||
c: bananaC
|
||||
- a: dingo
|
||||
c: dingoC
|
||||
something: else
|
||||
```
|
||||
|
||||
## Merge to prefix an element
|
||||
|
||||
@ -209,7 +209,7 @@ will output
|
||||
```
|
||||
|
||||
## Test using regex
|
||||
Like jq'q equivalant, this works like match but only returns true/false instead of full match details
|
||||
Like jq'q equivalent, this works like match but only returns true/false instead of full match details
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
|
||||
@ -68,7 +68,7 @@ func (p *expressionPostFixerImpl) ConvertToPostfix(infixTokens []*token) ([]*Ope
|
||||
}
|
||||
// now we should have [ as the last element on the opStack, get rid of it
|
||||
opStack = opStack[0 : len(opStack)-1]
|
||||
log.Debugf("deleteing open bracket from opstack")
|
||||
log.Debugf("deleting open bracket from opstack")
|
||||
|
||||
//and append a collect to the result
|
||||
// hack - see if there's the optional traverse flag
|
||||
|
||||
@ -34,7 +34,7 @@ func tryRemoveFile(filename string) {
|
||||
|
||||
// thanks https://stackoverflow.com/questions/21060945/simple-way-to-copy-a-file-in-golang
|
||||
func copyFileContents(src, dst string) (err error) {
|
||||
// ignore CWE-22 gosec issue - that's more targetted for http based apps that run in a public directory,
|
||||
// ignore CWE-22 gosec issue - that's more targeted for http based apps that run in a public directory,
|
||||
// and ensuring that it's not possible to give a path to a file outside thar directory.
|
||||
|
||||
in, err := os.Open(src) // #nosec
|
||||
|
||||
@ -2,7 +2,6 @@ package yqlib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"strconv"
|
||||
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
package yqlib
|
||||
|
||||
import (
|
||||
// "bufio"
|
||||
// "bytes"
|
||||
"bufio"
|
||||
"bytes"
|
||||
"container/list"
|
||||
|
||||
@ -173,7 +173,7 @@ var equalsOperatorScenarios = []expressionScenario{
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Two non existant keys are equal",
|
||||
description: "Two non existent keys are equal",
|
||||
document: "a: frog",
|
||||
expression: `select(.b == .c)`,
|
||||
expected: []string{
|
||||
|
||||
@ -15,7 +15,7 @@ type loadPrefs struct {
|
||||
}
|
||||
|
||||
func loadString(filename string) (*CandidateNode, error) {
|
||||
// ignore CWE-22 gosec issue - that's more targetted for http based apps that run in a public directory,
|
||||
// ignore CWE-22 gosec issue - that's more targeted for http based apps that run in a public directory,
|
||||
// and ensuring that it's not possible to give a path to a file outside that directory.
|
||||
|
||||
filebytes, err := ioutil.ReadFile(filename) // #nosec
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
package yqlib
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"container/list"
|
||||
|
||||
"github.com/jinzhu/copier"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
@ -42,7 +41,7 @@ func multiply(preferences multiplyPreferences) func(d *dataTreeNavigator, contex
|
||||
leadingContent, headComment, footComment := getComments(lhs, rhs)
|
||||
lhs.Node = unwrapDoc(lhs.Node)
|
||||
rhs.Node = unwrapDoc(rhs.Node)
|
||||
log.Debugf("Multipling LHS: %v", lhs.Node.Tag)
|
||||
log.Debugf("Multiplying LHS: %v", lhs.Node.Tag)
|
||||
log.Debugf("- RHS: %v", rhs.Node.Tag)
|
||||
|
||||
if lhs.Node.Kind == yaml.MappingNode && rhs.Node.Kind == yaml.MappingNode ||
|
||||
|
||||
@ -29,10 +29,22 @@ var mergeArrayWithAnchors = `sample:
|
||||
- <<: *a
|
||||
`
|
||||
|
||||
var mergeArraysObjectKeysText = `It's a complex command, the trickyness comes from needing to have the right context in the expressions.
|
||||
First we save the second array into a variable '$two' which lets us reference it later.
|
||||
We then need to update the first array. We will use the relative update (|=) because we need to update relative to the current element of the array in the LHS in the RHS expression.
|
||||
We set the current element of the first array as $cur. Now we multiply (merge) $cur with the matching entry in $two, by passing $two through a select filter.
|
||||
var mergeArraysObjectKeysText = `There are several parts of the complex expression.
|
||||
The first part is doing the hard work, it creates a map from the arrays keyed by '.a', so that there are no duplicates.
|
||||
Then there's another reduce that converts that map back to an array.
|
||||
Finally, we set the result of the merged array back into the first doc.
|
||||
|
||||
To use this, you will need to update '.myArray' to be the expression to your array (e.g. .my.array), and '.a' to be the key field of your array (e.g. '.name')
|
||||
|
||||
Thanks Kev from [stackoverflow](https://stackoverflow.com/a/70109529/1168223)
|
||||
`
|
||||
|
||||
var mergeExpression = `
|
||||
(
|
||||
((.myArray[] | {.a: .}) as $item ireduce ({}; . * $item )) as $uniqueMap
|
||||
| ( $uniqueMap | to_entries | .[]) as $item ireduce([]; . + $item.value)
|
||||
) as $mergedArray
|
||||
| select(fi == 0) | .myArray = $mergedArray
|
||||
`
|
||||
|
||||
var docWithHeader = `# here
|
||||
@ -371,11 +383,11 @@ var multiplyOperatorScenarios = []expressionScenario{
|
||||
{
|
||||
description: "Merge arrays of objects together, matching on a key",
|
||||
subdescription: mergeArraysObjectKeysText,
|
||||
document: `[{a: apple, b: appleB}, {a: kiwi, b: kiwiB}, {a: banana, b: bananaB}]`,
|
||||
document2: `[{a: banana, c: bananaC}, {a: apple, b: appleB2}, {a: dingo, c: dingoC}]`,
|
||||
expression: `(select(fi==1) | .[]) as $two | select(fi==0) | .[] |= (. as $cur | $cur * ($two | select(.a == $cur.a)))`,
|
||||
document: `{myArray: [{a: apple, b: appleB}, {a: kiwi, b: kiwiB}, {a: banana, b: bananaB}], something: else}`,
|
||||
document2: `myArray: [{a: banana, c: bananaC}, {a: apple, b: appleB2}, {a: dingo, c: dingoC}]`,
|
||||
expression: mergeExpression,
|
||||
expected: []string{
|
||||
"D0, P[], (doc)::[{a: apple, b: appleB2}, {a: kiwi, b: kiwiB}, {a: banana, b: bananaB, c: bananaC}]\n",
|
||||
"D0, P[], (doc)::{myArray: [{a: apple, b: appleB2}, {a: kiwi, b: kiwiB}, {a: banana, b: bananaB, c: bananaC}, {a: dingo, c: dingoC}], something: else}\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@ -99,7 +99,7 @@ var stringsOperatorScenarios = []expressionScenario{
|
||||
},
|
||||
{
|
||||
description: "Test using regex",
|
||||
subdescription: "Like jq'q equivalant, this works like match but only returns true/false instead of full match details",
|
||||
subdescription: "Like jq'q equivalent, this works like match but only returns true/false instead of full match details",
|
||||
document: `["cat", "dog"]`,
|
||||
expression: `.[] | test("at")`,
|
||||
expected: []string{
|
||||
|
||||
@ -2,7 +2,6 @@ package yqlib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
@ -42,7 +42,7 @@ func traverse(d *dataTreeNavigator, context Context, matchingNode *CandidateNode
|
||||
|
||||
if value.Tag == "!!null" && operation.Value != "[]" {
|
||||
log.Debugf("Guessing kind")
|
||||
// we must ahve added this automatically, lets guess what it should be now
|
||||
// we must have added this automatically, lets guess what it should be now
|
||||
switch operation.Value.(type) {
|
||||
case int, int64:
|
||||
log.Debugf("probably an array")
|
||||
@ -87,7 +87,7 @@ func traverseArrayOperator(d *dataTreeNavigator, context Context, expressionNode
|
||||
return Context{}, err
|
||||
}
|
||||
|
||||
// rhs is a collect expression that will yield indexes to retreive of the arrays
|
||||
// rhs is a collect expression that will yield indexes to retrieve of the arrays
|
||||
|
||||
rhs, err := d.GetMatchingNodes(context.ReadOnlyClone(), expressionNode.Rhs)
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ func readStream(filename string, leadingContentPreProcessing bool) (io.Reader, s
|
||||
if filename == "-" {
|
||||
reader = bufio.NewReader(os.Stdin)
|
||||
} else {
|
||||
// ignore CWE-22 gosec issue - that's more targetted for http based apps that run in a public directory,
|
||||
// ignore CWE-22 gosec issue - that's more targeted for http based apps that run in a public directory,
|
||||
// and ensuring that it's not possible to give a path to a file outside thar directory.
|
||||
file, err := os.Open(filename) // #nosec
|
||||
if err != nil {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
go mod download golang.org/x/tools
|
||||
wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.37.1
|
||||
go mod download golang.org/x/tools@latest
|
||||
wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.43.0
|
||||
wget -O- -nv https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s v2.9.1
|
||||
|
||||
Loading…
Reference in New Issue
Block a user