Skip to content

Commit

Permalink
fix: change to make buildFlatMap support arrays as YAML values (#8152)
Browse files Browse the repository at this point in the history
* fix: change to make buildFlatMap support arrays as YAML values

* test: add unit test for unmarshal logic with nested arrays
  • Loading branch information
renzodavid9 authored Nov 28, 2022
1 parent db3bb6e commit 9938801
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 33 deletions.
55 changes: 22 additions & 33 deletions pkg/skaffold/schema/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,45 +92,34 @@ func (m *FlatMap) UnmarshalYAML(unmarshal func(interface{}) error) error {
return err
}
result := make(map[string]string)
if err := buildFlatMap(obj, result, ""); err != nil {
return err
}
buildFlatMap(obj, result, "")
*m = result
return nil
}

func buildFlatMap(obj map[string]interface{}, result map[string]string, currK string) (err error) {
var prevK string
for k, v := range obj {
prevK = currK
if currK == "" {
currK = fmt.Sprintf("%v", k)
} else {
currK = fmt.Sprintf("%v.%v", currK, k)
}
func buildFlatList(list []interface{}, result map[string]string, parentK string) {
for idx, item := range list {
currK := fmt.Sprintf("%v[%d]", parentK, idx)
processItem(item, result, currK)
}
}

switch v := v.(type) {
case map[string]interface{}:
if err = buildFlatMap(v, result, currK); err != nil {
return
}
case []interface{}:
for idx, i := range v {
if m, ok := i.(map[string]interface{}); ok {
currIdx := fmt.Sprintf("%v[%d]", currK, idx)
if err = buildFlatMap(m, result, currIdx); err != nil {
return
}
}
}
case string:
result[currK] = v
default:
result[currK] = fmt.Sprintf("%v", v)
}
currK = prevK
func buildFlatMap(obj map[string]interface{}, result map[string]string, parentK string) {
for key, item := range obj {
currK := fmt.Sprintf("%v%v", parentK, key)
processItem(item, result, currK)
}
}

func processItem(item interface{}, result map[string]string, currK string) {
switch v := item.(type) {
case map[string]interface{}:
buildFlatMap(v, result, fmt.Sprintf("%v.", currK))
case []interface{}:
buildFlatList(v, result, currK)
default:
result[currK] = fmt.Sprintf("%v", v)
}
return err
}

func marshalInlineYaml(in interface{}) ([]byte, error) {
Expand Down
68 changes: 68 additions & 0 deletions pkg/skaffold/schema/util/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,71 @@ values.val3[0].val9: foo4
values.val3[0].val9: foo4
`, string(out))
}

func TestFlatMap_UnmarshalYAMLNestedArrays(t *testing.T) {
inputYaml := `
name: nameValue
configs:
name: configName
defaults:
- prop1: bar1
prop2: foo1
- prop1: bar2
prop2: foo2
mixlist:
- prop1: bar3
prop2:
- foo3
- element2
matrix:
- - i1
- i2
- - j1
- j2
`

expected := `name: nameValue
configs.name: configName
configs.defaults[0].prop1: bar1
configs.defaults[0].prop2: foo1
configs.defaults[1].prop1: bar2
configs.defaults[1].prop2: foo2
configs.mixlist[0].prop1: bar3
configs.mixlist[0].prop2[0]: foo3
configs.mixlist[1]: element2
configs.matrix[0][0]: i1
configs.matrix[0][1]: i2
configs.matrix[1][0]: j1
configs.matrix[1][1]: j2
`
inputFlatmap := &FlatMap{}
expectedFlatmap := &FlatMap{}

err := yaml.Unmarshal([]byte(inputYaml), &inputFlatmap)
testutil.CheckError(t, false, err)

err = yaml.Unmarshal([]byte(expected), &expectedFlatmap)
testutil.CheckError(t, false, err)

testutil.CheckDeepEqual(t, *inputFlatmap, *expectedFlatmap)

out, err := yaml.Marshal(struct {
M *FlatMap `yaml:"value,omitempty"`
}{inputFlatmap})

testutil.CheckErrorAndDeepEqual(t, false, err, `value:
configs.defaults[0].prop1: bar1
configs.defaults[0].prop2: foo1
configs.defaults[1].prop1: bar2
configs.defaults[1].prop2: foo2
configs.matrix[0][0]: i1
configs.matrix[0][1]: i2
configs.matrix[1][0]: j1
configs.matrix[1][1]: j2
configs.mixlist[0].prop1: bar3
configs.mixlist[0].prop2[0]: foo3
configs.mixlist[1]: element2
configs.name: configName
name: nameValue
`, string(out))
}

0 comments on commit 9938801

Please sign in to comment.