mirror of
https://github.com/mikefarah/yq.git
synced 2024-12-19 20:19:04 +00:00
Adding to array copies styling of previous elements #722
This commit is contained in:
parent
992fe066aa
commit
d00153de71
@ -9,29 +9,6 @@ Add behaves differently according to the type of the LHS:
|
|||||||
Use `+=` as a relative append assign for things like increment. Note that `.a += .x` is equivalent to running `.a = .a + .x`.
|
Use `+=` as a relative append assign for things like increment. Note that `.a += .x` is equivalent to running `.a = .a + .x`.
|
||||||
|
|
||||||
|
|
||||||
## Concatenate and assign arrays
|
|
||||||
Given a sample.yml file of:
|
|
||||||
```yaml
|
|
||||||
a:
|
|
||||||
val: thing
|
|
||||||
b:
|
|
||||||
- cat
|
|
||||||
- dog
|
|
||||||
```
|
|
||||||
then
|
|
||||||
```bash
|
|
||||||
yq '.a.b += ["cow"]' sample.yml
|
|
||||||
```
|
|
||||||
will output
|
|
||||||
```yaml
|
|
||||||
a:
|
|
||||||
val: thing
|
|
||||||
b:
|
|
||||||
- cat
|
|
||||||
- dog
|
|
||||||
- cow
|
|
||||||
```
|
|
||||||
|
|
||||||
## Concatenate arrays
|
## Concatenate arrays
|
||||||
Given a sample.yml file of:
|
Given a sample.yml file of:
|
||||||
```yaml
|
```yaml
|
||||||
@ -54,6 +31,28 @@ will output
|
|||||||
- 4
|
- 4
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Concatenate to existing array
|
||||||
|
Note that the styling of `a` is kept.
|
||||||
|
|
||||||
|
Given a sample.yml file of:
|
||||||
|
```yaml
|
||||||
|
a: [1,2]
|
||||||
|
b:
|
||||||
|
- 3
|
||||||
|
- 4
|
||||||
|
```
|
||||||
|
then
|
||||||
|
```bash
|
||||||
|
yq '.a += .b' sample.yml
|
||||||
|
```
|
||||||
|
will output
|
||||||
|
```yaml
|
||||||
|
a: [1, 2, 3, 4]
|
||||||
|
b:
|
||||||
|
- 3
|
||||||
|
- 4
|
||||||
|
```
|
||||||
|
|
||||||
## Concatenate null to array
|
## Concatenate null to array
|
||||||
Given a sample.yml file of:
|
Given a sample.yml file of:
|
||||||
```yaml
|
```yaml
|
||||||
@ -71,6 +70,22 @@ will output
|
|||||||
- 2
|
- 2
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Append to existing array
|
||||||
|
Note that the styling is copied from existing array elements
|
||||||
|
|
||||||
|
Given a sample.yml file of:
|
||||||
|
```yaml
|
||||||
|
a: ['dog']
|
||||||
|
```
|
||||||
|
then
|
||||||
|
```bash
|
||||||
|
yq '.a += "cat"' sample.yml
|
||||||
|
```
|
||||||
|
will output
|
||||||
|
```yaml
|
||||||
|
a: ['dog', 'cat']
|
||||||
|
```
|
||||||
|
|
||||||
## Add new object to array
|
## Add new object to array
|
||||||
Given a sample.yml file of:
|
Given a sample.yml file of:
|
||||||
```yaml
|
```yaml
|
||||||
@ -87,76 +102,6 @@ will output
|
|||||||
- cat: meow
|
- cat: meow
|
||||||
```
|
```
|
||||||
|
|
||||||
## Add string to array
|
|
||||||
Given a sample.yml file of:
|
|
||||||
```yaml
|
|
||||||
a:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
```
|
|
||||||
then
|
|
||||||
```bash
|
|
||||||
yq '.a + "hello"' sample.yml
|
|
||||||
```
|
|
||||||
will output
|
|
||||||
```yaml
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- hello
|
|
||||||
```
|
|
||||||
|
|
||||||
## Append to array
|
|
||||||
Given a sample.yml file of:
|
|
||||||
```yaml
|
|
||||||
a:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
b:
|
|
||||||
- 3
|
|
||||||
- 4
|
|
||||||
```
|
|
||||||
then
|
|
||||||
```bash
|
|
||||||
yq '.a = .a + .b' sample.yml
|
|
||||||
```
|
|
||||||
will output
|
|
||||||
```yaml
|
|
||||||
a:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- 3
|
|
||||||
- 4
|
|
||||||
b:
|
|
||||||
- 3
|
|
||||||
- 4
|
|
||||||
```
|
|
||||||
|
|
||||||
## Append another array using +=
|
|
||||||
Given a sample.yml file of:
|
|
||||||
```yaml
|
|
||||||
a:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
b:
|
|
||||||
- 3
|
|
||||||
- 4
|
|
||||||
```
|
|
||||||
then
|
|
||||||
```bash
|
|
||||||
yq '.a += .b' sample.yml
|
|
||||||
```
|
|
||||||
will output
|
|
||||||
```yaml
|
|
||||||
a:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- 3
|
|
||||||
- 4
|
|
||||||
b:
|
|
||||||
- 3
|
|
||||||
- 4
|
|
||||||
```
|
|
||||||
|
|
||||||
## Relative append
|
## Relative append
|
||||||
Given a sample.yml file of:
|
Given a sample.yml file of:
|
||||||
```yaml
|
```yaml
|
||||||
@ -195,7 +140,7 @@ b: meow
|
|||||||
```
|
```
|
||||||
then
|
then
|
||||||
```bash
|
```bash
|
||||||
yq '.a = .a + .b' sample.yml
|
yq '.a += .b' sample.yml
|
||||||
```
|
```
|
||||||
will output
|
will output
|
||||||
```yaml
|
```yaml
|
||||||
|
@ -18,16 +18,23 @@ func addAssignOperator(d *dataTreeNavigator, context Context, expressionNode *Ex
|
|||||||
return compoundAssignFunction(d, context, expressionNode, createAddOp)
|
return compoundAssignFunction(d, context, expressionNode, createAddOp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func toNodes(candidate *CandidateNode) []*yaml.Node {
|
func toNodes(candidate *CandidateNode, lhs *CandidateNode) ([]*yaml.Node, error) {
|
||||||
if candidate.Node.Tag == "!!null" {
|
if candidate.Node.Tag == "!!null" {
|
||||||
return []*yaml.Node{}
|
return []*yaml.Node{}, nil
|
||||||
|
}
|
||||||
|
clone, err := candidate.Copy()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch candidate.Node.Kind {
|
switch candidate.Node.Kind {
|
||||||
case yaml.SequenceNode:
|
case yaml.SequenceNode:
|
||||||
return candidate.Node.Content
|
return clone.Node.Content, nil
|
||||||
default:
|
default:
|
||||||
return []*yaml.Node{candidate.Node}
|
if len(lhs.Node.Content) > 0 {
|
||||||
|
clone.Node.Style = lhs.Node.Content[0].Style
|
||||||
|
}
|
||||||
|
return []*yaml.Node{clone.Node}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -54,7 +61,10 @@ func add(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *Candida
|
|||||||
case yaml.MappingNode:
|
case yaml.MappingNode:
|
||||||
addMaps(target, lhs, rhs)
|
addMaps(target, lhs, rhs)
|
||||||
case yaml.SequenceNode:
|
case yaml.SequenceNode:
|
||||||
addSequences(target, lhs, rhs)
|
if err := addSequences(target, lhs, rhs); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
case yaml.ScalarNode:
|
case yaml.ScalarNode:
|
||||||
if rhs.Node.Kind != yaml.ScalarNode {
|
if rhs.Node.Kind != yaml.ScalarNode {
|
||||||
return nil, fmt.Errorf("%v (%v) cannot be added to a %v", rhs.Node.Tag, rhs.Path, lhsNode.Tag)
|
return nil, fmt.Errorf("%v (%v) cannot be added to a %v", rhs.Node.Tag, rhs.Path, lhsNode.Tag)
|
||||||
@ -139,7 +149,7 @@ func addScalars(target *CandidateNode, lhs *yaml.Node, rhs *yaml.Node) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func addSequences(target *CandidateNode, lhs *CandidateNode, rhs *CandidateNode) {
|
func addSequences(target *CandidateNode, lhs *CandidateNode, rhs *CandidateNode) error {
|
||||||
target.Node.Kind = yaml.SequenceNode
|
target.Node.Kind = yaml.SequenceNode
|
||||||
if len(lhs.Node.Content) > 0 {
|
if len(lhs.Node.Content) > 0 {
|
||||||
target.Node.Style = lhs.Node.Style
|
target.Node.Style = lhs.Node.Style
|
||||||
@ -147,7 +157,15 @@ func addSequences(target *CandidateNode, lhs *CandidateNode, rhs *CandidateNode)
|
|||||||
target.Node.Tag = lhs.Node.Tag
|
target.Node.Tag = lhs.Node.Tag
|
||||||
target.Node.Content = make([]*yaml.Node, len(lhs.Node.Content))
|
target.Node.Content = make([]*yaml.Node, len(lhs.Node.Content))
|
||||||
copy(target.Node.Content, lhs.Node.Content)
|
copy(target.Node.Content, lhs.Node.Content)
|
||||||
target.Node.Content = append(target.Node.Content, toNodes(rhs)...)
|
|
||||||
|
extraNodes, err := toNodes(rhs, lhs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
target.Node.Content = append(target.Node.Content, extraNodes...)
|
||||||
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func addMaps(target *CandidateNode, lhsC *CandidateNode, rhsC *CandidateNode) {
|
func addMaps(target *CandidateNode, lhsC *CandidateNode, rhsC *CandidateNode) {
|
||||||
|
@ -30,14 +30,7 @@ var addOperatorScenarios = []expressionScenario{
|
|||||||
"D0, P[], (doc)::a: 0\n",
|
"D0, P[], (doc)::a: 0\n",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
description: "Concatenate and assign arrays",
|
|
||||||
document: `{a: {val: thing, b: [cat,dog]}}`,
|
|
||||||
expression: ".a.b += [\"cow\"]",
|
|
||||||
expected: []string{
|
|
||||||
"D0, P[], (doc)::{a: {val: thing, b: [cat, dog, cow]}}\n",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
description: "Concatenate arrays",
|
description: "Concatenate arrays",
|
||||||
document: `{a: [1,2], b: [3,4]}`,
|
document: `{a: [1,2], b: [3,4]}`,
|
||||||
@ -46,6 +39,16 @@ var addOperatorScenarios = []expressionScenario{
|
|||||||
"D0, P[a], (!!seq)::[1, 2, 3, 4]\n",
|
"D0, P[a], (!!seq)::[1, 2, 3, 4]\n",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
description: "Concatenate to existing array",
|
||||||
|
subdescription: "Note that the styling of `a` is kept.",
|
||||||
|
document: "a: [1,2]\nb:\n - 3\n - 4",
|
||||||
|
dontFormatInputForDoc: true,
|
||||||
|
expression: `.a += .b`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[], (doc)::a: [1, 2, 3, 4]\nb:\n - 3\n - 4\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
skipDoc: true,
|
skipDoc: true,
|
||||||
expression: `[1] + ([2], [3])`,
|
expression: `[1] + ([2], [3])`,
|
||||||
@ -72,12 +75,23 @@ var addOperatorScenarios = []expressionScenario{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
skipDoc: true,
|
description: "Append to existing array",
|
||||||
description: "Concatenate to existing array",
|
subdescription: "Note that the styling is copied from existing array elements",
|
||||||
document: `{a: [dog]}`,
|
dontFormatInputForDoc: true,
|
||||||
expression: `.a + "cat"`,
|
document: `a: ['dog']`,
|
||||||
|
expression: `.a += "cat"`,
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"D0, P[a], (!!seq)::[dog, cat]\n",
|
"D0, P[], (doc)::a: ['dog', 'cat']\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
description: "Concatenate to existing array",
|
||||||
|
subdescription: "does not modify original",
|
||||||
|
document: `{a: ['dog'], b: cat}`,
|
||||||
|
expression: `.a = .a + .b`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[], (doc)::{a: ['dog', 'cat'], b: cat}\n",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -116,6 +130,16 @@ var addOperatorScenarios = []expressionScenario{
|
|||||||
"D0, P[a], (!!map)::{c: dog, b: cat}\n",
|
"D0, P[a], (!!map)::{c: dog, b: cat}\n",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
description: "Concatenate to existing object",
|
||||||
|
subdescription: "matches stylig",
|
||||||
|
document: "a:\n c: dog",
|
||||||
|
expression: `.a + {"b": "cat"}`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[a], (!!map)::c: dog\nb: cat\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
skipDoc: true,
|
skipDoc: true,
|
||||||
description: "Concatenate to empty object in place",
|
description: "Concatenate to empty object in place",
|
||||||
@ -142,30 +166,6 @@ var addOperatorScenarios = []expressionScenario{
|
|||||||
"D0, P[a], (!!seq)::[{dog: woof}, {cat: meow}]\n",
|
"D0, P[a], (!!seq)::[{dog: woof}, {cat: meow}]\n",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
description: "Add string to array",
|
|
||||||
document: `{a: [1,2]}`,
|
|
||||||
expression: `.a + "hello"`,
|
|
||||||
expected: []string{
|
|
||||||
"D0, P[a], (!!seq)::[1, 2, hello]\n",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "Append to array",
|
|
||||||
document: `{a: [1,2], b: [3,4]}`,
|
|
||||||
expression: `.a = .a + .b`,
|
|
||||||
expected: []string{
|
|
||||||
"D0, P[], (doc)::{a: [1, 2, 3, 4], b: [3, 4]}\n",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "Append another array using +=",
|
|
||||||
document: `{a: [1,2], b: [3,4]}`,
|
|
||||||
expression: `.a += .b`,
|
|
||||||
expected: []string{
|
|
||||||
"D0, P[], (doc)::{a: [1, 2, 3, 4], b: [3, 4]}\n",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
description: "Relative append",
|
description: "Relative append",
|
||||||
document: `a: { a1: {b: [cat]}, a2: {b: [dog]}, a3: {} }`,
|
document: `a: { a1: {b: [cat]}, a2: {b: [dog]}, a3: {} }`,
|
||||||
@ -177,7 +177,7 @@ var addOperatorScenarios = []expressionScenario{
|
|||||||
{
|
{
|
||||||
description: "String concatenation",
|
description: "String concatenation",
|
||||||
document: `{a: cat, b: meow}`,
|
document: `{a: cat, b: meow}`,
|
||||||
expression: `.a = .a + .b`,
|
expression: `.a += .b`,
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"D0, P[], (doc)::{a: catmeow, b: meow}\n",
|
"D0, P[], (doc)::{a: catmeow, b: meow}\n",
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user