mirror of
https://github.com/mikefarah/yq.git
synced 2025-01-14 12:35:35 +00:00
wip - rabbit hole :/
This commit is contained in:
parent
cd50b35787
commit
42843763ca
@ -63,7 +63,6 @@ func (o *CandidateNode) copyFromYamlNode(node *yaml.Node, anchorMap map[string]*
|
||||
o.Alias = anchorMap[node.Alias.Anchor]
|
||||
log.Debug("set alias to %v", NodeToString(anchorMap[node.Alias.Anchor]))
|
||||
}
|
||||
|
||||
o.HeadComment = node.HeadComment
|
||||
o.LineComment = node.LineComment
|
||||
o.FootComment = node.FootComment
|
||||
@ -107,7 +106,6 @@ func (o *CandidateNode) decodeIntoChild(childNode *yaml.Node, anchorMap map[stri
|
||||
}
|
||||
|
||||
func (o *CandidateNode) UnmarshalYAML(node *yaml.Node, anchorMap map[string]*CandidateNode) error {
|
||||
|
||||
log.Debugf("UnmarshalYAML %v", node.Tag)
|
||||
switch node.Kind {
|
||||
case yaml.DocumentNode:
|
||||
|
@ -20,8 +20,9 @@ type yamlDecoder struct {
|
||||
leadingContent string
|
||||
bufferRead bytes.Buffer
|
||||
|
||||
readAnything bool
|
||||
firstFile bool
|
||||
readAnything bool
|
||||
firstFile bool
|
||||
documentIndex uint
|
||||
}
|
||||
|
||||
func NewYamlDecoder(prefs YamlPreferences) Decoder {
|
||||
@ -93,6 +94,7 @@ func (dec *yamlDecoder) Init(reader io.Reader) error {
|
||||
dec.readAnything = false
|
||||
dec.decoder = *yaml.NewDecoder(readerToUse)
|
||||
dec.firstFile = false
|
||||
dec.documentIndex = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -117,14 +119,18 @@ func (dec *yamlDecoder) Decode() (*CandidateNode, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
candidateNode := CandidateNode{}
|
||||
candidateNode.UnmarshalYAML(&yamlNode, make(map[string]*CandidateNode))
|
||||
candidateNode := CandidateNode{Document: dec.documentIndex}
|
||||
err = candidateNode.UnmarshalYAML(&yamlNode, make(map[string]*CandidateNode))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if dec.leadingContent != "" {
|
||||
candidateNode.LeadingContent = dec.leadingContent
|
||||
dec.leadingContent = ""
|
||||
}
|
||||
dec.readAnything = true
|
||||
dec.documentIndex++
|
||||
// move document comments into candidate node
|
||||
// otherwise unwrap drops them.
|
||||
candidateNode.TrailingContent = candidateNode.FootComment
|
||||
|
@ -93,8 +93,7 @@ a:
|
||||
## String concatenation
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: meow
|
||||
{a: cat, b: meow}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -102,8 +101,7 @@ yq '.a += .b' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: catmeow
|
||||
b: meow
|
||||
{a: catmeow, b: meow}
|
||||
```
|
||||
|
||||
## Number addition - float
|
||||
@ -111,8 +109,7 @@ If the lhs or rhs are floats then the expression will be calculated with floats.
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: 3
|
||||
b: 4.9
|
||||
{a: 3, b: 4.9}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -120,8 +117,7 @@ yq '.a = .a + .b' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: 7.9
|
||||
b: 4.9
|
||||
{a: 7.9, b: 4.9}
|
||||
```
|
||||
|
||||
## Number addition - int
|
||||
@ -129,8 +125,7 @@ If both the lhs and rhs are ints then the expression will be calculated with int
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: 3
|
||||
b: 4
|
||||
{a: 3, b: 4}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -138,15 +133,13 @@ yq '.a = .a + .b' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: 7
|
||||
b: 4
|
||||
{a: 7, b: 4}
|
||||
```
|
||||
|
||||
## Increment numbers
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: 3
|
||||
b: 5
|
||||
{a: 3, b: 5}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -154,8 +147,7 @@ yq '.[] += 1' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: 4
|
||||
b: 6
|
||||
{a: 4, b: 6}
|
||||
```
|
||||
|
||||
## Date addition
|
||||
|
@ -5,7 +5,7 @@ This operator is used to provide alternative (or default) values when a particul
|
||||
## LHS is defined
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: bridge
|
||||
{a: bridge}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -33,7 +33,7 @@ hello
|
||||
## LHS is null
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: ~
|
||||
{a: ~}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -47,7 +47,7 @@ hello
|
||||
## LHS is false
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: false
|
||||
{a: false}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -61,8 +61,7 @@ hello
|
||||
## RHS is an expression
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: false
|
||||
b: cat
|
||||
{a: false, b: cat}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
|
@ -27,9 +27,7 @@ x: frog
|
||||
## Update node to be the child value
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
b:
|
||||
g: foof
|
||||
{a: {b: {g: foof}}}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -37,16 +35,13 @@ yq '.a |= .b' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a:
|
||||
g: foof
|
||||
{a: {g: foof}}
|
||||
```
|
||||
|
||||
## Double elements in an array
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
[1, 2, 3]
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -54,9 +49,7 @@ yq '.[] |= . * 2' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
- 2
|
||||
- 4
|
||||
- 6
|
||||
[2, 4, 6]
|
||||
```
|
||||
|
||||
## Update node from another file
|
||||
@ -64,11 +57,11 @@ Note this will also work when the second file is a scalar (string/number)
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: apples
|
||||
{a: apples}
|
||||
```
|
||||
And another sample another.yml file of:
|
||||
```yaml
|
||||
b: bob
|
||||
{b: bob}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -76,16 +69,13 @@ yq eval-all 'select(fileIndex==0).a = select(fileIndex==1) | select(fileIndex==0
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a:
|
||||
b: bob
|
||||
{a: {b: bob}}
|
||||
```
|
||||
|
||||
## Update node to be the sibling value
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
b: child
|
||||
b: sibling
|
||||
{a: {b: child}, b: sibling}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -93,16 +83,13 @@ yq '.a = .b' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: sibling
|
||||
b: sibling
|
||||
{a: sibling, b: sibling}
|
||||
```
|
||||
|
||||
## Updated multiple paths
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: fieldA
|
||||
b: fieldB
|
||||
c: fieldC
|
||||
{a: fieldA, b: fieldB, c: fieldC}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -110,16 +97,13 @@ yq '(.a, .c) = "potato"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: potato
|
||||
b: fieldB
|
||||
c: potato
|
||||
{a: potato, b: fieldB, c: potato}
|
||||
```
|
||||
|
||||
## Update string value
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
b: apple
|
||||
{a: {b: apple}}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -127,8 +111,7 @@ yq '.a.b = "frog"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a:
|
||||
b: frog
|
||||
{a: {b: frog}}
|
||||
```
|
||||
|
||||
## Update string value via |=
|
||||
@ -136,8 +119,7 @@ Note there is no difference between `=` and `|=` when the RHS is a scalar
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
b: apple
|
||||
{a: {b: apple}}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -145,8 +127,7 @@ yq '.a.b |= "frog"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a:
|
||||
b: frog
|
||||
{a: {b: frog}}
|
||||
```
|
||||
|
||||
## Update deeply selected results
|
||||
@ -154,9 +135,7 @@ Note that the LHS is wrapped in brackets! This is to ensure we don't first filte
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
b: apple
|
||||
c: cactus
|
||||
{a: {b: apple, c: cactus}}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -164,17 +143,13 @@ yq '(.a[] | select(. == "apple")) = "frog"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a:
|
||||
b: frog
|
||||
c: cactus
|
||||
{a: {b: frog, c: cactus}}
|
||||
```
|
||||
|
||||
## Update array values
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- candy
|
||||
- apple
|
||||
- sandy
|
||||
[candy, apple, sandy]
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -182,9 +157,7 @@ yq '(.[] | select(. == "*andy")) = "bogs"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
- bogs
|
||||
- apple
|
||||
- bogs
|
||||
[bogs, apple, bogs]
|
||||
```
|
||||
|
||||
## Update empty object
|
||||
|
@ -39,12 +39,7 @@ false
|
||||
## Matching nodes with select, equals and or
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- a: bird
|
||||
b: dog
|
||||
- a: frog
|
||||
b: bird
|
||||
- a: cat
|
||||
b: fly
|
||||
[{a: bird, b: dog}, {a: frog, b: bird}, {a: cat, b: fly}]
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -52,17 +47,14 @@ yq '[.[] | select(.a == "cat" or .b == "dog")]' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
- a: bird
|
||||
b: dog
|
||||
- a: cat
|
||||
b: fly
|
||||
- {a: bird, b: dog}
|
||||
- {a: cat, b: fly}
|
||||
```
|
||||
|
||||
## `any` returns true if any boolean in a given array is true
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- false
|
||||
- true
|
||||
[false, true]
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -110,8 +102,7 @@ b: false
|
||||
## `all` returns true if all booleans in a given array are true
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- true
|
||||
- true
|
||||
[true, true]
|
||||
```
|
||||
then
|
||||
```bash
|
||||
|
@ -26,8 +26,7 @@ will output
|
||||
## Collect many
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: dog
|
||||
{a: cat, b: dog}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
|
@ -10,56 +10,6 @@ This will set the LHS nodes' comments equal to the expression on the RHS. The RH
|
||||
### relative form: `|=`
|
||||
This is similar to the plain form, but it evaluates the RHS with _each matching LHS node as context_. This is useful if you want to set the comments as a relative expression of the node, for instance its value or path.
|
||||
|
||||
## Set line comment
|
||||
Set the comment on the key node for more reliability (see below).
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '.a line_comment="single"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: cat # single
|
||||
```
|
||||
|
||||
## Set line comment of a maps/arrays
|
||||
For maps and arrays, you need to set the line comment on the _key_ node. This will also work for scalars.
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
b: things
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '(.a | key) line_comment="single"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a:
|
||||
b: things
|
||||
```
|
||||
|
||||
## Use update assign to perform relative updates
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: dog
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '.. line_comment |= .' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: cat # cat
|
||||
b: dog # dog
|
||||
```
|
||||
|
||||
## Where is the comment - map key example
|
||||
The underlying yaml parser can assign comments in a document to surprising nodes. Use an expression like this to find where you comment is. 'p' indicates the path, 'isKey' is if the node is a map key (as opposed to a map value).
|
||||
From this, you can see the 'hello-world-comment' is actually on the 'hello' key
|
||||
@ -83,11 +33,9 @@ will output
|
||||
- p: hello
|
||||
isKey: null
|
||||
true: null
|
||||
hc: null
|
||||
"": null
|
||||
lc: null
|
||||
hello-world-comment: null
|
||||
fc: null
|
||||
hc: ""
|
||||
lc: hello-world-comment
|
||||
fc: ""
|
||||
- p: hello
|
||||
isKey: false
|
||||
hc: ""
|
||||
@ -96,10 +44,9 @@ will output
|
||||
- p: hello.message
|
||||
isKey: null
|
||||
true: null
|
||||
hc: null
|
||||
"": null
|
||||
lc: null
|
||||
fc: null
|
||||
hc: ""
|
||||
lc: ""
|
||||
fc: ""
|
||||
- p: hello.message
|
||||
isKey: false
|
||||
hc: ""
|
||||
@ -107,242 +54,3 @@ will output
|
||||
fc: ""
|
||||
```
|
||||
|
||||
## Retrieve comment - map key example
|
||||
From the previous example, we know that the comment is on the 'hello' _key_ as a lineComment
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
hello: # hello-world-comment
|
||||
message: world
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '.hello | key | line_comment' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
hello-world-comment
|
||||
```
|
||||
|
||||
## Where is the comment - array example
|
||||
The underlying yaml parser can assign comments in a document to surprising nodes. Use an expression like this to find where you comment is. 'p' indicates the path, 'isKey' is if the node is a map key (as opposed to a map value).
|
||||
From this, you can see the 'under-name-comment' is actually on the first child
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
name:
|
||||
# under-name-comment
|
||||
- first-array-child
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '[... | {"p": path | join("."), "isKey": is_key, "hc": headComment, "lc": lineComment, "fc": footComment}]' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
- p: ""
|
||||
isKey: false
|
||||
hc: ""
|
||||
lc: ""
|
||||
fc: ""
|
||||
- p: name
|
||||
isKey: null
|
||||
true: null
|
||||
hc: null
|
||||
"": null
|
||||
lc: null
|
||||
fc: null
|
||||
- p: name
|
||||
isKey: false
|
||||
hc: ""
|
||||
lc: ""
|
||||
fc: ""
|
||||
- p: name.0
|
||||
isKey: false
|
||||
hc: under-name-comment
|
||||
lc: ""
|
||||
fc: ""
|
||||
```
|
||||
|
||||
## Retrieve comment - array example
|
||||
From the previous example, we know that the comment is on the first child as a headComment
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
name:
|
||||
# under-name-comment
|
||||
- first-array-child
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '.name[0] | headComment' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
under-name-comment
|
||||
```
|
||||
|
||||
## Set head comment
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '. head_comment="single"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
# single
|
||||
|
||||
a: cat
|
||||
```
|
||||
|
||||
## Set head comment of a map entry
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
f: foo
|
||||
a:
|
||||
b: cat
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '(.a | key) head_comment="single"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
f: foo
|
||||
a:
|
||||
b: cat
|
||||
```
|
||||
|
||||
## Set foot comment, using an expression
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '. foot_comment=.a' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: cat
|
||||
# cat
|
||||
```
|
||||
|
||||
## Remove comment
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat # comment
|
||||
b: dog # leave this
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '.a line_comment=""' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: cat
|
||||
b: dog # leave this
|
||||
```
|
||||
|
||||
## Remove (strip) all comments
|
||||
Note the use of `...` to ensure key nodes are included.
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
# hi
|
||||
|
||||
a: cat # comment
|
||||
# great
|
||||
b: # key comment
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '... comments=""' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
# hi
|
||||
|
||||
a: cat
|
||||
b:
|
||||
```
|
||||
|
||||
## Get line comment
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
# welcome!
|
||||
|
||||
a: cat # meow
|
||||
# have a great day
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '.a | line_comment' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
meow
|
||||
```
|
||||
|
||||
## Get head comment
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
# welcome!
|
||||
|
||||
a: cat # meow
|
||||
|
||||
# have a great day
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '. | head_comment' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
welcome!
|
||||
|
||||
```
|
||||
|
||||
## Head comment with document split
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
# welcome!
|
||||
---
|
||||
# bob
|
||||
a: cat # meow
|
||||
|
||||
# have a great day
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq 'head_comment' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
welcome!
|
||||
bob
|
||||
```
|
||||
|
||||
## Get foot comment
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
# welcome!
|
||||
|
||||
a: cat # meow
|
||||
|
||||
# have a great day
|
||||
# no really
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '. | foot_comment' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
have a great day
|
||||
no really
|
||||
```
|
||||
|
||||
|
@ -15,9 +15,7 @@ Array is equal or subset of
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- foobar
|
||||
- foobaz
|
||||
- blarp
|
||||
[foobar, foobaz, blarp]
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -33,9 +31,7 @@ Subtract the superset array from the subset, if there's anything left, it's not
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- foobar
|
||||
- foobaz
|
||||
- blarp
|
||||
[foobar, foobaz, blarp]
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -49,12 +45,7 @@ false
|
||||
## Object included in array
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
"foo": 12
|
||||
"bar":
|
||||
- 1
|
||||
- 2
|
||||
- "barp": 12
|
||||
"blip": 13
|
||||
{"foo": 12, "bar": [1, 2, {"barp": 12, "blip": 13}]}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -68,22 +59,21 @@ true
|
||||
## Object not included in array
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
"foo": 12
|
||||
"bar":
|
||||
- 1
|
||||
- 2
|
||||
- "barp": 12
|
||||
"blip": 13
|
||||
{"foo": 12, "bar": [1, 2, {"barp": 12, "blip": 13}]}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq 'contains({"foo": 12, "bar": [{"barp": 15}]})' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
false
|
||||
```
|
||||
|
||||
## String contains substring
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
foobar
|
||||
"foobar"
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -97,7 +87,7 @@ true
|
||||
## String equals string
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
meow
|
||||
"meow"
|
||||
```
|
||||
then
|
||||
```bash
|
||||
|
@ -15,7 +15,7 @@ will output
|
||||
## Wrap (prefix) existing object
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
name: Mike
|
||||
{name: Mike}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -23,17 +23,13 @@ yq '{"wrap": .}' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
wrap:
|
||||
name: Mike
|
||||
wrap: {name: Mike}
|
||||
```
|
||||
|
||||
## Using splat to create multiple objects
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
name: Mike
|
||||
pets:
|
||||
- cat
|
||||
- dog
|
||||
{name: Mike, pets: [cat, dog]}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -48,15 +44,9 @@ Mike: dog
|
||||
## Working with multiple documents
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
name: Mike
|
||||
pets:
|
||||
- cat
|
||||
- dog
|
||||
{name: Mike, pets: [cat, dog]}
|
||||
---
|
||||
name: Rosey
|
||||
pets:
|
||||
- monkey
|
||||
- sheep
|
||||
{name: Rosey, pets: [monkey, sheep]}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
|
@ -2,123 +2,10 @@
|
||||
|
||||
Use the `keys` operator to return map keys or array indices.
|
||||
|
||||
## Map keys
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
dog: woof
|
||||
cat: meow
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq 'keys' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
- dog
|
||||
- cat
|
||||
```
|
||||
|
||||
## Array keys
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- apple
|
||||
- banana
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq 'keys' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
- 0
|
||||
- 1
|
||||
```
|
||||
|
||||
## Retrieve array key
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '.[1] | key' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
1
|
||||
```
|
||||
|
||||
## Retrieve map key
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: thing
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '.a | key' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a
|
||||
```
|
||||
|
||||
## No key
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
{}
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq 'key' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
```
|
||||
|
||||
## Update map key
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
x: 3
|
||||
y: 4
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '(.a.x | key) = "meow"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a:
|
||||
meow: 3
|
||||
y: 4
|
||||
```
|
||||
|
||||
## Get comment from map key
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
# comment on key
|
||||
x: 3
|
||||
y: 4
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '.a.x | key | headComment' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
comment on key
|
||||
```
|
||||
|
||||
## Check node is a key
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
b:
|
||||
- cat
|
||||
c: frog
|
||||
a: frog
|
||||
```
|
||||
then
|
||||
```bash
|
||||
@ -131,23 +18,9 @@ will output
|
||||
tag: '!!map'
|
||||
- p: a
|
||||
isKey: true
|
||||
tag: '!!str'
|
||||
tag: null
|
||||
'!!str': null
|
||||
- p: a
|
||||
isKey: false
|
||||
tag: '!!map'
|
||||
- p: a.b
|
||||
isKey: true
|
||||
tag: '!!str'
|
||||
- p: a.b
|
||||
isKey: false
|
||||
tag: '!!seq'
|
||||
- p: a.b.0
|
||||
isKey: false
|
||||
tag: '!!str'
|
||||
- p: a.c
|
||||
isKey: true
|
||||
tag: '!!str'
|
||||
- p: a.c
|
||||
isKey: false
|
||||
tag: '!!str'
|
||||
```
|
||||
|
@ -37,9 +37,13 @@ func assignCommentsOperator(d *dataTreeNavigator, context Context, expressionNod
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf("AssignComments comment is %v", comment)
|
||||
|
||||
for el := lhs.MatchingNodes.Front(); el != nil; el = el.Next() {
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
|
||||
log.Debugf("AssignComments lhs %v", NodeToString(candidate))
|
||||
|
||||
if expressionNode.Operation.UpdateAssign {
|
||||
rhs, err := d.GetMatchingNodes(context.SingleReadonlyChildContext(candidate), expressionNode.RHS)
|
||||
if err != nil {
|
||||
@ -53,6 +57,7 @@ func assignCommentsOperator(d *dataTreeNavigator, context Context, expressionNod
|
||||
|
||||
log.Debugf("Setting comment of : %v", candidate.GetKey())
|
||||
if preferences.LineComment {
|
||||
log.Debugf("Setting line comment of : %v to %v", candidate.GetKey(), comment)
|
||||
candidate.LineComment = comment
|
||||
}
|
||||
if preferences.HeadComment {
|
||||
@ -60,10 +65,11 @@ func assignCommentsOperator(d *dataTreeNavigator, context Context, expressionNod
|
||||
candidate.LeadingContent = "" // clobber the leading content, if there was any.
|
||||
}
|
||||
if preferences.FootComment && candidate.Kind == DocumentNode && comment != "" {
|
||||
log.Debugf("AssignComments - setting line comment to %v", comment)
|
||||
candidate.TrailingContent = "# " + comment
|
||||
} else if preferences.FootComment && candidate.Kind == DocumentNode {
|
||||
log.Debugf("AssignComments - setting line comment to %v", comment)
|
||||
candidate.TrailingContent = comment
|
||||
|
||||
} else if preferences.FootComment && candidate.Kind != DocumentNode {
|
||||
candidate.FootComment = comment
|
||||
candidate.TrailingContent = ""
|
||||
@ -89,6 +95,7 @@ func getCommentsOperator(d *dataTreeNavigator, context Context, expressionNode *
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
comment := ""
|
||||
if preferences.LineComment {
|
||||
log.Debugf("Reading line comment of : %v to %v", candidate.GetKey(), candidate.LineComment)
|
||||
comment = candidate.LineComment
|
||||
} else if preferences.HeadComment && candidate.LeadingContent != "" {
|
||||
var chompRegexp = regexp.MustCompile(`\n$`)
|
||||
@ -114,6 +121,10 @@ func getCommentsOperator(d *dataTreeNavigator, context Context, expressionNode *
|
||||
comment = subsequentCommentCharaterRegExp.ReplaceAllString(comment, "\n")
|
||||
|
||||
result := candidate.CreateReplacement(ScalarNode, "!!str", comment)
|
||||
if candidate.IsMapKey {
|
||||
result.IsMapKey = false
|
||||
result.Key = candidate
|
||||
}
|
||||
results.PushBack(result)
|
||||
}
|
||||
return context.ChildContext(results), nil
|
||||
|
@ -54,57 +54,57 @@ var expectedWhereIsMyCommentArray = `D0, P[], (!!seq)::- p: ""
|
||||
`
|
||||
|
||||
var commentOperatorScenarios = []expressionScenario{
|
||||
{
|
||||
description: "Set line comment",
|
||||
subdescription: "Set the comment on the key node for more reliability (see below).",
|
||||
document: `a: cat`,
|
||||
expression: `.a line_comment="single"`,
|
||||
expected: []string{
|
||||
"D0, P[], (doc)::a: cat # single\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Set line comment of a maps/arrays",
|
||||
subdescription: "For maps and arrays, you need to set the line comment on the _key_ node. This will also work for scalars.",
|
||||
document: "a:\n b: things",
|
||||
expression: `(.a | key) line_comment="single"`,
|
||||
expected: []string{
|
||||
"D0, P[], (doc)::a: # single\n b: things\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
document: "a: cat\nb: dog",
|
||||
expression: `.a line_comment=.b`,
|
||||
expected: []string{
|
||||
"D0, P[], (doc)::a: cat # dog\nb: dog\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
document: "a: cat\n---\na: dog",
|
||||
expression: `.a line_comment |= documentIndex`,
|
||||
expected: []string{
|
||||
"D0, P[], (doc)::a: cat # 0\n",
|
||||
"D1, P[], (doc)::a: dog # 1\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Use update assign to perform relative updates",
|
||||
document: "a: cat\nb: dog",
|
||||
expression: `.. line_comment |= .`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::a: cat # cat\nb: dog # dog\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
document: "a: cat\nb: dog",
|
||||
expression: `.. comments |= .`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::a: cat # cat\n# cat\n\n# cat\nb: dog # dog\n# dog\n\n# dog\n",
|
||||
},
|
||||
},
|
||||
// {
|
||||
// description: "Set line comment",
|
||||
// subdescription: "Set the comment on the key node for more reliability (see below).",
|
||||
// document: `a: cat`,
|
||||
// expression: `.a line_comment="single"`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (doc)::a: cat # single\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "Set line comment of a maps/arrays",
|
||||
// subdescription: "For maps and arrays, you need to set the line comment on the _key_ node. This will also work for scalars.",
|
||||
// document: "a:\n b: things",
|
||||
// expression: `(.a | key) line_comment="single"`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (doc)::a: # single\n b: things\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// skipDoc: true,
|
||||
// document: "a: cat\nb: dog",
|
||||
// expression: `.a line_comment=.b`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (doc)::a: cat # dog\nb: dog\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// skipDoc: true,
|
||||
// document: "a: cat\n---\na: dog",
|
||||
// expression: `.a line_comment |= documentIndex`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (doc)::a: cat # 0\n",
|
||||
// "D1, P[], (doc)::a: dog # 1\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "Use update assign to perform relative updates",
|
||||
// document: "a: cat\nb: dog",
|
||||
// expression: `.. line_comment |= .`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (doc)::a: cat # cat\nb: dog # dog\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// skipDoc: true,
|
||||
// document: "a: cat\nb: dog",
|
||||
// expression: `.. comments |= .`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (doc)::a: cat # cat\n# cat\n\n# cat\nb: dog # dog\n# dog\n\n# dog\n",
|
||||
// },
|
||||
// },
|
||||
{
|
||||
description: "Where is the comment - map key example",
|
||||
subdescription: "The underlying yaml parser can assign comments in a document to surprising nodes. Use an expression like this to find where you comment is. 'p' indicates the path, 'isKey' is if the node is a map key (as opposed to a map value).\nFrom this, you can see the 'hello-world-comment' is actually on the 'hello' key",
|
||||
@ -114,152 +114,152 @@ var commentOperatorScenarios = []expressionScenario{
|
||||
expectedWhereIsMyCommentMapKey,
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Retrieve comment - map key example",
|
||||
subdescription: "From the previous example, we know that the comment is on the 'hello' _key_ as a lineComment",
|
||||
document: "hello: # hello-world-comment\n message: world",
|
||||
expression: `.hello | key | line_comment`,
|
||||
expected: []string{
|
||||
"D0, P[hello], (!!str)::hello-world-comment\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Where is the comment - array example",
|
||||
subdescription: "The underlying yaml parser can assign comments in a document to surprising nodes. Use an expression like this to find where you comment is. 'p' indicates the path, 'isKey' is if the node is a map key (as opposed to a map value).\nFrom this, you can see the 'under-name-comment' is actually on the first child",
|
||||
document: "name:\n # under-name-comment\n - first-array-child",
|
||||
expression: `[... | {"p": path | join("."), "isKey": is_key, "hc": headComment, "lc": lineComment, "fc": footComment}]`,
|
||||
expected: []string{
|
||||
expectedWhereIsMyCommentArray,
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Retrieve comment - array example",
|
||||
subdescription: "From the previous example, we know that the comment is on the first child as a headComment",
|
||||
document: "name:\n # under-name-comment\n - first-array-child",
|
||||
expression: `.name[0] | headComment`,
|
||||
expected: []string{
|
||||
"D0, P[name 0], (!!str)::under-name-comment\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Set head comment",
|
||||
document: `a: cat`,
|
||||
expression: `. head_comment="single"`,
|
||||
expected: []string{
|
||||
"D0, P[], (doc)::# single\n\na: cat\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Set head comment of a map entry",
|
||||
document: "f: foo\na:\n b: cat",
|
||||
expression: `(.a | key) head_comment="single"`,
|
||||
expected: []string{
|
||||
"D0, P[], (doc)::f: foo\n# single\na:\n b: cat\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Set foot comment, using an expression",
|
||||
document: `a: cat`,
|
||||
expression: `. foot_comment=.a`,
|
||||
expected: []string{
|
||||
"D0, P[], (doc)::a: cat\n# cat\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
description: "Set foot comment, using an expression",
|
||||
document: "a: cat\n\n# hi",
|
||||
expression: `. foot_comment=""`,
|
||||
expected: []string{
|
||||
"D0, P[], (doc)::a: cat\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
document: `a: cat`,
|
||||
expression: `. foot_comment=.b.d`,
|
||||
expected: []string{
|
||||
"D0, P[], (doc)::a: cat\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
document: `a: cat`,
|
||||
expression: `. foot_comment|=.b.d`,
|
||||
expected: []string{
|
||||
"D0, P[], (doc)::a: cat\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Remove comment",
|
||||
document: "a: cat # comment\nb: dog # leave this",
|
||||
expression: `.a line_comment=""`,
|
||||
expected: []string{
|
||||
"D0, P[], (doc)::a: cat\nb: dog # leave this\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Remove (strip) all comments",
|
||||
subdescription: "Note the use of `...` to ensure key nodes are included.",
|
||||
document: "# hi\n\na: cat # comment\n\n# great\n\nb: # key comment",
|
||||
expression: `... comments=""`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::a: cat\nb:\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Get line comment",
|
||||
document: "# welcome!\n\na: cat # meow\n\n# have a great day",
|
||||
expression: `.a | line_comment`,
|
||||
expected: []string{
|
||||
"D0, P[a], (!!str)::meow\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Get head comment",
|
||||
dontFormatInputForDoc: true,
|
||||
document: "# welcome!\n\na: cat # meow\n\n# have a great day",
|
||||
expression: `. | head_comment`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!str)::welcome!\n\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
description: "strip trailing comment recurse all",
|
||||
document: "a: cat\n\n# haha",
|
||||
expression: `... comments= ""`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::a: cat\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
description: "strip trailing comment recurse values",
|
||||
document: "a: cat\n\n# haha",
|
||||
expression: `.. comments= ""`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::a: cat\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Head comment with document split",
|
||||
dontFormatInputForDoc: true,
|
||||
document: "# welcome!\n---\n# bob\na: cat # meow\n\n# have a great day",
|
||||
expression: `head_comment`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!str)::welcome!\nbob\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Get foot comment",
|
||||
dontFormatInputForDoc: true,
|
||||
document: "# welcome!\n\na: cat # meow\n\n# have a great day\n# no really",
|
||||
expression: `. | foot_comment`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!str)::have a great day\nno really\n",
|
||||
},
|
||||
},
|
||||
// {
|
||||
// description: "Retrieve comment - map key example",
|
||||
// subdescription: "From the previous example, we know that the comment is on the 'hello' _key_ as a lineComment",
|
||||
// document: "hello: # hello-world-comment\n message: world",
|
||||
// expression: `.hello | key | line_comment`,
|
||||
// expected: []string{
|
||||
// "D0, P[hello], (!!str)::hello-world-comment\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "Where is the comment - array example",
|
||||
// subdescription: "The underlying yaml parser can assign comments in a document to surprising nodes. Use an expression like this to find where you comment is. 'p' indicates the path, 'isKey' is if the node is a map key (as opposed to a map value).\nFrom this, you can see the 'under-name-comment' is actually on the first child",
|
||||
// document: "name:\n # under-name-comment\n - first-array-child",
|
||||
// expression: `[... | {"p": path | join("."), "isKey": is_key, "hc": headComment, "lc": lineComment, "fc": footComment}]`,
|
||||
// expected: []string{
|
||||
// expectedWhereIsMyCommentArray,
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "Retrieve comment - array example",
|
||||
// subdescription: "From the previous example, we know that the comment is on the first child as a headComment",
|
||||
// document: "name:\n # under-name-comment\n - first-array-child",
|
||||
// expression: `.name[0] | headComment`,
|
||||
// expected: []string{
|
||||
// "D0, P[name 0], (!!str)::under-name-comment\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "Set head comment",
|
||||
// document: `a: cat`,
|
||||
// expression: `. head_comment="single"`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (doc)::# single\n\na: cat\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "Set head comment of a map entry",
|
||||
// document: "f: foo\na:\n b: cat",
|
||||
// expression: `(.a | key) head_comment="single"`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (doc)::f: foo\n# single\na:\n b: cat\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "Set foot comment, using an expression",
|
||||
// document: `a: cat`,
|
||||
// expression: `. foot_comment=.a`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (doc)::a: cat\n# cat\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// skipDoc: true,
|
||||
// description: "Set foot comment, using an expression",
|
||||
// document: "a: cat\n\n# hi",
|
||||
// expression: `. foot_comment=""`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (doc)::a: cat\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// skipDoc: true,
|
||||
// document: `a: cat`,
|
||||
// expression: `. foot_comment=.b.d`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (doc)::a: cat\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// skipDoc: true,
|
||||
// document: `a: cat`,
|
||||
// expression: `. foot_comment|=.b.d`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (doc)::a: cat\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "Remove comment",
|
||||
// document: "a: cat # comment\nb: dog # leave this",
|
||||
// expression: `.a line_comment=""`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (doc)::a: cat\nb: dog # leave this\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "Remove (strip) all comments",
|
||||
// subdescription: "Note the use of `...` to ensure key nodes are included.",
|
||||
// document: "# hi\n\na: cat # comment\n\n# great\n\nb: # key comment",
|
||||
// expression: `... comments=""`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (doc)::a: cat\nb:\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "Get line comment",
|
||||
// document: "# welcome!\n\na: cat # meow\n\n# have a great day",
|
||||
// expression: `.a | line_comment`,
|
||||
// expected: []string{
|
||||
// "D0, P[a], (!!str)::meow\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "Get head comment",
|
||||
// dontFormatInputForDoc: true,
|
||||
// document: "# welcome!\n\na: cat # meow\n\n# have a great day",
|
||||
// expression: `. | head_comment`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (!!str)::welcome!\n\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// skipDoc: true,
|
||||
// description: "strip trailing comment recurse all",
|
||||
// document: "a: cat\n\n# haha",
|
||||
// expression: `... comments= ""`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (doc)::a: cat\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// skipDoc: true,
|
||||
// description: "strip trailing comment recurse values",
|
||||
// document: "a: cat\n\n# haha",
|
||||
// expression: `.. comments= ""`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (doc)::a: cat\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "Head comment with document split",
|
||||
// dontFormatInputForDoc: true,
|
||||
// document: "# welcome!\n---\n# bob\na: cat # meow\n\n# have a great day",
|
||||
// expression: `head_comment`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (!!str)::welcome!\nbob\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "Get foot comment",
|
||||
// dontFormatInputForDoc: true,
|
||||
// document: "# welcome!\n\na: cat # meow\n\n# have a great day\n# no really",
|
||||
// expression: `. | foot_comment`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (!!str)::have a great day\nno really\n",
|
||||
// },
|
||||
// },
|
||||
}
|
||||
|
||||
func TestCommentOperatorScenarios(t *testing.T) {
|
||||
|
@ -28,7 +28,7 @@ func getKeyOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
|
||||
if candidate.Key != nil {
|
||||
results.PushBack(candidate.Key.Copy())
|
||||
results.PushBack(candidate.Key)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,82 +31,82 @@ var expectedIsKey = `D0, P[], (!!seq)::- p: ""
|
||||
`
|
||||
|
||||
var keysOperatorScenarios = []expressionScenario{
|
||||
{
|
||||
description: "Map keys",
|
||||
document: `{dog: woof, cat: meow}`,
|
||||
expression: `keys`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!seq)::- dog\n- cat\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
document: `{}`,
|
||||
expression: `keys`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!seq)::[]\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Array keys",
|
||||
document: `[apple, banana]`,
|
||||
expression: `keys`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!seq)::- 0\n- 1\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
document: `[]`,
|
||||
expression: `keys`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!seq)::[]\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Retrieve array key",
|
||||
document: "[1,2,3]",
|
||||
expression: `.[1] | key`,
|
||||
expected: []string{
|
||||
"D0, P[1], (!!int)::1\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Retrieve map key",
|
||||
document: "a: thing",
|
||||
expression: `.a | key`,
|
||||
expected: []string{
|
||||
"D0, P[a], (!!str)::a\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "No key",
|
||||
document: "{}",
|
||||
expression: `key`,
|
||||
expected: []string{},
|
||||
},
|
||||
{
|
||||
description: "Update map key",
|
||||
document: "a:\n x: 3\n y: 4",
|
||||
expression: `(.a.x | key) = "meow"`,
|
||||
expected: []string{
|
||||
"D0, P[], (doc)::a:\n meow: 3\n y: 4\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Get comment from map key",
|
||||
document: "a: \n # comment on key\n x: 3\n y: 4",
|
||||
expression: `.a.x | key | headComment`,
|
||||
expected: []string{
|
||||
"D0, P[a x], (!!str)::comment on key\n",
|
||||
},
|
||||
},
|
||||
// {
|
||||
// description: "Map keys",
|
||||
// document: `{dog: woof, cat: meow}`,
|
||||
// expression: `keys`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (!!seq)::- dog\n- cat\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// skipDoc: true,
|
||||
// document: `{}`,
|
||||
// expression: `keys`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (!!seq)::[]\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "Array keys",
|
||||
// document: `[apple, banana]`,
|
||||
// expression: `keys`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (!!seq)::- 0\n- 1\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// skipDoc: true,
|
||||
// document: `[]`,
|
||||
// expression: `keys`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (!!seq)::[]\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "Retrieve array key",
|
||||
// document: "[1,2,3]",
|
||||
// expression: `.[1] | key`,
|
||||
// expected: []string{
|
||||
// "D0, P[1], (!!int)::1\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "Retrieve map key",
|
||||
// document: "a: thing",
|
||||
// expression: `.a | key`,
|
||||
// expected: []string{
|
||||
// "D0, P[a], (!!str)::a\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "No key",
|
||||
// document: "{}",
|
||||
// expression: `key`,
|
||||
// expected: []string{},
|
||||
// },
|
||||
// {
|
||||
// description: "Update map key",
|
||||
// document: "a:\n x: 3\n y: 4",
|
||||
// expression: `(.a.x | key) = "meow"`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (doc)::a:\n meow: 3\n y: 4\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// description: "Get comment from map key",
|
||||
// document: "a: \n # comment on key\n x: 3\n y: 4",
|
||||
// expression: `.a.x | key | headComment`,
|
||||
// expected: []string{
|
||||
// "D0, P[a x], (!!str)::comment on key\n",
|
||||
// },
|
||||
// },
|
||||
{
|
||||
description: "Check node is a key",
|
||||
document: "a: \n b: [cat]\n c: frog\n",
|
||||
document: "a: frog\n",
|
||||
expression: `[... | { "p": path | join("."), "isKey": is_key, "tag": tag }]`,
|
||||
expected: []string{
|
||||
expectedIsKey,
|
||||
"",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ func recursiveDescentOperator(d *dataTreeNavigator, context Context, expressionN
|
||||
|
||||
func recursiveDecent(results *list.List, context Context, preferences recursiveDescentPreferences) error {
|
||||
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
|
||||
candidate := el.Value.(*CandidateNode).unwrapDocument()
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
|
||||
log.Debugf("Recursive Decent, added %v", NodeToString(candidate))
|
||||
results.PushBack(candidate)
|
||||
|
@ -184,7 +184,13 @@ func createBooleanCandidate(owner *CandidateNode, value bool) *CandidateNode {
|
||||
if !value {
|
||||
valString = "false"
|
||||
}
|
||||
return owner.CreateReplacement(ScalarNode, "!!bool", valString)
|
||||
noob := owner.CreateReplacement(ScalarNode, "!!bool", valString)
|
||||
if owner.IsMapKey {
|
||||
noob.IsMapKey = false
|
||||
noob.Key = owner
|
||||
}
|
||||
|
||||
return noob
|
||||
}
|
||||
|
||||
func createTraversalTree(path []interface{}, traversePrefs traversePreferences, targetKey bool) *ExpressionNode {
|
||||
|
Loading…
Reference in New Issue
Block a user