Skip to content

Commit 44ee869

Browse files
author
Mike Farah
committed
Maintain order
1 parent 5d2d37a commit 44ee869

File tree

8 files changed

+79
-27
lines changed

8 files changed

+79
-27
lines changed

data_navigator.go

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,34 @@ package main
22

33
import (
44
// "fmt"
5+
"github.com/mikefarah/yaml/Godeps/_workspace/src/gopkg.in/yaml.v2"
56
"strconv"
67
)
78

8-
func write(context map[interface{}]interface{}, head string, tail []string, value interface{}) {
9+
func entryInSlice(context yaml.MapSlice, key interface{}) *yaml.MapItem {
10+
for idx := range context {
11+
var entry = &context[idx]
12+
if entry.Key == key {
13+
return entry
14+
}
15+
}
16+
return nil
17+
}
18+
19+
func write(context yaml.MapSlice, head string, tail []string, value interface{}) {
920
if len(tail) == 0 {
10-
context[head] = value
21+
var entry = entryInSlice(context, head)
22+
entry.Value = value
1123
} else {
1224
// e.g. if updating a.b.c, we need to get the 'b', this could be a map or an array
1325
var parent = readMap(context, head, tail[0:len(tail)-1])
1426
switch parent.(type) {
15-
case map[interface{}]interface{}:
16-
toUpdate := parent.(map[interface{}]interface{})
27+
case yaml.MapSlice:
28+
toUpdate := parent.(yaml.MapSlice)
1729
// b is a map, update the key 'c' to the supplied value
1830
key := (tail[len(tail)-1])
19-
toUpdate[key] = value
31+
toUpdateEntry := entryInSlice(toUpdate, key)
32+
toUpdateEntry.Value = value
2033
case []interface{}:
2134
toUpdate := parent.([]interface{})
2235
// b is an array, update it at index 'c' to the supplied value
@@ -31,22 +44,26 @@ func write(context map[interface{}]interface{}, head string, tail []string, valu
3144
}
3245
}
3346

34-
func readMap(context map[interface{}]interface{}, head string, tail []string) interface{} {
47+
func readMap(context yaml.MapSlice, head string, tail []string) interface{} {
3548
if head == "*" {
3649
return readMapSplat(context, tail)
3750
}
38-
value := context[head]
51+
entry := entryInSlice(context, head)
52+
var value interface{}
53+
if entry != nil {
54+
value = entry.Value
55+
}
3956
return calculateValue(value, tail)
4057
}
4158

42-
func readMapSplat(context map[interface{}]interface{}, tail []string) interface{} {
59+
func readMapSplat(context yaml.MapSlice, tail []string) interface{} {
4360
var newArray = make([]interface{}, len(context))
4461
var i = 0
45-
for _, value := range context {
62+
for _, entry := range context {
4663
if len(tail) > 0 {
47-
newArray[i] = recurse(value, tail[0], tail[1:len(tail)])
64+
newArray[i] = recurse(entry.Value, tail[0], tail[1:len(tail)])
4865
} else {
49-
newArray[i] = value
66+
newArray[i] = entry.Value
5067
}
5168
i++
5269
}
@@ -64,8 +81,8 @@ func recurse(value interface{}, head string, tail []string) interface{} {
6481
die("Error accessing array: %v", err)
6582
}
6683
return readArray(value.([]interface{}), index, tail)
67-
case map[interface{}]interface{}:
68-
return readMap(value.(map[interface{}]interface{}), head, tail)
84+
case yaml.MapSlice:
85+
return readMap(value.(yaml.MapSlice), head, tail)
6986
default:
7087
return nil
7188
}

data_navigator_test.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"fmt"
5+
"github.com/mikefarah/yaml/Godeps/_workspace/src/gopkg.in/yaml.v2"
56
"sort"
67
"testing"
78
)
@@ -107,16 +108,26 @@ e:
107108
assertResult(t, "[Fred Sam]", fmt.Sprintf("%v", readMap(data, "e", []string{"*", "name"})))
108109
}
109110

111+
func TestWrite_really_simple(t *testing.T) {
112+
var data = parseData(`
113+
b: 2
114+
`)
115+
116+
write(data, "b", []string{}, "4")
117+
b := entryInSlice(data, "b").Value
118+
assertResult(t, "4", b)
119+
}
120+
110121
func TestWrite_simple(t *testing.T) {
111122
var data = parseData(`
112123
b:
113124
c: 2
114125
`)
115126

116127
write(data, "b", []string{"c"}, "4")
117-
118-
b := data["b"].(map[interface{}]interface{})
119-
assertResult(t, "4", b["c"].(string))
128+
b := entryInSlice(data, "b").Value.(yaml.MapSlice)
129+
c := entryInSlice(b, "c").Value
130+
assertResult(t, "4", c)
120131
}
121132

122133
func TestWrite_array(t *testing.T) {
@@ -127,7 +138,7 @@ b:
127138

128139
write(data, "b", []string{"0"}, "bb")
129140

130-
b := data["b"].([]interface{})
141+
b := entryInSlice(data, "b").Value.([]interface{})
131142
assertResult(t, "bb", b[0].(string))
132143
}
133144

@@ -138,6 +149,6 @@ b:
138149
`)
139150
write(data, "b", []string{}, "4")
140151

141-
b := data["b"]
152+
b := entryInSlice(data, "b").Value
142153
assertResult(t, "4", fmt.Sprintf("%v", b))
143154
}

json_converter.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"encoding/json"
5+
"github.com/mikefarah/yaml/Godeps/_workspace/src/gopkg.in/yaml.v2"
56
)
67

78
func fromJSONBytes(jsonBytes []byte, parsedData *map[interface{}]interface{}) {
@@ -55,11 +56,11 @@ func toJSON(context interface{}) interface{} {
5556
newArray[index] = toJSON(value)
5657
}
5758
return newArray
58-
case map[interface{}]interface{}:
59-
oldMap := context.(map[interface{}]interface{})
59+
case yaml.MapSlice:
60+
oldMap := context.(yaml.MapSlice)
6061
newMap := make(map[string]interface{})
61-
for key, value := range oldMap {
62-
newMap[key.(string)] = toJSON(value)
62+
for _, entry := range oldMap {
63+
newMap[entry.Key.(string)] = toJSON(entry.Value)
6364
}
6465
return newMap
6566
default:

order.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
version: 3
2+
application: MyApp

order.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
version: '2'
2+
services:
3+
test:
4+
image: ubuntu:14.04
5+
stdin_open: true
6+
tty: true

utils_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import (
77
"testing"
88
)
99

10-
func parseData(rawData string) map[interface{}]interface{} {
11-
var parsedData map[interface{}]interface{}
10+
func parseData(rawData string) yaml.MapSlice {
11+
var parsedData yaml.MapSlice
1212
err := yaml.Unmarshal([]byte(rawData), &parsedData)
1313
if err != nil {
1414
fmt.Println("Error parsing yaml: %v", err)

yaml.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ func readProperty(cmd *cobra.Command, args []string) {
8181
}
8282

8383
func read(args []string) interface{} {
84-
var parsedData map[interface{}]interface{}
84+
var parsedData yaml.MapSlice
8585

8686
readData(args[0], &parsedData, inputJSON)
8787

@@ -114,13 +114,14 @@ func updateYaml(args []string) interface{} {
114114
writeCommands[args[1]] = parseValue(args[2])
115115
}
116116

117-
var parsedData map[interface{}]interface{}
117+
var parsedData yaml.MapSlice
118118
readData(args[0], &parsedData, inputJSON)
119119

120120
for path, value := range writeCommands {
121121
var paths = parsePath(path)
122122
write(parsedData, paths[0], paths[1:len(paths)], value)
123123
}
124+
124125
return parsedData
125126
}
126127

yaml_test.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"fmt"
45
"testing"
56
)
67

@@ -26,8 +27,21 @@ func TestRead(t *testing.T) {
2627
assertResult(t, 2, result)
2728
}
2829

30+
func TestOrder(t *testing.T) {
31+
result := read([]string{"order.yaml"})
32+
formattedResult := yamlToString(result)
33+
assertResult(t,
34+
`version: 3
35+
application: MyApp`,
36+
formattedResult)
37+
}
38+
2939
func TestUpdateYaml(t *testing.T) {
30-
updateYaml([]string{"sample.yaml", "b.c", "3"})
40+
result := updateYaml([]string{"sample.yaml", "b.c", "3"})
41+
formattedResult := fmt.Sprintf("%v", result)
42+
assertResult(t,
43+
"[{a Easy! as one two three} {b [{c 3} {d [3 4]} {e [[{name fred} {value 3}] [{name sam} {value 4}]]}]}]",
44+
formattedResult)
3145
}
3246

3347
func TestUpdateYaml_WithScript(t *testing.T) {

0 commit comments

Comments
 (0)