mirror of
https://github.com/taigrr/yq
synced 2025-01-18 04:53:17 -08:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b4972e46e | ||
|
|
23543ee031 | ||
|
|
75c7d40c44 | ||
|
|
44b8a5e80f | ||
|
|
77c8f22a79 | ||
|
|
386a0ca3c3 |
@@ -1,6 +1,6 @@
|
|||||||
language: go
|
language: go
|
||||||
go:
|
go:
|
||||||
- 1.9.x
|
- 1.11.x
|
||||||
script:
|
script:
|
||||||
- scripts/devtools.sh
|
- scripts/devtools.sh
|
||||||
- make local build
|
- make local build
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.9 as builder
|
FROM golang:1.11 as builder
|
||||||
|
|
||||||
WORKDIR /go/src/mikefarah/yq
|
WORKDIR /go/src/mikefarah/yq
|
||||||
|
|
||||||
|
|||||||
5
Makefile
5
Makefile
@@ -14,7 +14,6 @@ help:
|
|||||||
@echo ' make build Build yq binary.'
|
@echo ' make build Build yq binary.'
|
||||||
@echo ' make install Install yq.'
|
@echo ' make install Install yq.'
|
||||||
@echo ' make xcompile Build cross-compiled binaries of yq.'
|
@echo ' make xcompile Build cross-compiled binaries of yq.'
|
||||||
@echo ' make snap Build a snap package of yq.'
|
|
||||||
@echo ' make vendor Install dependencies using govendor.'
|
@echo ' make vendor Install dependencies using govendor.'
|
||||||
@echo ' make format Run code formatter.'
|
@echo ' make format Run code formatter.'
|
||||||
@echo ' make check Run static code analysis (lint).'
|
@echo ' make check Run static code analysis (lint).'
|
||||||
@@ -65,10 +64,6 @@ xcompile: check
|
|||||||
@find build -type d -exec chmod 755 {} \; || :
|
@find build -type d -exec chmod 755 {} \; || :
|
||||||
@find build -type f -exec chmod 755 {} \; || :
|
@find build -type f -exec chmod 755 {} \; || :
|
||||||
|
|
||||||
.PHONY: snap
|
|
||||||
snap:
|
|
||||||
snapcraft
|
|
||||||
|
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
install: build
|
install: build
|
||||||
${DOCKRUN} go install
|
${DOCKRUN} go install
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"gopkg.in/spf13/cobra.v0"
|
cobra "gopkg.in/spf13/cobra.v0"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getRootCommand() *cobra.Command {
|
func getRootCommand() *cobra.Command {
|
||||||
@@ -122,7 +122,7 @@ func TestReadBadDocumentIndexCmd(t *testing.T) {
|
|||||||
if result.Error == nil {
|
if result.Error == nil {
|
||||||
t.Error("Expected command to fail due to invalid path")
|
t.Error("Expected command to fail due to invalid path")
|
||||||
}
|
}
|
||||||
expectedOutput := `Asked to process document index 1 but there are only 1 document(s)`
|
expectedOutput := `asked to process document index 1 but there are only 1 document(s)`
|
||||||
assertResult(t, expectedOutput, result.Error.Error())
|
assertResult(t, expectedOutput, result.Error.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ func TestReadCmd_ArrayYaml_ErrorBadPath(t *testing.T) {
|
|||||||
if result.Error == nil {
|
if result.Error == nil {
|
||||||
t.Error("Expected command to fail due to invalid path")
|
t.Error("Expected command to fail due to invalid path")
|
||||||
}
|
}
|
||||||
expectedOutput := `Error reading path in document index 0: Error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
|
expectedOutput := `Error reading path in document index 0: error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
|
||||||
assertResult(t, expectedOutput, result.Error.Error())
|
assertResult(t, expectedOutput, result.Error.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +250,7 @@ func TestReadCmd_ArrayYaml_Splat_ErrorBadPath(t *testing.T) {
|
|||||||
if result.Error == nil {
|
if result.Error == nil {
|
||||||
t.Error("Expected command to fail due to invalid path")
|
t.Error("Expected command to fail due to invalid path")
|
||||||
}
|
}
|
||||||
expectedOutput := `Error reading path in document index 0: Error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
|
expectedOutput := `Error reading path in document index 0: error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
|
||||||
assertResult(t, expectedOutput, result.Error.Error())
|
assertResult(t, expectedOutput, result.Error.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,7 +307,7 @@ func TestReadCmd_ErrorBadPath(t *testing.T) {
|
|||||||
if result.Error == nil {
|
if result.Error == nil {
|
||||||
t.Fatal("Expected command to fail due to invalid path")
|
t.Fatal("Expected command to fail due to invalid path")
|
||||||
}
|
}
|
||||||
expectedOutput := `Error reading path in document index 0: Error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
|
expectedOutput := `Error reading path in document index 0: error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
|
||||||
assertResult(t, expectedOutput, result.Error.Error())
|
assertResult(t, expectedOutput, result.Error.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -457,7 +457,7 @@ func TestPrefixBadDocumentIndexCmd(t *testing.T) {
|
|||||||
if result.Error == nil {
|
if result.Error == nil {
|
||||||
t.Error("Expected command to fail due to invalid path")
|
t.Error("Expected command to fail due to invalid path")
|
||||||
}
|
}
|
||||||
expectedOutput := `Asked to process document index 1 but there are only 1 document(s)`
|
expectedOutput := `asked to process document index 1 but there are only 1 document(s)`
|
||||||
assertResult(t, expectedOutput, result.Error.Error())
|
assertResult(t, expectedOutput, result.Error.Error())
|
||||||
}
|
}
|
||||||
func TestPrefixMultiAllCmd(t *testing.T) {
|
func TestPrefixMultiAllCmd(t *testing.T) {
|
||||||
@@ -647,7 +647,7 @@ func TestWriteBadDocumentIndexCmd(t *testing.T) {
|
|||||||
if result.Error == nil {
|
if result.Error == nil {
|
||||||
t.Error("Expected command to fail due to invalid path")
|
t.Error("Expected command to fail due to invalid path")
|
||||||
}
|
}
|
||||||
expectedOutput := `Asked to process document index 1 but there are only 1 document(s)`
|
expectedOutput := `asked to process document index 1 but there are only 1 document(s)`
|
||||||
assertResult(t, expectedOutput, result.Error.Error())
|
assertResult(t, expectedOutput, result.Error.Error())
|
||||||
}
|
}
|
||||||
func TestWriteMultiAllCmd(t *testing.T) {
|
func TestWriteMultiAllCmd(t *testing.T) {
|
||||||
@@ -1084,3 +1084,17 @@ c:
|
|||||||
assertResult(t, expectedOutput, strings.Trim(gotOutput, "\n "))
|
assertResult(t, expectedOutput, strings.Trim(gotOutput, "\n "))
|
||||||
assertResult(t, os.FileMode(int(0666)), info.Mode())
|
assertResult(t, os.FileMode(int(0666)), info.Mode())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMergeAllowEmptyCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := runCmd(cmd, "merge --allow-empty examples/data1.yaml examples/empty.yaml")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `a: simple
|
||||||
|
b:
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
`
|
||||||
|
assertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ func entryInSlice(context yaml.MapSlice, key interface{}) *yaml.MapItem {
|
|||||||
|
|
||||||
func getMapSlice(context interface{}) yaml.MapSlice {
|
func getMapSlice(context interface{}) yaml.MapSlice {
|
||||||
var mapSlice yaml.MapSlice
|
var mapSlice yaml.MapSlice
|
||||||
switch context.(type) {
|
switch context := context.(type) {
|
||||||
case yaml.MapSlice:
|
case yaml.MapSlice:
|
||||||
mapSlice = context.(yaml.MapSlice)
|
mapSlice = context
|
||||||
default:
|
default:
|
||||||
mapSlice = make(yaml.MapSlice, 0)
|
mapSlice = make(yaml.MapSlice, 0)
|
||||||
}
|
}
|
||||||
@@ -29,9 +29,9 @@ func getMapSlice(context interface{}) yaml.MapSlice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getArray(context interface{}) (array []interface{}, ok bool) {
|
func getArray(context interface{}) (array []interface{}, ok bool) {
|
||||||
switch context.(type) {
|
switch context := context.(type) {
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
array = context.([]interface{})
|
array = context
|
||||||
ok = true
|
ok = true
|
||||||
default:
|
default:
|
||||||
array = make([]interface{}, 0)
|
array = make([]interface{}, 0)
|
||||||
@@ -146,18 +146,18 @@ func readMapSplat(context yaml.MapSlice, tail []string) (interface{}, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func recurse(value interface{}, head string, tail []string) (interface{}, error) {
|
func recurse(value interface{}, head string, tail []string) (interface{}, error) {
|
||||||
switch value.(type) {
|
switch value := value.(type) {
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
if head == "*" {
|
if head == "*" {
|
||||||
return readArraySplat(value.([]interface{}), tail)
|
return readArraySplat(value, tail)
|
||||||
}
|
}
|
||||||
index, err := strconv.ParseInt(head, 10, 64)
|
index, err := strconv.ParseInt(head, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error accessing array: %v", err)
|
return nil, fmt.Errorf("error accessing array: %v", err)
|
||||||
}
|
}
|
||||||
return readArray(value.([]interface{}), index, tail)
|
return readArray(value, index, tail)
|
||||||
case yaml.MapSlice:
|
case yaml.MapSlice:
|
||||||
return readMap(value.(yaml.MapSlice), head, tail)
|
return readMap(value, head, tail)
|
||||||
default:
|
default:
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ b:
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("Expected error due to invalid path")
|
t.Fatal("Expected error due to invalid path")
|
||||||
}
|
}
|
||||||
expectedOutput := `Error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
|
expectedOutput := `error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
|
||||||
assertResult(t, expectedOutput, err.Error())
|
assertResult(t, expectedOutput, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ b:
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("Expected error due to invalid path")
|
t.Fatal("Expected error due to invalid path")
|
||||||
}
|
}
|
||||||
expectedOutput := `Error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
|
expectedOutput := `error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
|
||||||
assertResult(t, expectedOutput, err.Error())
|
assertResult(t, expectedOutput, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ b:
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("Expected error due to invalid path")
|
t.Fatal("Expected error due to invalid path")
|
||||||
}
|
}
|
||||||
expectedOutput := `Error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
|
expectedOutput := `error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
|
||||||
assertResult(t, expectedOutput, err.Error())
|
assertResult(t, expectedOutput, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
debian/changelog
vendored
12
debian/changelog
vendored
@@ -1,3 +1,15 @@
|
|||||||
|
yq (2.2-1) bionic; urgency=medium
|
||||||
|
|
||||||
|
* Added Windows support for the "--inplace" command flag
|
||||||
|
* Prefix now supports arrays
|
||||||
|
* Add prefix command
|
||||||
|
* Bump Alpine version to 3.8
|
||||||
|
* Improved docker build process
|
||||||
|
* Lint fixes
|
||||||
|
* Build support for all linux architectures supported by gox
|
||||||
|
|
||||||
|
-- Roberto Mier Escandon <rmescandon@gmail.com> Sat, 19 Jan 2019 15:50:47 +0100
|
||||||
|
|
||||||
yq (2.1-0) bionic; urgency=medium
|
yq (2.1-0) bionic; urgency=medium
|
||||||
|
|
||||||
* Ability to read multiple documents in a single file
|
* Ability to read multiple documents in a single file
|
||||||
|
|||||||
2
debian/control
vendored
2
debian/control
vendored
@@ -12,7 +12,7 @@ Vcs-Browser: https://github.com/mikefarah/yq.git
|
|||||||
Vcs-Git: https://github.com/mikefarah/yq.git
|
Vcs-Git: https://github.com/mikefarah/yq.git
|
||||||
|
|
||||||
Package: yq
|
Package: yq
|
||||||
Architecture: all
|
Architecture: any
|
||||||
Built-Using: ${misc:Built-Using}
|
Built-Using: ${misc:Built-Using}
|
||||||
Depends: ${shlibs:Depends},
|
Depends: ${shlibs:Depends},
|
||||||
${misc:Depends}
|
${misc:Depends}
|
||||||
|
|||||||
2
examples/empty.yaml
Normal file
2
examples/empty.yaml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# a: apple
|
||||||
|
# b: cat
|
||||||
@@ -17,16 +17,16 @@ func jsonToString(context interface{}) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func toJSON(context interface{}) interface{} {
|
func toJSON(context interface{}) interface{} {
|
||||||
switch context.(type) {
|
switch context := context.(type) {
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
oldArray := context.([]interface{})
|
oldArray := context
|
||||||
newArray := make([]interface{}, len(oldArray))
|
newArray := make([]interface{}, len(oldArray))
|
||||||
for index, value := range oldArray {
|
for index, value := range oldArray {
|
||||||
newArray[index] = toJSON(value)
|
newArray[index] = toJSON(value)
|
||||||
}
|
}
|
||||||
return newArray
|
return newArray
|
||||||
case yaml.MapSlice:
|
case yaml.MapSlice:
|
||||||
oldMap := context.(yaml.MapSlice)
|
oldMap := context
|
||||||
newMap := make(map[string]interface{})
|
newMap := make(map[string]interface{})
|
||||||
for _, entry := range oldMap {
|
for _, entry := range oldMap {
|
||||||
if str, ok := entry.Key.(string); ok {
|
if str, ok := entry.Key.(string); ok {
|
||||||
|
|||||||
2
merge.go
2
merge.go
@@ -1,6 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "gopkg.in/imdario/mergo.v0"
|
import mergo "gopkg.in/imdario/mergo.v0"
|
||||||
|
|
||||||
func merge(dst interface{}, src interface{}, overwrite bool, append bool) error {
|
func merge(dst interface{}, src interface{}, overwrite bool, append bool) error {
|
||||||
if overwrite {
|
if overwrite {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: yq
|
name: yq
|
||||||
version: '2.2.1'
|
version: '2.3.0'
|
||||||
summary: A lightweight and portable command-line YAML processor
|
summary: A lightweight and portable command-line YAML processor
|
||||||
description: |
|
description: |
|
||||||
The aim of the project is to be the jq or sed of yaml files.
|
The aim of the project is to be the jq or sed of yaml files.
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
yaml "gopkg.in/mikefarah/yaml.v2"
|
yaml "gopkg.in/mikefarah/yaml.v2"
|
||||||
"gopkg.in/spf13/cobra.v0"
|
cobra "gopkg.in/spf13/cobra.v0"
|
||||||
)
|
)
|
||||||
|
|
||||||
type resulter struct {
|
type resulter struct {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ var (
|
|||||||
GitDescribe string
|
GitDescribe string
|
||||||
|
|
||||||
// Version is main version number that is being run at the moment.
|
// Version is main version number that is being run at the moment.
|
||||||
Version = "2.2.1"
|
Version = "2.3.0"
|
||||||
|
|
||||||
// VersionPrerelease is a pre-release marker for the version. If this is "" (empty string)
|
// VersionPrerelease is a pre-release marker for the version. If this is "" (empty string)
|
||||||
// then it means that it is a final release. Otherwise, this is a pre-release
|
// then it means that it is a final release. Otherwise, this is a pre-release
|
||||||
|
|||||||
13
yq.go
13
yq.go
@@ -22,6 +22,7 @@ var writeInplace = false
|
|||||||
var writeScript = ""
|
var writeScript = ""
|
||||||
var outputToJSON = false
|
var outputToJSON = false
|
||||||
var overwriteFlag = false
|
var overwriteFlag = false
|
||||||
|
var allowEmptyFlag = false
|
||||||
var appendFlag = false
|
var appendFlag = false
|
||||||
var verbose = false
|
var verbose = false
|
||||||
var version = false
|
var version = false
|
||||||
@@ -229,6 +230,7 @@ Note that if you set both flags only overwrite will take effect.
|
|||||||
cmdMerge.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
cmdMerge.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
||||||
cmdMerge.PersistentFlags().BoolVarP(&overwriteFlag, "overwrite", "x", false, "update the yaml file by overwriting existing values")
|
cmdMerge.PersistentFlags().BoolVarP(&overwriteFlag, "overwrite", "x", false, "update the yaml file by overwriting existing values")
|
||||||
cmdMerge.PersistentFlags().BoolVarP(&appendFlag, "append", "a", false, "update the yaml file by appending array values")
|
cmdMerge.PersistentFlags().BoolVarP(&appendFlag, "append", "a", false, "update the yaml file by appending array values")
|
||||||
|
cmdMerge.PersistentFlags().BoolVarP(&allowEmptyFlag, "allow-empty", "e", false, "allow empty yaml files")
|
||||||
cmdMerge.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
cmdMerge.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||||
return cmdMerge
|
return cmdMerge
|
||||||
}
|
}
|
||||||
@@ -255,7 +257,7 @@ func readProperty(cmd *cobra.Command, args []string) error {
|
|||||||
if errorReading == io.EOF {
|
if errorReading == io.EOF {
|
||||||
log.Debugf("done %v / %v", currentIndex, docIndexInt)
|
log.Debugf("done %v / %v", currentIndex, docIndexInt)
|
||||||
if !updateAll && currentIndex <= docIndexInt {
|
if !updateAll && currentIndex <= docIndexInt {
|
||||||
return fmt.Errorf("Asked to process document index %v but there are only %v document(s)", docIndex, currentIndex)
|
return fmt.Errorf("asked to process document index %v but there are only %v document(s)", docIndex, currentIndex)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -370,7 +372,7 @@ func mapYamlDecoder(updateData updateDataFn, encoder *yaml.Encoder) yamlDecoderF
|
|||||||
|
|
||||||
if errorReading == io.EOF {
|
if errorReading == io.EOF {
|
||||||
if !updateAll && currentIndex <= docIndexInt {
|
if !updateAll && currentIndex <= docIndexInt {
|
||||||
return fmt.Errorf("Asked to process document index %v but there are only %v document(s)", docIndex, currentIndex)
|
return fmt.Errorf("asked to process document index %v but there are only %v document(s)", docIndex, currentIndex)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
} else if errorReading != nil {
|
} else if errorReading != nil {
|
||||||
@@ -530,6 +532,9 @@ func mergeProperties(cmd *cobra.Command, args []string) error {
|
|||||||
for _, f := range filesToMerge {
|
for _, f := range filesToMerge {
|
||||||
var fileToMerge interface{}
|
var fileToMerge interface{}
|
||||||
if err := readData(f, 0, &fileToMerge); err != nil {
|
if err := readData(f, 0, &fileToMerge); err != nil {
|
||||||
|
if allowEmptyFlag && err == io.EOF {
|
||||||
|
continue
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
mapDataBucket["root"] = fileToMerge
|
mapDataBucket["root"] = fileToMerge
|
||||||
@@ -589,9 +594,9 @@ func toString(context interface{}) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func yamlToString(context interface{}) (string, error) {
|
func yamlToString(context interface{}) (string, error) {
|
||||||
switch context.(type) {
|
switch context := context.(type) {
|
||||||
case string:
|
case string:
|
||||||
return context.(string), nil
|
return context, nil
|
||||||
default:
|
default:
|
||||||
return marshalContext(context)
|
return marshalContext(context)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user