Skip to content

Commit 11b0957

Browse files
committed
fix(yaml): make MarshalYAML deterministic
This PR sorts the keys of a map[string]interface{} before marshaling to YAML, similar to what the standard encoding/json does. * fixes go-swagger/go-swagger#2850 Signed-off-by: Frederic BIDON <[email protected]>
1 parent 3f60c98 commit 11b0957

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

yaml.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"fmt"
2020
"path/filepath"
2121
"reflect"
22+
"sort"
2223
"strconv"
2324

2425
"github.com/mailru/easyjson/jlexer"
@@ -286,7 +287,14 @@ func json2yaml(item interface{}) (*yaml.Node, error) {
286287
case map[string]interface{}:
287288
var n yaml.Node
288289
n.Kind = yaml.MappingNode
289-
for k, v := range val {
290+
keys := make([]string, 0, len(val))
291+
for k := range val {
292+
keys = append(keys, k)
293+
}
294+
sort.Strings(keys)
295+
296+
for _, k := range keys {
297+
v := val[k]
290298
childNode, err := json2yaml(v)
291299
if err != nil {
292300
return nil, err

yaml_test.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,30 @@ y: some value
7575
assert.Equal(t, expected, string(ny.([]byte)))
7676
}
7777

78-
func TestYAMLToJSON(t *testing.T) {
78+
func TestMarshalYAML(t *testing.T) {
79+
t.Run("marshalYAML should be deterministic", func(t *testing.T) {
80+
const (
81+
jazon = `{"1":"x","2":null,"3":{"a":1,"b":2,"c":3}}`
82+
expected = `"1": x
83+
"2": null
84+
"3":
85+
a: !!float 1
86+
b: !!float 2
87+
c: !!float 3
88+
`
89+
)
90+
const iterations = 10
91+
for n := 0; n < iterations; n++ {
92+
var data JSONMapSlice
93+
require.NoError(t, json.Unmarshal([]byte(jazon), &data))
94+
ny, err := data.MarshalYAML()
95+
require.NoError(t, err)
96+
assert.Equal(t, expected, string(ny.([]byte)))
97+
}
98+
})
99+
}
79100

101+
func TestYAMLToJSON(t *testing.T) {
80102
sd := `---
81103
1: the int key value
82104
name: a string value

0 commit comments

Comments
 (0)