diff --git a/kustomize/commands/edit/remove/all.go b/kustomize/commands/edit/remove/all.go index 12c1ea94c..e7b9c3cfd 100644 --- a/kustomize/commands/edit/remove/all.go +++ b/kustomize/commands/edit/remove/all.go @@ -28,6 +28,10 @@ func NewCmdRemove( # Removes one or more secret from the kustomization file kustomize edit remove secret {name1},{name2} + # Removes one or more components from the kustomization file + kustomize edit remove component {filepath} {filepath} + kustomize edit remove component {pattern} + # Removes one or more patches from the kustomization file kustomize edit remove patch --path {filepath} --group {target group name} --version {target version} @@ -46,6 +50,7 @@ func NewCmdRemove( newCmdRemoveConfigMap(fSys), newCmdRemoveSecret(fSys), newCmdRemoveResource(fSys), + newCmdRemoveComponent(fSys), newCmdRemoveLabel(fSys, v.MakeLabelNameValidator()), newCmdRemoveAnnotation(fSys, v.MakeAnnotationNameValidator()), newCmdRemovePatch(fSys), diff --git a/kustomize/commands/edit/remove/removecomponent.go b/kustomize/commands/edit/remove/removecomponent.go new file mode 100644 index 000000000..42b71cfc7 --- /dev/null +++ b/kustomize/commands/edit/remove/removecomponent.go @@ -0,0 +1,88 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package remove + +import ( + "errors" + "fmt" + "slices" + + "github.com/spf13/cobra" + "sigs.k8s.io/kustomize/api/konfig" + "sigs.k8s.io/kustomize/kustomize/v5/commands/internal/kustfile" + "sigs.k8s.io/kustomize/kyaml/filesys" +) + +type removeComponentOptions struct { + componentFilePaths []string +} + +// newCmdRemoveComponent remove the name of a file containing a component to the kustomization file. +func newCmdRemoveComponent(fSys filesys.FileSystem) *cobra.Command { + var o removeComponentOptions + + cmd := &cobra.Command{ + Use: "component", + Short: "Removes one or more components from " + + konfig.DefaultKustomizationFileName(), + Example: ` + remove component ../../components/component1 + remove component ../../components/component1 ../../components/component2 + remove component ../../components/component* + `, + RunE: func(cmd *cobra.Command, args []string) error { + err := o.Validate(args) + if err != nil { + return err + } + return o.RunRemoveComponent(fSys) + }, + } + return cmd +} + +// Validate validates removeComponent command. +func (o *removeComponentOptions) Validate(args []string) error { + if len(args) == 0 { + return errors.New("must specify a component file") + } + o.componentFilePaths = args + return nil +} + +// RunRemoveComponent runs Component command (do real work). +func (o *removeComponentOptions) RunRemoveComponent(fSys filesys.FileSystem) error { + mf, err := kustfile.NewKustomizationFile(fSys) + if err != nil { + return fmt.Errorf("failed to read kustomization file: %w", err) + } + + m, err := mf.Read() + if err != nil { + return fmt.Errorf("failed to read kustomization file content: %w", err) + } + + components, err := globPatterns(m.Components, o.componentFilePaths) + if err != nil { + return err + } + + if len(components) == 0 { + return nil + } + + newComponents := make([]string, 0, len(m.Components)) + for _, component := range m.Components { + if slices.Contains(components, component) { + continue + } + newComponents = append(newComponents, component) + } + + m.Components = newComponents + if err := mf.Write(m); err != nil { + return fmt.Errorf("failed to write kustomization file: %w", err) + } + return nil +} diff --git a/kustomize/commands/edit/remove/removecomponent_test.go b/kustomize/commands/edit/remove/removecomponent_test.go new file mode 100644 index 000000000..ac50d87a0 --- /dev/null +++ b/kustomize/commands/edit/remove/removecomponent_test.go @@ -0,0 +1,111 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package remove + +import ( + "errors" + "testing" + + testutils_test "sigs.k8s.io/kustomize/kustomize/v5/commands/internal/testutils" +) + +func TestRemoveComponents(t *testing.T) { + testCases := []testutils_test.RemoveTestCase{ + { + Description: "remove components", + Given: testutils_test.RemoveTestGivenValues{ + Items: []string{ + "../../components/component1", + "../../components/component2", + "../../components/component3", + }, + RemoveArgs: []string{"../../components/component2"}, + }, + Expected: testutils_test.RemoveTestExpectedValues{ + Items: []string{ + "../../components/component1", + "../../components/component3", + }, + Deleted: []string{ + "../../components/component2", + }, + }, + }, + { + Description: "remove component with pattern", + Given: testutils_test.RemoveTestGivenValues{ + Items: []string{ + "../../component/component1", + "../../component/component2", + "../../component/component3", + "../../component/do_not_delete", + }, + RemoveArgs: []string{"../../component/component*"}, + }, + Expected: testutils_test.RemoveTestExpectedValues{ + Items: []string{ + "../../component/do_not_delete", + }, + Deleted: []string{ + "../../component/component1", + "../../component/component2", + "../../component/component3", + }, + }, + }, + { + Description: "nothing found to remove", + Given: testutils_test.RemoveTestGivenValues{ + Items: []string{ + "component/component1", + "component/component2", + "component/component3", + }, + RemoveArgs: []string{"component/component4"}, + }, + Expected: testutils_test.RemoveTestExpectedValues{ + Items: []string{ + "component/component1", + "component/component2", + "component/component3", + }, + }, + }, + { + Description: "no arguments", + Given: testutils_test.RemoveTestGivenValues{}, + Expected: testutils_test.RemoveTestExpectedValues{ + Err: errors.New("must specify a component file"), + }, + }, + { + Description: "remove with multiple pattern arguments", + Given: testutils_test.RemoveTestGivenValues{ + Items: []string{ + "foo/component1", + "bar/component2", + "do_not_delete", + "component3", + }, + RemoveArgs: []string{ + "foo/*", + "bar/*", + "compo*", + }, + }, + Expected: testutils_test.RemoveTestExpectedValues{ + Items: []string{ + "do_not_delete", + }, + Deleted: []string{ + "foo/component1", + "bar/component2", + "component3", + }, + }, + }, + } + + testutils_test.ExecuteRemoveTestCases(t, testCases, "components", newCmdRemoveComponent) +}