forked from LaconicNetwork/kompose
Merge pull request #1775 from martinjirku/1758-remove-useless-keys-in-output
feat(1765): remove useless keys from the output yml
This commit is contained in:
@@ -280,6 +280,46 @@ func marshal(obj runtime.Object, jsonFormat bool, indent int) (data []byte, err
|
||||
return
|
||||
}
|
||||
|
||||
// remove empty map[string]interface{} strings from the object
|
||||
//
|
||||
// Note: this function uses recursion, use it only objects created by the unmarshalled json.
|
||||
// Passing cyclic structures to removeEmptyInterfaces will result in a stack overflow.
|
||||
func removeEmptyInterfaces(obj interface{}) interface{} {
|
||||
switch v := obj.(type) {
|
||||
case []interface{}:
|
||||
for i, val := range v {
|
||||
if valMap, ok := val.(map[string]interface{}); (ok && len(valMap) == 0) || val == nil {
|
||||
v = append(v[:i], v[i+1:]...)
|
||||
} else {
|
||||
v[i] = removeEmptyInterfaces(val)
|
||||
}
|
||||
}
|
||||
return v
|
||||
case map[string]interface{}:
|
||||
for k, val := range v {
|
||||
if valMap, ok := val.(map[string]interface{}); ok {
|
||||
// It is always map[string]interface{} when passed the map[string]interface{}
|
||||
valMap := removeEmptyInterfaces(valMap).(map[string]interface{})
|
||||
if len(valMap) == 0 {
|
||||
delete(v, k)
|
||||
}
|
||||
} else if val == nil {
|
||||
delete(v, k)
|
||||
} else {
|
||||
processedInterface := removeEmptyInterfaces(val)
|
||||
if valSlice, ok := processedInterface.([]interface{}); ok && len(valSlice) == 0 {
|
||||
delete(v, k)
|
||||
} else {
|
||||
v[k] = processedInterface
|
||||
}
|
||||
}
|
||||
}
|
||||
return v
|
||||
default:
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// Convert JSON to YAML.
|
||||
func jsonToYaml(j []byte, spaces int) ([]byte, error) {
|
||||
// Convert the JSON to an object.
|
||||
@@ -293,7 +333,7 @@ func jsonToYaml(j []byte, spaces int) ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
jsonObj = removeEmptyInterfaces(jsonObj)
|
||||
var b bytes.Buffer
|
||||
encoder := yaml.NewEncoder(&b)
|
||||
encoder.SetIndent(spaces)
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package kubernetes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
@@ -704,3 +705,27 @@ func TestFormatEnvName(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Test empty interfaces removal
|
||||
func TestRemoveEmptyInterfaces(t *testing.T) {
|
||||
type Obj = map[string]interface{}
|
||||
var testCases = []struct {
|
||||
input interface{}
|
||||
output interface{}
|
||||
}{
|
||||
{Obj{"useless": Obj{}}, Obj{}},
|
||||
{Obj{"usefull": Obj{"usefull": "usefull"}}, Obj{"usefull": Obj{"usefull": "usefull"}}},
|
||||
{Obj{"usefull": Obj{"usefull": "usefull", "uselessdeep": Obj{}, "uselessnil": nil}}, Obj{"usefull": Obj{"usefull": "usefull"}}},
|
||||
{Obj{"uselessdeep": Obj{"uselessdeep": Obj{}, "uselessnil": nil}}, Obj{}},
|
||||
{Obj{"uselessempty": []interface{}{nil}}, Obj{}},
|
||||
{"test", "test"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("Test removeEmptyInterfaces(%s)", tc.input), func(t *testing.T) {
|
||||
result := removeEmptyInterfaces(tc.input)
|
||||
if !reflect.DeepEqual(result, tc.output) {
|
||||
t.Errorf("Expected %v, got %v", tc.output, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user