Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions manifest/normalize_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package manifest

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestNormalizeContent(t *testing.T) {
tests := []struct {
name string
content []byte
expectedOutput []byte
expectError bool
}{
{
name: "Valid content",
content: []byte(`apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx`),
expectedOutput: []byte(`apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- image: nginx
name: my-container
`),
},
{
// yaml.v2 marshals a nil map to "{}\n". Empty content never
// reaches this path in practice (Parse filters it earlier),
// but document the behavior regardless.
name: "Empty content",
content: []byte(""),
expectedOutput: []byte("{}\n"),
},
{
name: "Sequence cannot unmarshal into map",
content: []byte("- a\n- b"),
expectError: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
output, err := normalizeContent(tt.content)
if tt.expectError {
require.Error(t, err)
return
}
require.NoError(t, err)
require.Equal(t, tt.expectedOutput, output)
})
}
}
27 changes: 19 additions & 8 deletions manifest/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,11 @@ func parseContent(content []byte, defaultNamespace string, normalizeManifests bo
}

if normalizeManifests {
var object map[interface{}]interface{}
if err := yaml.Unmarshal(content, &object); err != nil {
log.Fatalf("YAML unmarshal error: %s\nCan't unmarshal %s", err, content)
}
normalizedContent, err := yaml.Marshal(object)
if err != nil {
log.Fatalf("YAML marshal error: %s\nCan't marshal %v", err, object)
var normalizeErr error
content, normalizeErr = normalizeContent(content)
if normalizeErr != nil {
log.Fatalf("Error normalizing manifests: %v", normalizeErr)
}
content = normalizedContent
}

if isHook(parsedMetadata, excludedHooks...) {
Expand All @@ -220,6 +216,21 @@ func parseContent(content []byte, defaultNamespace string, normalizeManifests bo
}, nil
}

func normalizeContent(content []byte) ([]byte, error) {
// Unmarshal and marshal again content to normalize yaml structure
// This avoids style differences to show up as diffs but it can
// make the output different from the original template (since it is in normalized form)
var object map[interface{}]interface{}
if err := yaml.Unmarshal(content, &object); err != nil {
return nil, err
}
normalizedContent, err := yaml.Marshal(object)
if err != nil {
return nil, err
}
return normalizedContent, nil
}

func isHook(metadata metadata, hooks ...string) bool {
for _, hook := range hooks {
if metadata.Metadata.Annotations[hookAnnotation] == hook {
Expand Down
Loading