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

Compare commits

..

6 Commits

Author SHA1 Message Date
Mike Farah
9b4972e46e Increment version for new functionality 2019-03-22 09:15:26 +11:00
Renzo Crisóstomo
23543ee031 Add test for --allow-empty flag in merge command 2019-03-22 09:13:39 +11:00
Renzo Crisóstomo
75c7d40c44 Add --allow-empty flag to merge command 2019-03-22 09:13:39 +11:00
Mikhail Novosyolov
44b8a5e80f Fix Debian 'Architecture'
When it's 'all', architecture-independent packages are built, and so now an x86_64 executable is packaged to noarch packaged.
2019-03-21 12:39:47 +11:00
Mike Farah
77c8f22a79 Bump golang version to 1.11 2019-01-21 09:37:22 +11:00
Roberto Mier Escandon
386a0ca3c3 Bump debian pkg to 2.2-1 version 2019-01-21 09:06:43 +11:00
15 changed files with 66 additions and 38 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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
} }

View File

@@ -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
View File

@@ -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
View File

@@ -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
View File

@@ -0,0 +1,2 @@
# a: apple
# b: cat

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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.

View File

@@ -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 {

View File

@@ -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
View File

@@ -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)
} }