From bcebad1664c2b92846abff54525b42f7b87a577d Mon Sep 17 00:00:00 2001
From: Natasha Sarkar <natashasarkar@google.com>
Date: Wed, 26 Jan 2022 15:34:50 -0800
Subject: [PATCH] new command `kustomize edit add buildmetadata` (#4413)

* new command kustomize edit add buildmetadata

* new commands kustomize edit set buildmetadata and kustomize edit remove buildmetadata
---
 api/internal/target/kusttarget.go             |  6 +-
 api/types/kustomization.go                    |  2 +
 .../commands/edit/add/addbuildmetadata.go     | 69 +++++++++++++++++
 .../edit/add/addbuildmetadata_test.go         | 63 +++++++++++++++
 kustomize/commands/edit/add/all.go            |  1 +
 kustomize/commands/edit/remove/all.go         |  1 +
 .../edit/remove/removebuildmetadata.go        | 71 +++++++++++++++++
 .../edit/remove/removebuildmetadata_test.go   | 65 ++++++++++++++++
 kustomize/commands/edit/set/all.go            |  1 +
 .../commands/edit/set/setbuildmetadata.go     | 63 +++++++++++++++
 .../edit/set/setbuildmetadata_test.go         | 76 +++++++++++++++++++
 .../internal/kustfile/kustomizationfile.go    |  1 +
 .../kustfile/kustomizationfile_test.go        |  1 +
 kustomize/commands/internal/util/util_test.go |  3 +
 kustomize/commands/internal/util/validate.go  | 31 ++++++++
 .../prefixtransformer/PrefixTransformer.go    |  2 +-
 16 files changed, 450 insertions(+), 6 deletions(-)
 create mode 100644 kustomize/commands/edit/add/addbuildmetadata.go
 create mode 100644 kustomize/commands/edit/add/addbuildmetadata_test.go
 create mode 100644 kustomize/commands/edit/remove/removebuildmetadata.go
 create mode 100644 kustomize/commands/edit/remove/removebuildmetadata_test.go
 create mode 100644 kustomize/commands/edit/set/setbuildmetadata.go
 create mode 100644 kustomize/commands/edit/set/setbuildmetadata_test.go
 create mode 100644 kustomize/commands/internal/util/validate.go

diff --git a/api/internal/target/kusttarget.go b/api/internal/target/kusttarget.go
index c89e0f7996..2fcfd830db 100644
--- a/api/internal/target/kusttarget.go
+++ b/api/internal/target/kusttarget.go
@@ -325,11 +325,7 @@ func (kt *KustTarget) runTransformers(ra *accumulator.ResAccumulator) error {
 		return err
 	}
 	r = append(r, lts...)
-	err = ra.Transform(newMultiTransformer(r))
-	if err != nil {
-		return err
-	}
-	return nil
+	return ra.Transform(newMultiTransformer(r))
 }
 
 func (kt *KustTarget) configureExternalTransformers(transformers []string) ([]*resmap.TransformerWithProperties, error) {
diff --git a/api/types/kustomization.go b/api/types/kustomization.go
index fb14f191c0..a128c77490 100644
--- a/api/types/kustomization.go
+++ b/api/types/kustomization.go
@@ -23,6 +23,8 @@ const (
 	ManagedByLabelOption   = "managedByLabel"
 )
 
+var BuildMetadataOptions = []string{OriginAnnotations, TransformerAnnotations, ManagedByLabelOption}
+
 // Kustomization holds the information needed to generate customized k8s api resources.
 type Kustomization struct {
 	TypeMeta `json:",inline" yaml:",inline"`
diff --git a/kustomize/commands/edit/add/addbuildmetadata.go b/kustomize/commands/edit/add/addbuildmetadata.go
new file mode 100644
index 0000000000..b376238420
--- /dev/null
+++ b/kustomize/commands/edit/add/addbuildmetadata.go
@@ -0,0 +1,69 @@
+// Copyright 2022 The Kubernetes Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+package add
+
+import (
+	"fmt"
+
+	"github.com/spf13/cobra"
+	"sigs.k8s.io/kustomize/kustomize/v4/commands/internal/kustfile"
+	"sigs.k8s.io/kustomize/kustomize/v4/commands/internal/util"
+	"sigs.k8s.io/kustomize/kyaml/filesys"
+)
+
+type addBuildMetadataOptions struct {
+	*util.BuildMetadataValidator
+	buildMetadataOptions []string
+}
+
+// newCmdAddBuildMetadata adds options to the kustomization's buildMetada field.
+func newCmdAddBuildMetadata(fSys filesys.FileSystem) *cobra.Command {
+	var o addBuildMetadataOptions
+
+	cmd := &cobra.Command{
+		Use:   "buildmetadata",
+		Short: "Adds one or more buildMetadata options to the kustomization.yaml in the current directory",
+		Long: `Adds one or more buildMetadata options to the kustomization.yaml in the current directory.
+The following options are valid:
+  - originAnnotations
+  - transformerAnnotations
+  - managedByLabel
+originAnnotations will add the annotation config.kubernetes.io/origin to each resource, describing where 
+each resource originated from.
+transformerAnnotations will add the annotation alpha.config.kubernetes.io/transformations to each resource,
+describing the transformers that have acted upon the resource.
+managedByLabel will add the label app.kubernetes.io/managed-by to each resource, describing which version
+of kustomize managed the resource.`,
+		Example: `
+		add buildmetadata {option1},{option2}`,
+		RunE: func(cmd *cobra.Command, args []string) error {
+			var err error
+			o.buildMetadataOptions, err = o.BuildMetadataValidator.Validate(args)
+			if err != nil {
+				return err
+			}
+			return o.RunAddBuildMetadata(fSys)
+		},
+	}
+	return cmd
+}
+
+// RunAddBuildMetadata runs addBuildMetadata command (do real work).
+func (o *addBuildMetadataOptions) RunAddBuildMetadata(fSys filesys.FileSystem) error {
+	mf, err := kustfile.NewKustomizationFile(fSys)
+	if err != nil {
+		return err
+	}
+	m, err := mf.Read()
+	if err != nil {
+		return err
+	}
+	for _, opt := range o.buildMetadataOptions {
+		if kustfile.StringInSlice(opt, m.BuildMetadata) {
+			return fmt.Errorf("buildMetadata option %s already in kustomization file", opt)
+		}
+		m.BuildMetadata = append(m.BuildMetadata, opt)
+	}
+	return mf.Write(m)
+}
diff --git a/kustomize/commands/edit/add/addbuildmetadata_test.go b/kustomize/commands/edit/add/addbuildmetadata_test.go
new file mode 100644
index 0000000000..47d91471a6
--- /dev/null
+++ b/kustomize/commands/edit/add/addbuildmetadata_test.go
@@ -0,0 +1,63 @@
+// Copyright 2022 The Kubernetes Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+package add
+
+import (
+	"strings"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"sigs.k8s.io/kustomize/api/types"
+	testutils_test "sigs.k8s.io/kustomize/kustomize/v4/commands/internal/testutils"
+	"sigs.k8s.io/kustomize/kyaml/filesys"
+)
+
+func TestAddBuildMetadata(t *testing.T) {
+	tests := map[string]struct {
+		input       string
+		args        []string
+		expectedErr string
+	}{
+		"happy path": {
+			input: ``,
+			args:  []string{strings.Join(types.BuildMetadataOptions, ",")},
+		},
+		"option already there": {
+			input: `
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+buildMetadata: [originAnnotations]`,
+			args:        []string{types.OriginAnnotations},
+			expectedErr: "buildMetadata option originAnnotations already in kustomization file",
+		},
+		"invalid option": {
+			input:       ``,
+			args:        []string{"invalid_option"},
+			expectedErr: "invalid buildMetadata option: invalid_option",
+		},
+		"too many args": {
+			input:       ``,
+			args:        []string{"option1", "option2"},
+			expectedErr: "too many arguments: [option1 option2]; to provide multiple buildMetadata options, please separate options by comma",
+		},
+	}
+
+	for _, tc := range tests {
+		fSys := filesys.MakeFsInMemory()
+		testutils_test.WriteTestKustomizationWith(fSys, []byte(tc.input))
+		cmd := newCmdAddBuildMetadata(fSys)
+		err := cmd.RunE(cmd, tc.args)
+		if tc.expectedErr != "" {
+			assert.Error(t, err)
+			assert.Contains(t, err.Error(), tc.expectedErr)
+		} else {
+			assert.NoError(t, err)
+			content, err := testutils_test.ReadTestKustomization(fSys)
+			assert.NoError(t, err)
+			for _, opt := range strings.Split(tc.args[0], ",") {
+				assert.Contains(t, string(content), opt)
+			}
+		}
+	}
+}
diff --git a/kustomize/commands/edit/add/all.go b/kustomize/commands/edit/add/all.go
index e9309e557f..d9605444ce 100644
--- a/kustomize/commands/edit/add/all.go
+++ b/kustomize/commands/edit/add/all.go
@@ -57,6 +57,7 @@ func NewCmdAdd(
 		newCmdAddSecret(fSys, ldr, rf),
 		newCmdAddConfigMap(fSys, ldr, rf),
 		newCmdAddBase(fSys),
+		newCmdAddBuildMetadata(fSys),
 		newCmdAddLabel(fSys, ldr.Validator().MakeLabelValidator()),
 		newCmdAddAnnotation(fSys, ldr.Validator().MakeAnnotationValidator()),
 		newCmdAddTransformer(fSys),
diff --git a/kustomize/commands/edit/remove/all.go b/kustomize/commands/edit/remove/all.go
index 4629b48903..14db55ea1a 100644
--- a/kustomize/commands/edit/remove/all.go
+++ b/kustomize/commands/edit/remove/all.go
@@ -42,6 +42,7 @@ func NewCmdRemove(
 		newCmdRemoveAnnotation(fSys, v.MakeAnnotationNameValidator()),
 		newCmdRemovePatch(fSys),
 		newCmdRemoveTransformer(fSys),
+		newCmdRemoveBuildMetadata(fSys),
 	)
 	return c
 }
diff --git a/kustomize/commands/edit/remove/removebuildmetadata.go b/kustomize/commands/edit/remove/removebuildmetadata.go
new file mode 100644
index 0000000000..be918044dd
--- /dev/null
+++ b/kustomize/commands/edit/remove/removebuildmetadata.go
@@ -0,0 +1,71 @@
+// Copyright 2022 The Kubernetes Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+package remove
+
+import (
+	"github.com/spf13/cobra"
+	"sigs.k8s.io/kustomize/kustomize/v4/commands/internal/kustfile"
+	"sigs.k8s.io/kustomize/kustomize/v4/commands/internal/util"
+	"sigs.k8s.io/kustomize/kyaml/filesys"
+)
+
+type removeBuildMetadataOptions struct {
+	*util.BuildMetadataValidator
+	buildMetadataOptions []string
+}
+
+// newCmdRemoveBuildMetadata removes options to the kustomization's buildMetada field.
+func newCmdRemoveBuildMetadata(fSys filesys.FileSystem) *cobra.Command {
+	var o removeBuildMetadataOptions
+
+	cmd := &cobra.Command{
+		Use:   "buildmetadata",
+		Short: "Removes one or more buildMetadata options to the kustomization.yaml in the current directory",
+		Long: `Removes one or more buildMetadata options to the kustomization.yaml in the current directory.
+The following options are valid:
+  - originAnnotations
+  - transformerAnnotations
+  - managedByLabel
+originAnnotations will remove the annotation config.kubernetes.io/origin to each resource, describing where 
+each resource originated from.
+transformerAnnotations will remove the annotation alpha.config.kubernetes.io/transformations to each resource,
+describing the transformers that have acted upon the resource.
+managedByLabel will remove the label app.kubernetes.io/managed-by to each resource, describing which version
+of kustomize managed the resource.`,
+		Example: `
+		remove buildmetadata {option1},{option2}`,
+		RunE: func(cmd *cobra.Command, args []string) error {
+			var err error
+			o.buildMetadataOptions, err = o.BuildMetadataValidator.Validate(args)
+			if err != nil {
+				return err
+			}
+			return o.RunRemoveBuildMetadata(fSys)
+		},
+	}
+	return cmd
+}
+
+// RunRemoveBuildMetadata runs removeBuildMetadata command (do real work).
+func (o *removeBuildMetadataOptions) RunRemoveBuildMetadata(fSys filesys.FileSystem) error {
+	mf, err := kustfile.NewKustomizationFile(fSys)
+	if err != nil {
+		return err
+	}
+	m, err := mf.Read()
+	if err != nil {
+		return err
+	}
+	var newOptions []string
+	for _, opt := range m.BuildMetadata {
+		if !kustfile.StringInSlice(opt, o.buildMetadataOptions) {
+			newOptions = append(newOptions, opt)
+		}
+	}
+	m.BuildMetadata = newOptions
+	if len(m.BuildMetadata) == 0 {
+		m.BuildMetadata = nil
+	}
+	return mf.Write(m)
+}
diff --git a/kustomize/commands/edit/remove/removebuildmetadata_test.go b/kustomize/commands/edit/remove/removebuildmetadata_test.go
new file mode 100644
index 0000000000..0de7f0b7b0
--- /dev/null
+++ b/kustomize/commands/edit/remove/removebuildmetadata_test.go
@@ -0,0 +1,65 @@
+// Copyright 2022 The Kubernetes Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+package remove
+
+import (
+	"strings"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"sigs.k8s.io/kustomize/api/types"
+	testutils_test "sigs.k8s.io/kustomize/kustomize/v4/commands/internal/testutils"
+	"sigs.k8s.io/kustomize/kyaml/filesys"
+)
+
+func TestRemoveBuildMetadata(t *testing.T) {
+	tests := map[string]struct {
+		input       string
+		args        []string
+		expectedErr string
+	}{
+		"happy path": {
+			input: `
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+buildMetadata: [originAnnotations, transformerAnnotations, managedByLabel]`,
+			args: []string{types.OriginAnnotations},
+		},
+		"option already there": {
+			input: `
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+buildMetadata: [originAnnotations]`,
+			args: []string{types.OriginAnnotations},
+		},
+		"invalid option": {
+			input:       ``,
+			args:        []string{"invalid_option"},
+			expectedErr: "invalid buildMetadata option: invalid_option",
+		},
+		"too many args": {
+			input:       ``,
+			args:        []string{"option1", "option2"},
+			expectedErr: "too many arguments: [option1 option2]; to provide multiple buildMetadata options, please separate options by comma",
+		},
+	}
+
+	for _, tc := range tests {
+		fSys := filesys.MakeFsInMemory()
+		testutils_test.WriteTestKustomizationWith(fSys, []byte(tc.input))
+		cmd := newCmdRemoveBuildMetadata(fSys)
+		err := cmd.RunE(cmd, tc.args)
+		if tc.expectedErr != "" {
+			assert.Error(t, err)
+			assert.Contains(t, err.Error(), tc.expectedErr)
+		} else {
+			assert.NoError(t, err)
+			content, err := testutils_test.ReadTestKustomization(fSys)
+			assert.NoError(t, err)
+			for _, opt := range strings.Split(tc.args[0], ",") {
+				assert.NotContains(t, string(content), opt)
+			}
+		}
+	}
+}
diff --git a/kustomize/commands/edit/set/all.go b/kustomize/commands/edit/set/all.go
index e04f64c1d7..1f62d62a31 100644
--- a/kustomize/commands/edit/set/all.go
+++ b/kustomize/commands/edit/set/all.go
@@ -30,6 +30,7 @@ func NewCmdSet(fSys filesys.FileSystem, ldr ifc.KvLoader, v ifc.Validator) *cobr
 		newCmdSetNameSuffix(fSys),
 		newCmdSetNamespace(fSys, v),
 		newCmdSetImage(fSys),
+		newCmdSetBuildMetadata(fSys),
 		newCmdSetReplicas(fSys),
 		newCmdSetLabel(fSys, ldr.Validator().MakeLabelValidator()),
 		newCmdSetAnnotation(fSys, ldr.Validator().MakeAnnotationValidator()),
diff --git a/kustomize/commands/edit/set/setbuildmetadata.go b/kustomize/commands/edit/set/setbuildmetadata.go
new file mode 100644
index 0000000000..43a7cc1eaf
--- /dev/null
+++ b/kustomize/commands/edit/set/setbuildmetadata.go
@@ -0,0 +1,63 @@
+// Copyright 2022 The Kubernetes Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+package set
+
+import (
+	"github.com/spf13/cobra"
+	"sigs.k8s.io/kustomize/kustomize/v4/commands/internal/kustfile"
+	"sigs.k8s.io/kustomize/kustomize/v4/commands/internal/util"
+	"sigs.k8s.io/kustomize/kyaml/filesys"
+)
+
+type setBuildMetadataOptions struct {
+	*util.BuildMetadataValidator
+	buildMetadataOptions []string
+}
+
+// newCmdSetBuildMetadata sets options in the kustomization's buildMetada field.
+func newCmdSetBuildMetadata(fSys filesys.FileSystem) *cobra.Command {
+	var o setBuildMetadataOptions
+
+	cmd := &cobra.Command{
+		Use:   "buildmetadata",
+		Short: "Sets one or more buildMetadata options to the kustomization.yaml in the current directory",
+		Long: `Sets one or more buildMetadata options to the kustomization.yaml in the current directory.
+Existing options in the buildMetadata field will be replaced entirely by the new options set by this command.
+The following options are valid:
+  - originAnnotations
+  - transformerAnnotations
+  - managedByLabel
+originAnnotations will add the annotation config.kubernetes.io/origin to each resource, describing where 
+each resource originated from.
+transformerAnnotations will add the annotation alpha.config.kubernetes.io/transformations to each resource,
+describing the transformers that have acted upon the resource.
+managedByLabel will add the label app.kubernetes.io/managed-by to each resource, describing which version
+of kustomize managed the resource.`,
+		Example: `
+		set buildmetadata {option1},{option2}`,
+		RunE: func(cmd *cobra.Command, args []string) error {
+			var err error
+			o.buildMetadataOptions, err = o.BuildMetadataValidator.Validate(args)
+			if err != nil {
+				return err
+			}
+			return o.RunSetBuildMetadata(fSys)
+		},
+	}
+	return cmd
+}
+
+// RunSetBuildMetadata runs setBuildMetadata command (do real work).
+func (o *setBuildMetadataOptions) RunSetBuildMetadata(fSys filesys.FileSystem) error {
+	mf, err := kustfile.NewKustomizationFile(fSys)
+	if err != nil {
+		return err
+	}
+	m, err := mf.Read()
+	if err != nil {
+		return err
+	}
+	m.BuildMetadata = o.buildMetadataOptions
+	return mf.Write(m)
+}
diff --git a/kustomize/commands/edit/set/setbuildmetadata_test.go b/kustomize/commands/edit/set/setbuildmetadata_test.go
new file mode 100644
index 0000000000..9802b189c1
--- /dev/null
+++ b/kustomize/commands/edit/set/setbuildmetadata_test.go
@@ -0,0 +1,76 @@
+// Copyright 2022 The Kubernetes Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+package set
+
+import (
+	"strings"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"sigs.k8s.io/kustomize/api/types"
+	"sigs.k8s.io/kustomize/kustomize/v4/commands/internal/kustfile"
+	testutils_test "sigs.k8s.io/kustomize/kustomize/v4/commands/internal/testutils"
+	"sigs.k8s.io/kustomize/kyaml/filesys"
+)
+
+func TestSetBuildMetadata(t *testing.T) {
+	tests := map[string]struct {
+		input       string
+		args        []string
+		expectedErr string
+	}{
+		"happy path": {
+			input: ``,
+			args:  []string{strings.Join(types.BuildMetadataOptions, ",")},
+		},
+		"option already there": {
+			input: `
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+buildMetadata: [originAnnotations]`,
+			args: []string{types.OriginAnnotations},
+		},
+		"invalid option": {
+			input:       ``,
+			args:        []string{"invalid_option"},
+			expectedErr: "invalid buildMetadata option: invalid_option",
+		},
+		"too many args": {
+			input:       ``,
+			args:        []string{"option1", "option2"},
+			expectedErr: "too many arguments: [option1 option2]; to provide multiple buildMetadata options, please separate options by comma",
+		},
+		"remove old options": {
+			input: `
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+buildMetadata: [originAnnotations, transformerAnnotations, managedByLabel]`,
+			args: []string{types.OriginAnnotations},
+		},
+	}
+
+	for _, tc := range tests {
+		fSys := filesys.MakeFsInMemory()
+		testutils_test.WriteTestKustomizationWith(fSys, []byte(tc.input))
+		cmd := newCmdSetBuildMetadata(fSys)
+		err := cmd.RunE(cmd, tc.args)
+		if tc.expectedErr != "" {
+			assert.Error(t, err)
+			assert.Contains(t, err.Error(), tc.expectedErr)
+		} else {
+			assert.NoError(t, err)
+			content, err := testutils_test.ReadTestKustomization(fSys)
+			assert.NoError(t, err)
+			args := strings.Split(tc.args[0], ",")
+			for _, opt := range args {
+				assert.Contains(t, string(content), opt)
+			}
+			mf, err := kustfile.NewKustomizationFile(fSys)
+			assert.NoError(t, err)
+			m, err := mf.Read()
+			assert.NoError(t, err)
+			assert.Equal(t, len(m.BuildMetadata), len(args))
+		}
+	}
+}
diff --git a/kustomize/commands/internal/kustfile/kustomizationfile.go b/kustomize/commands/internal/kustfile/kustomizationfile.go
index d9e9493fa1..3d569cee11 100644
--- a/kustomize/commands/internal/kustfile/kustomizationfile.go
+++ b/kustomize/commands/internal/kustfile/kustomizationfile.go
@@ -67,6 +67,7 @@ func determineFieldOrder() []string {
 		"Inventory",
 		"Components",
 		"OpenAPI",
+		"BuildMetadata",
 	}
 
 	// Add deprecated fields here.
diff --git a/kustomize/commands/internal/kustfile/kustomizationfile_test.go b/kustomize/commands/internal/kustfile/kustomizationfile_test.go
index 760ee34450..0cc0a202ed 100644
--- a/kustomize/commands/internal/kustfile/kustomizationfile_test.go
+++ b/kustomize/commands/internal/kustfile/kustomizationfile_test.go
@@ -49,6 +49,7 @@ func TestFieldOrder(t *testing.T) {
 		"Inventory",
 		"Components",
 		"OpenAPI",
+		"BuildMetadata",
 	}
 	actual := determineFieldOrder()
 	if len(expected) != len(actual) {
diff --git a/kustomize/commands/internal/util/util_test.go b/kustomize/commands/internal/util/util_test.go
index 6fab551039..ebb3742c73 100644
--- a/kustomize/commands/internal/util/util_test.go
+++ b/kustomize/commands/internal/util/util_test.go
@@ -1,3 +1,6 @@
+// Copyright 2019 The Kubernetes Authors.
+// SPDX-License-Identifier: Apache-2.0
+
 package util
 
 import (
diff --git a/kustomize/commands/internal/util/validate.go b/kustomize/commands/internal/util/validate.go
new file mode 100644
index 0000000000..2c45381677
--- /dev/null
+++ b/kustomize/commands/internal/util/validate.go
@@ -0,0 +1,31 @@
+// Copyright 2022 The Kubernetes Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+package util
+
+import (
+	"errors"
+	"fmt"
+	"strings"
+
+	"sigs.k8s.io/kustomize/api/types"
+	"sigs.k8s.io/kustomize/kustomize/v4/commands/internal/kustfile"
+)
+
+type BuildMetadataValidator struct{}
+
+func (b *BuildMetadataValidator) Validate(args []string) ([]string, error) {
+	if len(args) == 0 {
+		return nil, errors.New("must specify a buildMetadata option")
+	}
+	if len(args) > 1 {
+		return nil, fmt.Errorf("too many arguments: %s; to provide multiple buildMetadata options, please separate options by comma", args)
+	}
+	opts := strings.Split(args[0], ",")
+	for _, opt := range opts {
+		if !kustfile.StringInSlice(opt, types.BuildMetadataOptions) {
+			return nil, fmt.Errorf("invalid buildMetadata option: %s", opt)
+		}
+	}
+	return opts, nil
+}
diff --git a/plugin/builtin/prefixtransformer/PrefixTransformer.go b/plugin/builtin/prefixtransformer/PrefixTransformer.go
index 3051d06367..bb486b82e2 100644
--- a/plugin/builtin/prefixtransformer/PrefixTransformer.go
+++ b/plugin/builtin/prefixtransformer/PrefixTransformer.go
@@ -71,7 +71,7 @@ func (p *plugin) Transform(m resmap.ResMap) error {
 				if p.Prefix != "" {
 					// TODO: There are multiple transformers that can change a resource's name, and each makes a call to
 					// StorePreviousID(). We should make it so that we only call StorePreviousID once per kustomization layer
-					// to avoid storing intermediate names between transformations, to prevent intermediate name conflicts. 
+					// to avoid storing intermediate names between transformations, to prevent intermediate name conflicts.
 					r.StorePreviousId()
 				}
 			}