mirror of
https://github.com/mikefarah/yq.git
synced 2024-12-19 20:19:04 +00:00
Feature: Add append to array
Adds the ability to append a value to an array instead of having to know the index of the values within the array. Resolves: #17
This commit is contained in:
parent
c17f8df8f8
commit
c5f80a105d
@ -435,6 +435,25 @@ func TestWriteCmd_Inplace(t *testing.T) {
|
|||||||
assertResult(t, expectedOutput, gotOutput)
|
assertResult(t, expectedOutput, gotOutput)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWriteCmd_Append(t *testing.T) {
|
||||||
|
content := `b:
|
||||||
|
- foo
|
||||||
|
`
|
||||||
|
filename := writeTempYamlFile(content)
|
||||||
|
defer removeTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := runCmd(cmd, fmt.Sprintf("write %s b[+] 7", filename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `b:
|
||||||
|
- foo
|
||||||
|
- 7
|
||||||
|
`
|
||||||
|
assertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
func TestMergeCmd(t *testing.T) {
|
func TestMergeCmd(t *testing.T) {
|
||||||
cmd := getRootCommand()
|
cmd := getRootCommand()
|
||||||
result := runCmd(cmd, "merge examples/data1.yaml examples/data2.yaml")
|
result := runCmd(cmd, "merge examples/data1.yaml examples/data2.yaml")
|
||||||
|
@ -55,7 +55,7 @@ func updatedChildValue(child interface{}, remainingPaths []string, value interfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
_, nextIndexErr := strconv.ParseInt(remainingPaths[0], 10, 64)
|
_, nextIndexErr := strconv.ParseInt(remainingPaths[0], 10, 64)
|
||||||
if nextIndexErr != nil {
|
if nextIndexErr != nil && remainingPaths[0] != "+" {
|
||||||
// must be a map
|
// must be a map
|
||||||
return writeMap(child, remainingPaths, value)
|
return writeMap(child, remainingPaths, value)
|
||||||
}
|
}
|
||||||
@ -81,7 +81,13 @@ func writeArray(context interface{}, paths []string, value interface{}) []interf
|
|||||||
log.Debugf("\tarray %v\n", array)
|
log.Debugf("\tarray %v\n", array)
|
||||||
|
|
||||||
rawIndex := paths[0]
|
rawIndex := paths[0]
|
||||||
index, _ := strconv.ParseInt(rawIndex, 10, 64)
|
var index int64
|
||||||
|
// the append array indicator
|
||||||
|
if rawIndex == "+" {
|
||||||
|
index = int64(len(array))
|
||||||
|
} else {
|
||||||
|
index, _ = strconv.ParseInt(rawIndex, 10, 64)
|
||||||
|
}
|
||||||
// writeArray is only called by updatedChildValue which handles parsing the
|
// writeArray is only called by updatedChildValue which handles parsing the
|
||||||
// index, as such this renders this dead code.
|
// index, as such this renders this dead code.
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"location": "/write/",
|
"location": "/write/",
|
||||||
"text": "yaml w \nyaml_file|json_file\n \npath\n \nnew value\n\n\n\n\n\nThis command can take a json file as input too, and will output yaml unless specified to export as json (-j)\n\n\nTo Stdout\n\n\nGiven a sample.yaml file of:\n\n\nb:\n c: 2\n\n\n\n\nthen\n\n\nyaml w sample.yaml b.c cat\n\n\n\n\nwill output:\n\n\nb:\n c: cat\n\n\n\n\nFrom STDIN\n\n\ncat sample.yaml | yaml w - b.c blah\n\n\n\n\nAdding new fields\n\n\nAny missing fields in the path will be created on the fly.\n\n\nGiven a sample.yaml file of:\n\n\nb:\n c: 2\n\n\n\n\nthen\n\n\nyaml w sample.yaml b.d[0] \nnew thing\n\n\n\n\n\nwill output:\n\n\nb:\n c: cat\n d:\n - new thing\n\n\n\n\nUpdating files in-place\n\n\nGiven a sample.yaml file of:\n\n\nb:\n c: 2\n\n\n\n\nthen\n\n\nyaml w -i sample.yaml b.c cat\n\n\n\n\nwill update the sample.yaml file so that the value of 'c' is cat.\n\n\nUpdating multiple values with a script\n\n\nGiven a sample.yaml file of:\n\n\nb:\n c: 2\n e:\n - name: Billy Bob\n\n\n\n\nand a script update_instructions.yaml of:\n\n\nb.c: 3\nb.e[0].name: Howdy Partner\n\n\n\n\nthen\n\n\nyaml w -s update_instructions.yaml sample.yaml\n\n\n\n\nwill output:\n\n\nb:\n c: 3\n e:\n - name: Howdy Partner\n\n\n\n\nAnd, of course, you can pipe the instructions in using '-':\n\n\ncat update_instructions.yaml | yaml w -s - sample.yaml\n\n\n\n\nValues starting with a hyphen (or dash)\n\n\nThe flag terminator needs to be used to stop the app from attempting to parse the subsequent arguments as flags:\n\n\nyaml w -- my.path -3\n\n\n\n\nwill output\n\n\nmy:\n path: -3",
|
"text": "yaml w \nyaml_file|json_file\n \npath\n \nnew value\n\n\n\n\n\nThis command can take a json file as input too, and will output yaml unless specified to export as json (-j)\n\n\nTo Stdout\n\n\nGiven a sample.yaml file of:\n\n\nb:\n c: 2\n\n\n\n\nthen\n\n\nyaml w sample.yaml b.c cat\n\n\n\n\nwill output:\n\n\nb:\n c: cat\n\n\n\n\nFrom STDIN\n\n\ncat sample.yaml | yaml w - b.c blah\n\n\n\n\nAdding new fields\n\n\nAny missing fields in the path will be created on the fly.\n\n\nGiven a sample.yaml file of:\n\n\nb:\n c: 2\n\n\n\n\nthen\n\n\nyaml w sample.yaml b.d[0] \nnew thing\n\n\n\n\n\nwill output:\n\n\nb:\n c: cat\n d:\n - new thing\n\n\n\n\nAppending value to an array field\n\n\nGiven a sample.yaml file of:\n\n\nb:\n c: 2\n d:\n - new thing\n - foo thing\n\n\n\n\nthen\n\n\nyaml w sample.yaml b.d[+] \nbar thing\n\n\n\n\n\nwill output:\n\n\nb:\n c: cat\n d:\n - new thing\n - foo thing\n - bar thing\n\n\n\n\nUpdating files in-place\n\n\nGiven a sample.yaml file of:\n\n\nb:\n c: 2\n\n\n\n\nthen\n\n\nyaml w -i sample.yaml b.c cat\n\n\n\n\nwill update the sample.yaml file so that the value of 'c' is cat.\n\n\nUpdating multiple values with a script\n\n\nGiven a sample.yaml file of:\n\n\nb:\n c: 2\n e:\n - name: Billy Bob\n\n\n\n\nand a script update_instructions.yaml of:\n\n\nb.c: 3\nb.e[0].name: Howdy Partner\n\n\n\n\nthen\n\n\nyaml w -s update_instructions.yaml sample.yaml\n\n\n\n\nwill output:\n\n\nb:\n c: 3\n e:\n - name: Howdy Partner\n\n\n\n\nAnd, of course, you can pipe the instructions in using '-':\n\n\ncat update_instructions.yaml | yaml w -s - sample.yaml\n\n\n\n\nValues starting with a hyphen (or dash)\n\n\nThe flag terminator needs to be used to stop the app from attempting to parse the subsequent arguments as flags:\n\n\nyaml w -- my.path -3\n\n\n\n\nwill output\n\n\nmy:\n path: -3",
|
||||||
"title": "Write/Update"
|
"title": "Write/Update"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -75,6 +75,11 @@
|
|||||||
"text": "Any missing fields in the path will be created on the fly. Given a sample.yaml file of: b:\n c: 2 then yaml w sample.yaml b.d[0] new thing will output: b:\n c: cat\n d:\n - new thing",
|
"text": "Any missing fields in the path will be created on the fly. Given a sample.yaml file of: b:\n c: 2 then yaml w sample.yaml b.d[0] new thing will output: b:\n c: cat\n d:\n - new thing",
|
||||||
"title": "Adding new fields"
|
"title": "Adding new fields"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"location": "/write/#appending-value-to-an-array-field",
|
||||||
|
"text": "Given a sample.yaml file of: b:\n c: 2\n d:\n - new thing\n - foo thing then yaml w sample.yaml b.d[+] bar thing will output: b:\n c: cat\n d:\n - new thing\n - foo thing\n - bar thing",
|
||||||
|
"title": "Appending value to an array field"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"location": "/write/#updating-files-in-place",
|
"location": "/write/#updating-files-in-place",
|
||||||
"text": "Given a sample.yaml file of: b:\n c: 2 then yaml w -i sample.yaml b.c cat will update the sample.yaml file so that the value of 'c' is cat.",
|
"text": "Given a sample.yaml file of: b:\n c: 2 then yaml w -i sample.yaml b.c cat will update the sample.yaml file so that the value of 'c' is cat.",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<url>
|
<url>
|
||||||
<loc>/</loc>
|
<loc>/</loc>
|
||||||
<lastmod>2017-09-23</lastmod>
|
<lastmod>2017-09-24</lastmod>
|
||||||
<changefreq>daily</changefreq>
|
<changefreq>daily</changefreq>
|
||||||
</url>
|
</url>
|
||||||
|
|
||||||
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
<url>
|
<url>
|
||||||
<loc>/read/</loc>
|
<loc>/read/</loc>
|
||||||
<lastmod>2017-09-23</lastmod>
|
<lastmod>2017-09-24</lastmod>
|
||||||
<changefreq>daily</changefreq>
|
<changefreq>daily</changefreq>
|
||||||
</url>
|
</url>
|
||||||
|
|
||||||
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
<url>
|
<url>
|
||||||
<loc>/write/</loc>
|
<loc>/write/</loc>
|
||||||
<lastmod>2017-09-23</lastmod>
|
<lastmod>2017-09-24</lastmod>
|
||||||
<changefreq>daily</changefreq>
|
<changefreq>daily</changefreq>
|
||||||
</url>
|
</url>
|
||||||
|
|
||||||
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
<url>
|
<url>
|
||||||
<loc>/create/</loc>
|
<loc>/create/</loc>
|
||||||
<lastmod>2017-09-23</lastmod>
|
<lastmod>2017-09-24</lastmod>
|
||||||
<changefreq>daily</changefreq>
|
<changefreq>daily</changefreq>
|
||||||
</url>
|
</url>
|
||||||
|
|
||||||
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
<url>
|
<url>
|
||||||
<loc>/convert/</loc>
|
<loc>/convert/</loc>
|
||||||
<lastmod>2017-09-23</lastmod>
|
<lastmod>2017-09-24</lastmod>
|
||||||
<changefreq>daily</changefreq>
|
<changefreq>daily</changefreq>
|
||||||
</url>
|
</url>
|
||||||
|
|
||||||
@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
<url>
|
<url>
|
||||||
<loc>/merge/</loc>
|
<loc>/merge/</loc>
|
||||||
<lastmod>2017-09-23</lastmod>
|
<lastmod>2017-09-24</lastmod>
|
||||||
<changefreq>daily</changefreq>
|
<changefreq>daily</changefreq>
|
||||||
</url>
|
</url>
|
||||||
|
|
||||||
|
@ -250,6 +250,13 @@
|
|||||||
Adding new fields
|
Adding new fields
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="md-nav__item">
|
||||||
|
<a href="#appending-value-to-an-array-field" title="Appending value to an array field" class="md-nav__link">
|
||||||
|
Appending value to an array field
|
||||||
|
</a>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="md-nav__item">
|
<li class="md-nav__item">
|
||||||
@ -355,6 +362,13 @@
|
|||||||
Adding new fields
|
Adding new fields
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="md-nav__item">
|
||||||
|
<a href="#appending-value-to-an-array-field" title="Appending value to an array field" class="md-nav__link">
|
||||||
|
Appending value to an array field
|
||||||
|
</a>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="md-nav__item">
|
<li class="md-nav__item">
|
||||||
@ -436,6 +450,28 @@
|
|||||||
- new thing
|
- new thing
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
|
<h3 id="appending-value-to-an-array-field">Appending value to an array field<a class="headerlink" href="#appending-value-to-an-array-field" title="Permanent link">¶</a></h3>
|
||||||
|
<p>Given a sample.yaml file of:</p>
|
||||||
|
<pre><code class="yaml">b:
|
||||||
|
c: 2
|
||||||
|
d:
|
||||||
|
- new thing
|
||||||
|
- foo thing
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>then</p>
|
||||||
|
<pre><code class="bash">yaml w sample.yaml b.d[+] "bar thing"
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>will output:</p>
|
||||||
|
<pre><code class="yaml">b:
|
||||||
|
c: cat
|
||||||
|
d:
|
||||||
|
- new thing
|
||||||
|
- foo thing
|
||||||
|
- bar thing
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
<h3 id="updating-files-in-place">Updating files in-place<a class="headerlink" href="#updating-files-in-place" title="Permanent link">¶</a></h3>
|
<h3 id="updating-files-in-place">Updating files in-place<a class="headerlink" href="#updating-files-in-place" title="Permanent link">¶</a></h3>
|
||||||
<p>Given a sample.yaml file of:</p>
|
<p>Given a sample.yaml file of:</p>
|
||||||
<pre><code class="yaml">b:
|
<pre><code class="yaml">b:
|
||||||
|
@ -44,6 +44,29 @@ b:
|
|||||||
- new thing
|
- new thing
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Appending value to an array field
|
||||||
|
Given a sample.yaml file of:
|
||||||
|
```yaml
|
||||||
|
b:
|
||||||
|
c: 2
|
||||||
|
d:
|
||||||
|
- new thing
|
||||||
|
- foo thing
|
||||||
|
```
|
||||||
|
then
|
||||||
|
```bash
|
||||||
|
yaml w sample.yaml b.d[+] "bar thing"
|
||||||
|
```
|
||||||
|
will output:
|
||||||
|
```yaml
|
||||||
|
b:
|
||||||
|
c: cat
|
||||||
|
d:
|
||||||
|
- new thing
|
||||||
|
- foo thing
|
||||||
|
- bar thing
|
||||||
|
```
|
||||||
|
|
||||||
### Updating files in-place
|
### Updating files in-place
|
||||||
Given a sample.yaml file of:
|
Given a sample.yaml file of:
|
||||||
```yaml
|
```yaml
|
||||||
|
@ -10,6 +10,7 @@ var parsePathsTests = []struct {
|
|||||||
}{
|
}{
|
||||||
{"a.b", []string{"a", "b"}},
|
{"a.b", []string{"a", "b"}},
|
||||||
{"a.b[0]", []string{"a", "b", "0"}},
|
{"a.b[0]", []string{"a", "b", "0"}},
|
||||||
|
{"a.b.d[+]", []string{"a", "b", "d", "+"}},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParsePath(t *testing.T) {
|
func TestParsePath(t *testing.T) {
|
||||||
|
4
yaml.go
4
yaml.go
@ -98,10 +98,14 @@ yaml write --inplace things.yaml a.b.c cat
|
|||||||
yaml w -i things.yaml a.b.c cat
|
yaml w -i things.yaml a.b.c cat
|
||||||
yaml w --script update_script.yaml things.yaml
|
yaml w --script update_script.yaml things.yaml
|
||||||
yaml w -i -s update_script.yaml things.yaml
|
yaml w -i -s update_script.yaml things.yaml
|
||||||
|
yaml w things.yaml a.b.d[+] foo
|
||||||
|
yaml w things.yaml a.b.d[+] foo
|
||||||
`,
|
`,
|
||||||
Long: `Updates the yaml file w.r.t the given path and value.
|
Long: `Updates the yaml file w.r.t the given path and value.
|
||||||
Outputs to STDOUT unless the inplace flag is used, in which case the file is updated instead.
|
Outputs to STDOUT unless the inplace flag is used, in which case the file is updated instead.
|
||||||
|
|
||||||
|
Append value to array adds the value to the end of array.
|
||||||
|
|
||||||
Update Scripts:
|
Update Scripts:
|
||||||
Note that you can give an update script to perform more sophisticated updated. Update script
|
Note that you can give an update script to perform more sophisticated updated. Update script
|
||||||
format is a yaml map where the key is the path and the value is..well the value. e.g.:
|
format is a yaml map where the key is the path and the value is..well the value. e.g.:
|
||||||
|
Loading…
Reference in New Issue
Block a user