diff --git a/kyaml/kio/byteio_writer.go b/kyaml/kio/byteio_writer.go index c6fe96db4..84097f108 100644 --- a/kyaml/kio/byteio_writer.go +++ b/kyaml/kio/byteio_writer.go @@ -72,15 +72,8 @@ func (w ByteWriter) Write(nodes []*yaml.RNode) error { } } - // TODO(pwittrock): factor this into a a common module for pruning empty values - _, err := nodes[i].Pipe(yaml.Lookup("metadata"), yaml.FieldClearer{ - Name: "annotations", IfEmpty: true}) - if err != nil { - return errors.Wrap(err) - } - _, err = nodes[i].Pipe(yaml.FieldClearer{Name: "metadata", IfEmpty: true}) - if err != nil { - return errors.Wrap(err) + if err := yaml.ClearEmptyAnnotations(nodes[i]); err != nil { + return err } if w.Style != 0 { diff --git a/kyaml/kio/pkgio_reader_test.go b/kyaml/kio/pkgio_reader_test.go index 62810277d..7f68fdd73 100644 --- a/kyaml/kio/pkgio_reader_test.go +++ b/kyaml/kio/pkgio_reader_test.go @@ -71,6 +71,17 @@ g: - j `) +var readFileC = []byte(`--- +a: b #third +metadata: + annotations: +`) + +var readFileD = []byte(`--- +a: b #forth +metadata: +`) + var pkgFile = []byte(``) func TestLocalPackageReader_Read_empty(t *testing.T) { @@ -87,6 +98,8 @@ func TestLocalPackageReader_Read_pkg(t *testing.T) { defer s.clean() s.writeFile(t, filepath.Join("a_test.yaml"), readFileA) s.writeFile(t, filepath.Join("b_test.yaml"), readFileB) + s.writeFile(t, filepath.Join("c_test.yaml"), readFileC) + s.writeFile(t, filepath.Join("d_test.yaml"), readFileD) paths := []struct { path string @@ -101,7 +114,7 @@ func TestLocalPackageReader_Read_pkg(t *testing.T) { return } - if !assert.Len(t, nodes, 3) { + if !assert.Len(t, nodes, 5) { return } expected := []string{ @@ -127,6 +140,18 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'b_test.yaml' +`, + `a: b #third +metadata: + annotations: + config.kubernetes.io/index: '0' + config.kubernetes.io/path: 'c_test.yaml' +`, + `a: b #forth +metadata: + annotations: + config.kubernetes.io/index: '0' + config.kubernetes.io/path: 'd_test.yaml' `, } for i := range nodes { diff --git a/kyaml/yaml/kfns.go b/kyaml/yaml/kfns.go index 229c9c4ca..a8545e41b 100644 --- a/kyaml/yaml/kfns.go +++ b/kyaml/yaml/kfns.go @@ -5,6 +5,7 @@ package yaml import ( "gopkg.in/yaml.v3" + "sigs.k8s.io/kustomize/kyaml/errors" ) // AnnotationClearer removes an annotation at metadata.annotations. @@ -24,6 +25,21 @@ func ClearAnnotation(key string) AnnotationClearer { return AnnotationClearer{Key: key} } +// ClearEmptyAnnotations clears the keys, annotations +// and metadata if they are empty/null +func ClearEmptyAnnotations(rn *RNode) error { + _, err := rn.Pipe(Lookup("metadata"), FieldClearer{ + Name: "annotations", IfEmpty: true}) + if err != nil { + return errors.Wrap(err) + } + _, err = rn.Pipe(FieldClearer{Name: "metadata", IfEmpty: true}) + if err != nil { + return errors.Wrap(err) + } + return nil +} + // AnnotationSetter sets an annotation at metadata.annotations. // Creates metadata.annotations if does not exist. type AnnotationSetter struct { @@ -37,6 +53,11 @@ func (s AnnotationSetter) Filter(rn *RNode) (*RNode, error) { v := NewScalarRNode(s.Value) v.YNode().Tag = StringTag v.YNode().Style = yaml.SingleQuotedStyle + + if err := ClearEmptyAnnotations(rn); err != nil { + return nil, err + } + return rn.Pipe( PathGetter{Path: []string{"metadata", "annotations"}, Create: yaml.MappingNode}, FieldSetter{Name: s.Key, Value: v})