1
0
mirror of https://github.com/taigrr/yq synced 2025-01-18 04:53:17 -08:00

Compare commits

...

4 Commits

Author SHA1 Message Date
Mike Farah
2f9f8665dd bolden contribute disclaimer 2020-01-13 10:21:28 +11:00
Conor Nosal
3dea1efc03 Allow merge commands to specify overwrite and append simultaneously 2020-01-13 10:17:29 +11:00
Ryan SIU
547787f3ae #314 Fix the big int changing into float 2020-01-13 10:17:08 +11:00
Ryan SIU
3e83ff7ac8 #20 Read the top level keys only 2020-01-13 10:16:53 +11:00
9 changed files with 105 additions and 10 deletions

View File

@@ -130,7 +130,7 @@ Use "yq [command] --help" for more information about a command.
## Contribute ## Contribute
Note: v3 is currently in progress - for the moment I won't be accepting new feature PRs until v3 is ready :) **Note: v3 is currently in progress - for the moment I won't be accepting new feature PRs until v3 is ready :)**
1. `scripts/devtools.sh` 1. `scripts/devtools.sh`
2. `make [local] vendor` 2. `make [local] vendor`

View File

@@ -1091,6 +1091,25 @@ c:
` `
test.AssertResult(t, expectedOutput, result.Output) test.AssertResult(t, expectedOutput, result.Output)
} }
func TestMergeOverwriteAndAppendCmd(t *testing.T) {
cmd := getRootCommand()
result := test.RunCmd(cmd, "merge --append --overwrite examples/data1.yaml examples/data2.yaml")
if result.Error != nil {
t.Error(result.Error)
}
expectedOutput := `a: other
b:
- 1
- 2
- 3
- 4
c:
test: 1
`
test.AssertResult(t, expectedOutput, result.Output)
}
func TestMergeArraysCmd(t *testing.T) { func TestMergeArraysCmd(t *testing.T) {
cmd := getRootCommand() cmd := getRootCommand()
result := test.RunCmd(cmd, "merge --append examples/sample_array.yaml examples/sample_array_2.yaml") result := test.RunCmd(cmd, "merge --append examples/sample_array.yaml examples/sample_array_2.yaml")

View File

@@ -58,11 +58,13 @@ func (l *lib) DeletePath(dataBucket interface{}, path string) (interface{}, erro
return l.navigator.DeleteChildValue(dataBucket, paths) return l.navigator.DeleteChildValue(dataBucket, paths)
} }
func (l *lib) Merge(dst interface{}, src interface{}, overwrite bool, append bool) error { func (l *lib) Merge(dst interface{}, src interface{}, overwriteFlag bool, appendFlag bool) error {
if overwrite { opts := []func(*mergo.Config){}
return mergo.Merge(dst, src, mergo.WithOverride) if overwriteFlag {
} else if append { opts = append(opts, mergo.WithOverride)
return mergo.Merge(dst, src, mergo.WithAppendSlice)
} }
return mergo.Merge(dst, src) if appendFlag {
opts = append(opts, mergo.WithAppendSlice)
}
return mergo.Merge(dst, src, opts...)
} }

View File

@@ -156,6 +156,23 @@ b: 2
test.AssertResult(t, `[{a b} {c d} {a 1} {b 2}]`, fmt.Sprintf("%v", mergedData["root"])) test.AssertResult(t, `[{a b} {c d} {a 1} {b 2}]`, fmt.Sprintf("%v", mergedData["root"]))
}) })
t.Run("TestMerge_WithAppendAndOverwrite", func(t *testing.T) {
var dst = map[interface{}]interface{}{
"a": "initial",
"b": []string{"old"},
}
var src = map[interface{}]interface{}{
"a": "replaced",
"b": []string{"new"},
}
err := subject.Merge(&dst, src, true, true)
if err != nil {
t.Fatal("Unexpected error")
}
test.AssertResult(t, `map[a:replaced b:[old new]]`, fmt.Sprintf("%v", dst))
})
t.Run("TestMerge_WithError", func(t *testing.T) { t.Run("TestMerge_WithError", func(t *testing.T) {
err := subject.Merge(nil, nil, false, false) err := subject.Merge(nil, nil, false, false)
if err == nil { if err == nil {

View File

@@ -18,9 +18,16 @@ func (v *valueParser) ParseValue(argument string) interface{} {
var value, err interface{} var value, err interface{}
var inQuotes = len(argument) > 0 && argument[0] == '"' var inQuotes = len(argument) > 0 && argument[0] == '"'
if !inQuotes { if !inQuotes {
value, err = strconv.ParseFloat(argument, 64) intValue, intErr := strconv.ParseInt(argument, 10, 64)
if err == nil { floatValue, floatErr := strconv.ParseFloat(argument, 64)
return value if intErr == nil && floatErr == nil {
if int64(floatValue) == intValue {
return intValue
}
return floatValue
} else if floatErr == nil {
// In case cannot parse the int due to large precision
return floatValue
} }
value, err = strconv.ParseBool(argument) value, err = strconv.ParseBool(argument)
if err == nil { if err == nil {

View File

@@ -16,6 +16,7 @@ var parseValueTests = []struct {
{"3.4", 3.4, "number"}, {"3.4", 3.4, "number"},
{"\"3.4\"", "3.4", "number as string"}, {"\"3.4\"", "3.4", "number as string"},
{"", "", "empty string"}, {"", "", "empty string"},
{"1212121", int64(1212121), "big number"},
} }
func TestParseValue(t *testing.T) { func TestParseValue(t *testing.T) {

View File

@@ -0,0 +1,6 @@
a:
b:
c: 1
d:
e: 2
f:

9
yq.go
View File

@@ -25,6 +25,7 @@ var writeInplace = false
var writeScript = "" var writeScript = ""
var outputToJSON = false var outputToJSON = false
var overwriteFlag = false var overwriteFlag = false
var keyOnlyFlag = false
var allowEmptyFlag = false var allowEmptyFlag = false
var appendFlag = false var appendFlag = false
var verbose = false var verbose = false
@@ -111,6 +112,7 @@ yq r -- things.yaml --key-starting-with-dashes
} }
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().BoolVarP(&outputToJSON, "tojson", "j", false, "output as json") cmdRead.PersistentFlags().BoolVarP(&outputToJSON, "tojson", "j", false, "output as json")
cmdRead.PersistentFlags().BoolVarP(&keyOnlyFlag, "keyonly", "k", false, "output with top level keys only")
return cmdRead return cmdRead
} }
@@ -304,6 +306,13 @@ func readProperty(cmd *cobra.Command, args []string) error {
dataBucket = mappedDocs dataBucket = mappedDocs
} }
if keyOnlyFlag {
for _, value := range dataBucket.(yaml.MapSlice) {
cmd.Println(value.Key)
}
return nil
}
dataStr, err := toString(dataBucket) dataStr, err := toString(dataBucket)
if err != nil { if err != nil {
return err return err

View File

@@ -1,12 +1,14 @@
package main package main
import ( import (
"bytes"
"fmt" "fmt"
"runtime" "runtime"
"testing" "testing"
"github.com/mikefarah/yq/v2/pkg/marshal" "github.com/mikefarah/yq/v2/pkg/marshal"
"github.com/mikefarah/yq/v2/test" "github.com/mikefarah/yq/v2/test"
"github.com/spf13/cobra"
) )
func TestMultilineString(t *testing.T) { func TestMultilineString(t *testing.T) {
@@ -33,6 +35,14 @@ func TestNewYamlArray(t *testing.T) {
formattedResult) formattedResult)
} }
func TestNewYamlBigInt(t *testing.T) {
result, _ := newYaml([]string{"b", "1212121"})
formattedResult := fmt.Sprintf("%v", result)
test.AssertResult(t,
"[{b 1212121}]",
formattedResult)
}
func TestNewYaml_WithScript(t *testing.T) { func TestNewYaml_WithScript(t *testing.T) {
writeScript = "examples/instruction_sample.yaml" writeScript = "examples/instruction_sample.yaml"
expectedResult := `b: expectedResult := `b:
@@ -58,3 +68,27 @@ func TestNewYaml_WithUnknownScript(t *testing.T) {
} }
test.AssertResult(t, expectedOutput, err.Error()) test.AssertResult(t, expectedOutput, err.Error())
} }
func TestReadWithKeyOnly(t *testing.T) {
readCmd := createReadCmd()
expectedResult := `b
d
f
`
actualResult, err := executeTestCommand(readCmd, "test/fixture/keyonly.yaml", "a", "-k")
if err != nil {
t.Error(err.Error())
}
test.AssertResult(t, expectedResult, actualResult)
}
func executeTestCommand(command *cobra.Command, args ...string) (output string, err error) {
buf := new(bytes.Buffer)
command.SetOutput(buf)
command.SetArgs(args)
_, err = command.ExecuteC()
return buf.String(), err
}