From 054a7b5389be9abba45c8f90d561bce14003cffb Mon Sep 17 00:00:00 2001 From: Adrian Orive Date: Mon, 8 Feb 2021 08:48:01 +0100 Subject: [PATCH] Export and cleanup scaffolding machinery - Export scaffolding machinery - Reorganize scaffolding machinery that was in model - Remove experimental pattern code (old plugin system) Signed-off-by: Adrian Orive --- Makefile | 2 +- pkg/machinery/errors.go | 75 +++++ pkg/machinery/errors_test.go | 48 +++ pkg/{model/file => machinery}/file.go | 16 +- pkg/{model/file => machinery}/funcmap.go | 11 +- pkg/machinery/funcmap_test.go | 45 +++ pkg/machinery/injector.go | 66 ++++ pkg/machinery/injector_test.go | 295 ++++++++++++++++++ pkg/{model/file => machinery}/interfaces.go | 14 +- .../internal/filesystem/errors.go | 0 .../internal/filesystem/errors_test.go | 0 .../internal/filesystem/filesystem.go | 0 .../filesystem/filesystem_suite_test.go | 0 .../internal/filesystem/filesystem_test.go | 0 .../internal/filesystem/mock.go | 0 .../internal/filesystem/mock_test.go | 0 .../machinery/machinery_suite_test.go | 0 pkg/{model/file => machinery}/marker.go | 8 +- pkg/machinery/marker_test.go | 47 +++ pkg/{model/file => machinery}/mixins.go | 28 +- pkg/machinery/mixins_test.go | 188 +++++++++++ .../internal => }/machinery/scaffold.go | 149 +++++---- .../internal => }/machinery/scaffold_test.go | 254 +++++++-------- .../internal => machinery}/util/exec.go | 0 .../internal => machinery}/util/go_version.go | 4 +- .../util/go_version_test.go | 0 .../internal => machinery}/util/repository.go | 0 .../internal => machinery}/util/stdin.go | 0 pkg/model/file/errors.go | 61 ---- pkg/model/plugin.go | 48 --- pkg/model/universe.go | 111 ------- pkg/plugins/declarative/v1/api.go | 19 +- .../v1/internal/templates/channel.go | 8 +- .../v1/internal/templates/controller.go | 14 +- .../v1/internal/templates/manifest.go | 10 +- .../v1/internal/templates/types.go | 16 +- pkg/plugins/golang/v2/api.go | 40 +-- pkg/plugins/golang/v2/init.go | 2 +- pkg/plugins/golang/v2/scaffolds/api.go | 55 ++-- pkg/plugins/golang/v2/scaffolds/edit.go | 6 +- pkg/plugins/golang/v2/scaffolds/init.go | 60 ++-- .../scaffolds/internal/templates/api/group.go | 12 +- .../scaffolds/internal/templates/api/types.go | 16 +- .../internal/templates/api/webhook.go | 14 +- .../config/certmanager/certificate.go | 6 +- .../config/certmanager/kustomization.go | 6 +- .../config/certmanager/kustomizeconfig.go | 6 +- .../templates/config/crd/kustomization.go | 36 +-- .../templates/config/crd/kustomizeconfig.go | 6 +- .../crd/patches/enablecainjection_patch.go | 8 +- .../config/crd/patches/enablewebhook_patch.go | 8 +- .../config/kdefault/enablecainection_patch.go | 8 +- .../config/kdefault/kustomization.go | 10 +- .../kdefault/manager_auth_proxy_patch.go | 8 +- .../config/kdefault/webhook_manager_patch.go | 6 +- .../templates/config/manager/config.go | 6 +- .../templates/config/manager/kustomization.go | 8 +- .../config/prometheus/kustomization.go | 6 +- .../templates/config/prometheus/monitor.go | 6 +- .../config/rbac/auth_proxy_client_role.go | 6 +- .../templates/config/rbac/auth_proxy_role.go | 6 +- .../config/rbac/auth_proxy_role_binding.go | 6 +- .../config/rbac/auth_proxy_service.go | 6 +- .../templates/config/rbac/crd_editor_role.go | 8 +- .../templates/config/rbac/crd_viewer_role.go | 8 +- .../templates/config/rbac/kustomization.go | 8 +- .../config/rbac/leader_election_role.go | 6 +- .../rbac/leader_election_role_binding.go | 6 +- .../templates/config/rbac/role_binding.go | 6 +- .../templates/config/samples/crd_sample.go | 12 +- .../templates/config/webhook/kustomization.go | 8 +- .../config/webhook/kustomizeconfig.go | 8 +- .../templates/config/webhook/service.go | 8 +- .../templates/controllers/controller.go | 16 +- .../controllers/controller_suitetest.go | 36 +-- .../internal/templates/dockerfile.go | 6 +- .../scaffolds/internal/templates/gitignore.go | 6 +- .../v2/scaffolds/internal/templates/gomod.go | 10 +- .../internal/templates/hack/boilerplate.go | 8 +- .../v2/scaffolds/internal/templates/main.go | 50 +-- .../scaffolds/internal/templates/makefile.go | 8 +- pkg/plugins/golang/v2/scaffolds/webhook.go | 35 +-- pkg/plugins/golang/v3/api.go | 48 +-- pkg/plugins/golang/v3/init.go | 2 +- pkg/plugins/golang/v3/scaffolds/api.go | 49 ++- pkg/plugins/golang/v3/scaffolds/edit.go | 6 +- pkg/plugins/golang/v3/scaffolds/init.go | 44 +-- .../scaffolds/internal/templates/api/group.go | 12 +- .../scaffolds/internal/templates/api/types.go | 16 +- .../internal/templates/api/webhook.go | 16 +- .../templates/api/webhook_suitetest.go | 40 +-- .../config/certmanager/certificate.go | 6 +- .../config/certmanager/kustomization.go | 6 +- .../config/certmanager/kustomizeconfig.go | 6 +- .../templates/config/crd/kustomization.go | 36 +-- .../templates/config/crd/kustomizeconfig.go | 8 +- .../crd/patches/enablecainjection_patch.go | 8 +- .../config/crd/patches/enablewebhook_patch.go | 8 +- .../config/kdefault/enablecainection_patch.go | 10 +- .../config/kdefault/kustomization.go | 12 +- .../kdefault/manager_auth_proxy_patch.go | 10 +- .../config/kdefault/manager_config_patch.go | 6 +- .../config/kdefault/webhook_manager_patch.go | 10 +- .../templates/config/manager/config.go | 8 +- .../manager/controller_manager_config.go | 12 +- .../templates/config/manager/kustomization.go | 8 +- .../config/prometheus/kustomization.go | 6 +- .../templates/config/prometheus/monitor.go | 6 +- .../config/rbac/auth_proxy_client_role.go | 6 +- .../templates/config/rbac/auth_proxy_role.go | 6 +- .../config/rbac/auth_proxy_role_binding.go | 6 +- .../config/rbac/auth_proxy_service.go | 6 +- .../templates/config/rbac/crd_editor_role.go | 8 +- .../templates/config/rbac/crd_viewer_role.go | 8 +- .../templates/config/rbac/kustomization.go | 8 +- .../config/rbac/leader_election_role.go | 6 +- .../rbac/leader_election_role_binding.go | 6 +- .../templates/config/rbac/role_binding.go | 6 +- .../templates/config/samples/crd_sample.go | 12 +- .../templates/config/webhook/kustomization.go | 12 +- .../config/webhook/kustomizeconfig.go | 8 +- .../templates/config/webhook/service.go | 8 +- .../templates/controllers/controller.go | 16 +- .../controllers/controller_suitetest.go | 36 +-- .../internal/templates/dockerfile.go | 6 +- .../internal/templates/dockerignore.go | 6 +- .../scaffolds/internal/templates/gitignore.go | 6 +- .../v3/scaffolds/internal/templates/gomod.go | 10 +- .../internal/templates/hack/boilerplate.go | 8 +- .../v3/scaffolds/internal/templates/main.go | 52 +-- .../scaffolds/internal/templates/makefile.go | 10 +- pkg/plugins/golang/v3/scaffolds/webhook.go | 38 +-- pkg/plugins/internal/machinery/errors.go | 74 ----- pkg/plugins/internal/machinery/errors_test.go | 65 ---- .../cmdutil/cmdutil.go => scaffolder.go} | 2 +- plugins/README.md | 46 --- plugins/addon/channel.go | 41 --- plugins/addon/controller.go | 108 ------- plugins/addon/helpers.go | 88 ------ plugins/addon/manifest.go | 50 --- plugins/addon/plugin.go | 28 -- plugins/addon/type.go | 126 -------- 142 files changed, 1626 insertions(+), 1848 deletions(-) create mode 100644 pkg/machinery/errors.go create mode 100644 pkg/machinery/errors_test.go rename pkg/{model/file => machinery}/file.go (75%) rename pkg/{model/file => machinery}/funcmap.go (86%) create mode 100644 pkg/machinery/funcmap_test.go create mode 100644 pkg/machinery/injector.go create mode 100644 pkg/machinery/injector_test.go rename pkg/{model/file => machinery}/interfaces.go (99%) rename pkg/{plugins => machinery}/internal/filesystem/errors.go (100%) rename pkg/{plugins => machinery}/internal/filesystem/errors_test.go (100%) rename pkg/{plugins => machinery}/internal/filesystem/filesystem.go (100%) rename pkg/{plugins => machinery}/internal/filesystem/filesystem_suite_test.go (100%) rename pkg/{plugins => machinery}/internal/filesystem/filesystem_test.go (100%) rename pkg/{plugins => machinery}/internal/filesystem/mock.go (100%) rename pkg/{plugins => machinery}/internal/filesystem/mock_test.go (100%) rename pkg/{plugins/internal => }/machinery/machinery_suite_test.go (100%) rename pkg/{model/file => machinery}/marker.go (87%) create mode 100644 pkg/machinery/marker_test.go rename pkg/{model/file => machinery}/mixins.go (99%) create mode 100644 pkg/machinery/mixins_test.go rename pkg/{plugins/internal => }/machinery/scaffold.go (69%) rename pkg/{plugins/internal => }/machinery/scaffold_test.go (64%) rename pkg/{plugins/internal => machinery}/util/exec.go (100%) rename pkg/{plugins/internal => machinery}/util/go_version.go (94%) rename pkg/{plugins/internal => machinery}/util/go_version_test.go (100%) rename pkg/{plugins/internal => machinery}/util/repository.go (100%) rename pkg/{plugins/internal => machinery}/util/stdin.go (100%) delete mode 100644 pkg/model/file/errors.go delete mode 100644 pkg/model/plugin.go delete mode 100644 pkg/model/universe.go delete mode 100644 pkg/plugins/internal/machinery/errors.go delete mode 100644 pkg/plugins/internal/machinery/errors_test.go rename pkg/plugins/{internal/cmdutil/cmdutil.go => scaffolder.go} (98%) delete mode 100644 plugins/README.md delete mode 100644 plugins/addon/channel.go delete mode 100644 plugins/addon/controller.go delete mode 100644 plugins/addon/helpers.go delete mode 100644 plugins/addon/manifest.go delete mode 100644 plugins/addon/plugin.go delete mode 100644 plugins/addon/type.go diff --git a/Makefile b/Makefile index 389384f1658..5f0173b0776 100644 --- a/Makefile +++ b/Makefile @@ -97,7 +97,7 @@ test-unit: ## Run the unit tests .PHONY: test-coverage test-coverage: ## Run unit tests creating the output to report coverage - rm -rf *.out # Remove all coverage files if exists - go test -race -failfast -tags=integration -coverprofile=coverage-all.out -coverpkg="./pkg/cli/...,./pkg/config/...,./pkg/internal/...,./pkg/model/...,./pkg/plugin/...,./pkg/plugins/golang,./pkg/plugins/internal/..." ./pkg/... + go test -race -failfast -tags=integration -coverprofile=coverage-all.out -coverpkg="./pkg/cli/...,./pkg/config/...,./pkg/internal/...,./pkg/machinery/...,./pkg/model/...,./pkg/plugin/...,./pkg/plugins/golang" ./pkg/... .PHONY: test-integration test-integration: ## Run the integration tests diff --git a/pkg/machinery/errors.go b/pkg/machinery/errors.go new file mode 100644 index 00000000000..f8aff194914 --- /dev/null +++ b/pkg/machinery/errors.go @@ -0,0 +1,75 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package machinery + +import ( + "fmt" +) + +// This file contains the errors returned by the scaffolding machinery +// They are exported to be able to check which kind of error was returned + +// ValidateError is a wrapper error that will be used for errors returned by RequiresValidation.Validate +type ValidateError struct { + error +} + +// Unwrap implements Wrapper interface +func (e ValidateError) Unwrap() error { + return e.error +} + +// SetTemplateDefaultsError is a wrapper error that will be used for errors returned by Template.SetTemplateDefaults +type SetTemplateDefaultsError struct { + error +} + +// Unwrap implements Wrapper interface +func (e SetTemplateDefaultsError) Unwrap() error { + return e.error +} + +// ModelAlreadyExistsError is returned if the file is expected not to exist but a previous model does +type ModelAlreadyExistsError struct { + path string +} + +// Error implements error interface +func (e ModelAlreadyExistsError) Error() string { + return fmt.Sprintf("failed to create %s: model already exists", e.path) +} + +// UnknownIfExistsActionError is returned if the if-exists-action is unknown +type UnknownIfExistsActionError struct { + path string + ifExistsAction IfExistsAction +} + +// Error implements error interface +func (e UnknownIfExistsActionError) Error() string { + return fmt.Sprintf("unknown behavior if file exists (%d) for %s", e.ifExistsAction, e.path) +} + +// FileAlreadyExistsError is returned if the file is expected not to exist but it does +type FileAlreadyExistsError struct { + path string +} + +// Error implements error interface +func (e FileAlreadyExistsError) Error() string { + return fmt.Sprintf("failed to create %s: file already exists", e.path) +} diff --git a/pkg/machinery/errors_test.go b/pkg/machinery/errors_test.go new file mode 100644 index 00000000000..b1513ca6a69 --- /dev/null +++ b/pkg/machinery/errors_test.go @@ -0,0 +1,48 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package machinery + +import ( + "errors" + "path/filepath" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/extensions/table" + . "github.com/onsi/gomega" +) + +var _ = Describe("Errors", func() { + var ( + path = filepath.Join("path", "to", "file") + testErr = errors.New("test error") + ) + + DescribeTable("should contain the wrapped error", + func(err error) { + Expect(errors.Is(err, testErr)).To(BeTrue()) + }, + Entry("for validate errors", ValidateError{testErr}), + Entry("for set template defaults errors", SetTemplateDefaultsError{testErr}), + ) + + // NOTE: the following test increases coverage + It("should print a descriptive error message", func() { + Expect(ModelAlreadyExistsError{path}.Error()).To(ContainSubstring("model already exists")) + Expect(UnknownIfExistsActionError{path, -1}.Error()).To(ContainSubstring("unknown behavior if file exists")) + Expect(FileAlreadyExistsError{path}.Error()).To(ContainSubstring("file already exists")) + }) +}) diff --git a/pkg/model/file/file.go b/pkg/machinery/file.go similarity index 75% rename from pkg/model/file/file.go rename to pkg/machinery/file.go index 3b9db1cd341..bf053d14ce5 100644 --- a/pkg/model/file/file.go +++ b/pkg/machinery/file.go @@ -14,30 +14,30 @@ See the License for the specific language governing permissions and limitations under the License. */ -package file +package machinery // IfExistsAction determines what to do if the scaffold file already exists type IfExistsAction int const ( - // Skip skips the file and moves to the next one - Skip IfExistsAction = iota + // SkipFile skips the file and moves to the next one + SkipFile IfExistsAction = iota // Error returns an error and stops processing Error - // Overwrite truncates and overwrites the existing file - Overwrite + // OverwriteFile truncates and overwrites the existing file + OverwriteFile ) // File describes a file that will be written type File struct { // Path is the file to write - Path string `json:"path,omitempty"` + Path string // Contents is the generated output - Contents string `json:"contents,omitempty"` + Contents string // IfExistsAction determines what to do if the file exists - IfExistsAction IfExistsAction `json:"ifExistsAction,omitempty"` + IfExistsAction IfExistsAction } diff --git a/pkg/model/file/funcmap.go b/pkg/machinery/funcmap.go similarity index 86% rename from pkg/model/file/funcmap.go rename to pkg/machinery/funcmap.go index a0a9432427b..ac25e272d70 100644 --- a/pkg/model/file/funcmap.go +++ b/pkg/machinery/funcmap.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package file +package machinery import ( "fmt" @@ -39,10 +39,9 @@ func isEmptyString(s string) bool { } // hashFNV will generate a random string useful for generating a unique string -func hashFNV(s string) (string, error) { +func hashFNV(s string) string { hasher := fnv.New32a() - if _, err := hasher.Write([]byte(s)); err != nil { - return "", err - } - return fmt.Sprintf("%x", hasher.Sum(nil)), nil + // Hash.Write never returns an error + _, _ = hasher.Write([]byte(s)) + return fmt.Sprintf("%x", hasher.Sum(nil)) } diff --git a/pkg/machinery/funcmap_test.go b/pkg/machinery/funcmap_test.go new file mode 100644 index 00000000000..7bb33df48af --- /dev/null +++ b/pkg/machinery/funcmap_test.go @@ -0,0 +1,45 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package machinery + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/extensions/table" + . "github.com/onsi/gomega" +) + +var _ = Describe("funcmap functions", func() { + Context("isEmptyString", func() { + It("should return true for empty strings", func() { + Expect(isEmptyString("")).To(BeTrue()) + }) + + DescribeTable("should return false for any other string", + func(str string) { Expect(isEmptyString(str)).To(BeFalse()) }, + Entry(`for "a"`, "a"), + Entry(`for "1"`, "1"), + Entry(`for "-"`, "-"), + Entry(`for "."`, "."), + ) + }) + + Context("hashFNV", func() { + It("should hash the input", func() { + Expect(hashFNV("test")).To(Equal("afd071e5")) + }) + }) +}) diff --git a/pkg/machinery/injector.go b/pkg/machinery/injector.go new file mode 100644 index 00000000000..5675a8a9ec3 --- /dev/null +++ b/pkg/machinery/injector.go @@ -0,0 +1,66 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package machinery + +import ( + "sigs.k8s.io/kubebuilder/v3/pkg/config" + "sigs.k8s.io/kubebuilder/v3/pkg/model/resource" +) + +// injector is used to inject certain fields to file templates. +type injector struct { + // config stores the project configuration. + config config.Config + + // boilerplate is the copyright comment added at the top of scaffolded files. + boilerplate string + + // resource contains the information of the API that is being scaffolded. + resource *resource.Resource +} + +// injectInto injects fields from the universe into the builder +func (i injector) injectInto(builder Builder) { + // Inject project configuration + if i.config != nil { + if builderWithDomain, hasDomain := builder.(HasDomain); hasDomain { + builderWithDomain.InjectDomain(i.config.GetDomain()) + } + if builderWithRepository, hasRepository := builder.(HasRepository); hasRepository { + builderWithRepository.InjectRepository(i.config.GetRepository()) + } + if builderWithProjectName, hasProjectName := builder.(HasProjectName); hasProjectName { + builderWithProjectName.InjectProjectName(i.config.GetProjectName()) + } + if builderWithMultiGroup, hasMultiGroup := builder.(HasMultiGroup); hasMultiGroup { + builderWithMultiGroup.InjectMultiGroup(i.config.IsMultiGroup()) + } + if builderWithComponentConfig, hasComponentConfig := builder.(HasComponentConfig); hasComponentConfig { + builderWithComponentConfig.InjectComponentConfig(i.config.IsComponentConfig()) + } + } + // Inject boilerplate + if builderWithBoilerplate, hasBoilerplate := builder.(HasBoilerplate); hasBoilerplate { + builderWithBoilerplate.InjectBoilerplate(i.boilerplate) + } + // Inject resource + if i.resource != nil { + if builderWithResource, hasResource := builder.(HasResource); hasResource { + builderWithResource.InjectResource(i.resource) + } + } +} diff --git a/pkg/machinery/injector_test.go b/pkg/machinery/injector_test.go new file mode 100644 index 00000000000..7c5c3038f4b --- /dev/null +++ b/pkg/machinery/injector_test.go @@ -0,0 +1,295 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package machinery + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "sigs.k8s.io/kubebuilder/v3/pkg/config" + cfgv3 "sigs.k8s.io/kubebuilder/v3/pkg/config/v3" + "sigs.k8s.io/kubebuilder/v3/pkg/model/resource" +) + +type templateBase struct { + path string + ifExistsAction IfExistsAction +} + +func (t templateBase) GetPath() string { + return t.path +} + +func (t templateBase) GetIfExistsAction() IfExistsAction { + return t.ifExistsAction +} + +type templateWithDomain struct { + templateBase + domain string +} + +func (t *templateWithDomain) InjectDomain(domain string) { + t.domain = domain +} + +type templateWithRepository struct { + templateBase + repository string +} + +func (t *templateWithRepository) InjectRepository(repository string) { + t.repository = repository +} + +type templateWithProjectName struct { + templateBase + projectName string +} + +func (t *templateWithProjectName) InjectProjectName(projectName string) { + t.projectName = projectName +} + +type templateWithMultiGroup struct { + templateBase + multiGroup bool +} + +func (t *templateWithMultiGroup) InjectMultiGroup(multiGroup bool) { + t.multiGroup = multiGroup +} + +type templateWithComponentConfig struct { + templateBase + componentConfig bool +} + +func (t *templateWithComponentConfig) InjectComponentConfig(componentConfig bool) { + t.componentConfig = componentConfig +} + +type templateWithBoilerplate struct { + templateBase + boilerplate string +} + +func (t *templateWithBoilerplate) InjectBoilerplate(boilerplate string) { + t.boilerplate = boilerplate +} + +type templateWithResource struct { + templateBase + resource *resource.Resource +} + +func (t *templateWithResource) InjectResource(res *resource.Resource) { + t.resource = res +} + +var _ = Describe("injector", func() { + var tmp = templateBase{ + path: "my/path/to/file", + ifExistsAction: Error, + } + + Context("injectInto", func() { + Context("Config", func() { + var c config.Config + + BeforeEach(func() { + c = cfgv3.New() + }) + + Context("Domain", func() { + var template *templateWithDomain + + BeforeEach(func() { + template = &templateWithDomain{templateBase: tmp} + }) + + It("should not inject anything if the config is nil", func() { + injector{}.injectInto(template) + Expect(template.domain).To(Equal("")) + }) + + It("should not inject anything if the config doesn't have a domain set", func() { + injector{config: c}.injectInto(template) + Expect(template.domain).To(Equal("")) + }) + + It("should inject if the config has a domain set", func() { + const domain = "my.domain" + Expect(c.SetDomain(domain)).To(Succeed()) + + injector{config: c}.injectInto(template) + Expect(template.domain).To(Equal(domain)) + }) + }) + + Context("Repository", func() { + var template *templateWithRepository + + BeforeEach(func() { + template = &templateWithRepository{templateBase: tmp} + }) + + It("should not inject anything if the config is nil", func() { + injector{}.injectInto(template) + Expect(template.repository).To(Equal("")) + }) + + It("should not inject anything if the config doesn't have a repository set", func() { + injector{config: c}.injectInto(template) + Expect(template.repository).To(Equal("")) + }) + + It("should inject if the config has a repository set", func() { + const repo = "test" + Expect(c.SetRepository(repo)).To(Succeed()) + + injector{config: c}.injectInto(template) + Expect(template.repository).To(Equal(repo)) + }) + }) + + Context("Project name", func() { + var template *templateWithProjectName + + BeforeEach(func() { + template = &templateWithProjectName{templateBase: tmp} + }) + + It("should not inject anything if the config is nil", func() { + injector{}.injectInto(template) + Expect(template.projectName).To(Equal("")) + }) + + It("should not inject anything if the config doesn't have a project name set", func() { + injector{config: c}.injectInto(template) + Expect(template.projectName).To(Equal("")) + }) + + It("should inject if the config has a project name set", func() { + const projectName = "my project" + Expect(c.SetProjectName(projectName)).To(Succeed()) + + injector{config: c}.injectInto(template) + Expect(template.projectName).To(Equal(projectName)) + }) + }) + + Context("Multi-group", func() { + var template *templateWithMultiGroup + + BeforeEach(func() { + template = &templateWithMultiGroup{templateBase: tmp} + }) + + It("should not inject anything if the config is nil", func() { + injector{}.injectInto(template) + Expect(template.multiGroup).To(BeFalse()) + }) + + It("should not set the flag if the config doesn't have the multi-group flag set", func() { + injector{config: c}.injectInto(template) + Expect(template.multiGroup).To(BeFalse()) + }) + + It("should set the flag if the config has the multi-group flag set", func() { + Expect(c.SetMultiGroup()).To(Succeed()) + + injector{config: c}.injectInto(template) + Expect(template.multiGroup).To(BeTrue()) + }) + }) + + Context("Component config", func() { + var template *templateWithComponentConfig + + BeforeEach(func() { + template = &templateWithComponentConfig{templateBase: tmp} + }) + + It("should not inject anything if the config is nil", func() { + injector{}.injectInto(template) + Expect(template.componentConfig).To(BeFalse()) + }) + + It("should not set the flag if the config doesn't have the component config flag set", func() { + injector{config: c}.injectInto(template) + Expect(template.componentConfig).To(BeFalse()) + }) + + It("should set the flag if the config has the component config flag set", func() { + Expect(c.SetComponentConfig()).To(Succeed()) + + injector{config: c}.injectInto(template) + Expect(template.componentConfig).To(BeTrue()) + }) + }) + }) + + Context("Boilerplate", func() { + var template *templateWithBoilerplate + + BeforeEach(func() { + template = &templateWithBoilerplate{templateBase: tmp} + }) + + It("should not inject anything if no boilerplate was set", func() { + injector{}.injectInto(template) + Expect(template.boilerplate).To(Equal("")) + }) + + It("should inject if the a boilerplate was set", func() { + const boilerplate = `Copyright "The Kubernetes Authors"` + + injector{boilerplate: boilerplate}.injectInto(template) + Expect(template.boilerplate).To(Equal(boilerplate)) + }) + }) + + Context("Resource", func() { + var template *templateWithResource + + BeforeEach(func() { + template = &templateWithResource{templateBase: tmp} + }) + + It("should not inject anything if the resource is nil", func() { + injector{}.injectInto(template) + Expect(template.resource).To(BeNil()) + }) + + It("should inject if the config has a domain set", func() { + var res = &resource.Resource{ + GVK: resource.GVK{ + Group: "group", + Domain: "my.domain", + Version: "v1", + Kind: "Kind", + }, + } + + injector{resource: res}.injectInto(template) + Expect(template.resource).To(Equal(res)) + }) + + }) + }) +}) diff --git a/pkg/model/file/interfaces.go b/pkg/machinery/interfaces.go similarity index 99% rename from pkg/model/file/interfaces.go rename to pkg/machinery/interfaces.go index 43470df4e60..73837dd8b30 100644 --- a/pkg/model/file/interfaces.go +++ b/pkg/machinery/interfaces.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package file +package machinery import ( "text/template" @@ -67,6 +67,12 @@ type HasRepository interface { InjectRepository(string) } +// HasProjectName allows a project name to be used on a template. +type HasProjectName interface { + // InjectProjectName sets the template project name. + InjectProjectName(string) +} + // HasMultiGroup allows the multi-group flag to be used on a template type HasMultiGroup interface { // InjectMultiGroup sets the template multi-group flag @@ -91,12 +97,6 @@ type HasResource interface { InjectResource(*resource.Resource) } -// HasProjectName allows a project name to be used on a template. -type HasProjectName interface { - // InjectProjectName sets the template project name. - InjectProjectName(string) -} - // UseCustomFuncMap allows a template to use a custom template.FuncMap instead of the default FuncMap. type UseCustomFuncMap interface { // GetFuncMap returns a custom FuncMap. diff --git a/pkg/plugins/internal/filesystem/errors.go b/pkg/machinery/internal/filesystem/errors.go similarity index 100% rename from pkg/plugins/internal/filesystem/errors.go rename to pkg/machinery/internal/filesystem/errors.go diff --git a/pkg/plugins/internal/filesystem/errors_test.go b/pkg/machinery/internal/filesystem/errors_test.go similarity index 100% rename from pkg/plugins/internal/filesystem/errors_test.go rename to pkg/machinery/internal/filesystem/errors_test.go diff --git a/pkg/plugins/internal/filesystem/filesystem.go b/pkg/machinery/internal/filesystem/filesystem.go similarity index 100% rename from pkg/plugins/internal/filesystem/filesystem.go rename to pkg/machinery/internal/filesystem/filesystem.go diff --git a/pkg/plugins/internal/filesystem/filesystem_suite_test.go b/pkg/machinery/internal/filesystem/filesystem_suite_test.go similarity index 100% rename from pkg/plugins/internal/filesystem/filesystem_suite_test.go rename to pkg/machinery/internal/filesystem/filesystem_suite_test.go diff --git a/pkg/plugins/internal/filesystem/filesystem_test.go b/pkg/machinery/internal/filesystem/filesystem_test.go similarity index 100% rename from pkg/plugins/internal/filesystem/filesystem_test.go rename to pkg/machinery/internal/filesystem/filesystem_test.go diff --git a/pkg/plugins/internal/filesystem/mock.go b/pkg/machinery/internal/filesystem/mock.go similarity index 100% rename from pkg/plugins/internal/filesystem/mock.go rename to pkg/machinery/internal/filesystem/mock.go diff --git a/pkg/plugins/internal/filesystem/mock_test.go b/pkg/machinery/internal/filesystem/mock_test.go similarity index 100% rename from pkg/plugins/internal/filesystem/mock_test.go rename to pkg/machinery/internal/filesystem/mock_test.go diff --git a/pkg/plugins/internal/machinery/machinery_suite_test.go b/pkg/machinery/machinery_suite_test.go similarity index 100% rename from pkg/plugins/internal/machinery/machinery_suite_test.go rename to pkg/machinery/machinery_suite_test.go diff --git a/pkg/model/file/marker.go b/pkg/machinery/marker.go similarity index 87% rename from pkg/model/file/marker.go rename to pkg/machinery/marker.go index a5b22c65502..e048615c6fa 100644 --- a/pkg/model/file/marker.go +++ b/pkg/machinery/marker.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package file +package machinery import ( "fmt" @@ -45,7 +45,11 @@ func NewMarkerFor(path string, value string) Marker { return Marker{comment, value} } - panic(fmt.Errorf("unknown file extension: '%s', expected '.go', '.yaml' or '.yml'", ext)) + extensions := make([]string, 0, len(commentsByExt)) + for extension := range commentsByExt { + extensions = append(extensions, fmt.Sprintf("%q", extension)) + } + panic(fmt.Errorf("unknown file extension: '%s', expected one of: %s", ext, strings.Join(extensions, ", "))) } // String implements Stringer diff --git a/pkg/machinery/marker_test.go b/pkg/machinery/marker_test.go new file mode 100644 index 00000000000..2f4468ff042 --- /dev/null +++ b/pkg/machinery/marker_test.go @@ -0,0 +1,47 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package machinery + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/extensions/table" + . "github.com/onsi/gomega" +) + +var _ = Describe("NerMarkerFor", func() { + DescribeTable("should create valid markers for known extensions", + func(path, comment string) { Expect(NewMarkerFor(path, "").comment).To(Equal(comment)) }, + Entry("for go files", "file.go", "//"), + Entry("for yaml files", "file.yaml", "#"), + Entry("for yaml files (short version)", "file.yml", "#"), + ) + + It("should panic for unknown extensions", func() { + // testing panics require to use a function with no arguments + Expect(func() { NewMarkerFor("file.unkownext", "") }).To(Panic()) + }) +}) + +var _ = Describe("Marker", func() { + Context("String", func() { + DescribeTable("should return the right string representation", + func(marker Marker, str string) { Expect(marker.String()).To(Equal(str)) }, + Entry("for go files", Marker{comment: "//", value: "test"}, "//+kubebuilder:scaffold:test"), + Entry("for yaml files", Marker{comment: "#", value: "test"}, "#+kubebuilder:scaffold:test"), + ) + }) +}) diff --git a/pkg/model/file/mixins.go b/pkg/machinery/mixins.go similarity index 99% rename from pkg/model/file/mixins.go rename to pkg/machinery/mixins.go index fcf1dbbbf58..9529e687bf6 100644 --- a/pkg/model/file/mixins.go +++ b/pkg/machinery/mixins.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package file +package machinery import ( "sigs.k8s.io/kubebuilder/v3/pkg/model/resource" @@ -64,7 +64,7 @@ type InserterMixin struct { // GetIfExistsAction implements Builder func (t *InserterMixin) GetIfExistsAction() IfExistsAction { // Inserter builders always need to overwrite previous files - return Overwrite + return OverwriteFile } // DomainMixin provides templates with a injectable domain field @@ -93,6 +93,18 @@ func (m *RepositoryMixin) InjectRepository(repository string) { } } +// ProjectNameMixin provides templates with an injectable project name field. +type ProjectNameMixin struct { + ProjectName string +} + +// InjectProjectName implements HasProjectName. +func (m *ProjectNameMixin) InjectProjectName(projectName string) { + if m.ProjectName == "" { + m.ProjectName = projectName + } +} + // MultiGroupMixin provides templates with a injectable multi-group flag field type MultiGroupMixin struct { // MultiGroup is the multi-group flag @@ -139,15 +151,3 @@ func (m *ResourceMixin) InjectResource(res *resource.Resource) { m.Resource = res } } - -// ProjectNameMixin provides templates with an injectable project name field. -type ProjectNameMixin struct { - ProjectName string -} - -// InjectProjectName implements HasProjectName. -func (m *ProjectNameMixin) InjectProjectName(projectName string) { - if m.ProjectName == "" { - m.ProjectName = projectName - } -} diff --git a/pkg/machinery/mixins_test.go b/pkg/machinery/mixins_test.go new file mode 100644 index 00000000000..944e4c0c195 --- /dev/null +++ b/pkg/machinery/mixins_test.go @@ -0,0 +1,188 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package machinery + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "sigs.k8s.io/kubebuilder/v3/pkg/model/resource" +) + +type mockTemplate struct { + TemplateMixin + DomainMixin + RepositoryMixin + ProjectNameMixin + MultiGroupMixin + ComponentConfigMixin + BoilerplateMixin + ResourceMixin +} + +type mockInserter struct { + // InserterMixin requires a different type because it collides with TemplateMixin + InserterMixin +} + +var _ = Describe("TemplateMixin", func() { + const ( + path = "path/to/file.go" + ifExistsAction = SkipFile + body = "content" + ) + + var tmp = mockTemplate{ + TemplateMixin: TemplateMixin{ + PathMixin: PathMixin{path}, + IfExistsActionMixin: IfExistsActionMixin{ifExistsAction}, + TemplateBody: body, + }, + } + + Context("GetPath", func() { + It("should return the path", func() { + Expect(tmp.GetPath()).To(Equal(path)) + }) + }) + + Context("GetIfExistsAction", func() { + It("should return the if-exists action", func() { + Expect(tmp.GetIfExistsAction()).To(Equal(ifExistsAction)) + }) + }) + + Context("GetBody", func() { + It("should return the body", func() { + Expect(tmp.GetBody()).To(Equal(body)) + }) + }) +}) + +var _ = Describe("InserterMixin", func() { + const path = "path/to/file.go" + + var tmp = mockInserter{ + InserterMixin: InserterMixin{ + PathMixin: PathMixin{path}, + }, + } + + Context("GetPath", func() { + It("should return the path", func() { + Expect(tmp.GetPath()).To(Equal(path)) + }) + }) + + Context("GetIfExistsAction", func() { + It("should return overwrite file always", func() { + Expect(tmp.GetIfExistsAction()).To(Equal(OverwriteFile)) + }) + }) +}) + +var _ = Describe("DomainMixin", func() { + const domain = "my.domain" + + var tmp = mockTemplate{} + + Context("InjectDomain", func() { + It("should inject the provided domain", func() { + tmp.InjectDomain(domain) + Expect(tmp.Domain).To(Equal(domain)) + }) + }) +}) + +var _ = Describe("RepositoryMixin", func() { + const repo = "test" + + var tmp = mockTemplate{} + + Context("InjectRepository", func() { + It("should inject the provided repository", func() { + tmp.InjectRepository(repo) + Expect(tmp.Repo).To(Equal(repo)) + }) + }) +}) + +var _ = Describe("ProjectNameMixin", func() { + const name = "my project" + + var tmp = mockTemplate{} + + Context("InjectProjectName", func() { + It("should inject the provided project name", func() { + tmp.InjectProjectName(name) + Expect(tmp.ProjectName).To(Equal(name)) + }) + }) +}) + +var _ = Describe("MultiGroupMixin", func() { + var tmp = mockTemplate{} + + Context("InjectMultiGroup", func() { + It("should inject the provided multi group flag", func() { + tmp.InjectMultiGroup(true) + Expect(tmp.MultiGroup).To(BeTrue()) + }) + }) +}) + +var _ = Describe("ComponentConfigMixin", func() { + var tmp = mockTemplate{} + + Context("InjectComponentConfig", func() { + It("should inject the provided component config flag", func() { + tmp.InjectComponentConfig(true) + Expect(tmp.ComponentConfig).To(BeTrue()) + }) + }) +}) + +var _ = Describe("BoilerplateMixin", func() { + const boilerplate = "Copyright" + + var tmp = mockTemplate{} + + Context("InjectBoilerplate", func() { + It("should inject the provided boilerplate", func() { + tmp.InjectBoilerplate(boilerplate) + Expect(tmp.Boilerplate).To(Equal(boilerplate)) + }) + }) +}) + +var _ = Describe("ResourceMixin", func() { + var res = &resource.Resource{GVK: resource.GVK{ + Group: "group", + Domain: "my.domain", + Version: "v1", + Kind: "Kind", + }} + + var tmp = mockTemplate{} + + Context("InjectResource", func() { + It("should inject the provided resource", func() { + tmp.InjectResource(res) + Expect(tmp.Resource.GVK.IsEqualTo(res.GVK)).To(BeTrue()) + }) + }) +}) diff --git a/pkg/plugins/internal/machinery/scaffold.go b/pkg/machinery/scaffold.go similarity index 69% rename from pkg/plugins/internal/machinery/scaffold.go rename to pkg/machinery/scaffold.go index 90dcee43a9b..bfcfd1a3118 100644 --- a/pkg/plugins/internal/machinery/scaffold.go +++ b/pkg/machinery/scaffold.go @@ -28,9 +28,9 @@ import ( "github.com/spf13/afero" "golang.org/x/tools/imports" - "sigs.k8s.io/kubebuilder/v3/pkg/model" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/filesystem" + "sigs.k8s.io/kubebuilder/v3/pkg/config" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery/internal/filesystem" + "sigs.k8s.io/kubebuilder/v3/pkg/model/resource" ) var options = imports.Options{ @@ -43,71 +43,90 @@ var options = imports.Options{ // Scaffold uses templates to scaffold new files type Scaffold interface { // Execute writes to disk the provided files - Execute(*model.Universe, ...file.Builder) error + Execute(...Builder) error } // scaffold implements Scaffold interface type scaffold struct { - // plugins is the list of plugins we should allow to transform our generated scaffolding - plugins []model.Plugin - // fs allows to mock the file system for tests fs filesystem.FileSystem + + // injector is used to provide several fields to the templates + injector injector } +// ScaffoldOption allows to provide optional arguments to the Scaffold +type ScaffoldOption func(*scaffold) + // NewScaffold returns a new Scaffold with the provided plugins -func NewScaffold(fs afero.Fs, plugins ...model.Plugin) Scaffold { - return &scaffold{ - plugins: plugins, - fs: filesystem.New(fs), +func NewScaffold(fs afero.Fs, options ...ScaffoldOption) Scaffold { + s := &scaffold{fs: filesystem.New(fs)} + + for _, option := range options { + option(s) } + + return s } -// Execute implements Scaffold.Execute -func (s *scaffold) Execute(universe *model.Universe, files ...file.Builder) error { - // Initialize the universe files - universe.Files = make(map[string]*file.File, len(files)) +// WithConfig provides the project configuration to the Scaffold +func WithConfig(cfg config.Config) ScaffoldOption { + return func(s *scaffold) { + s.injector.config = cfg - // Set the repo as the local prefix so that it knows how to group imports - if universe.Config != nil { - imports.LocalPrefix = universe.Config.GetRepository() + if cfg != nil && cfg.GetRepository() != "" { + imports.LocalPrefix = cfg.GetRepository() + } } +} - for _, f := range files { +// WithBoilerplate provides the boilerplate to the Scaffold +func WithBoilerplate(boilerplate string) ScaffoldOption { + return func(s *scaffold) { + s.injector.boilerplate = boilerplate + } +} + +// WithResource provides the resource to the Scaffold +func WithResource(resource *resource.Resource) ScaffoldOption { + return func(s *scaffold) { + s.injector.resource = resource + } +} + +// Execute implements Scaffold.Execute +func (s *scaffold) Execute(builders ...Builder) error { + // Initialize the files + files := make(map[string]*File, len(builders)) + + for _, builder := range builders { // Inject common fields - universe.InjectInto(f) + s.injector.injectInto(builder) // Validate file builders - if reqValFile, requiresValidation := f.(file.RequiresValidation); requiresValidation { - if err := reqValFile.Validate(); err != nil { - return file.NewValidateError(err) + if reqValBuilder, requiresValidation := builder.(RequiresValidation); requiresValidation { + if err := reqValBuilder.Validate(); err != nil { + return ValidateError{err} } } // Build models for Template builders - if t, isTemplate := f.(file.Template); isTemplate { - if err := s.buildFileModel(t, universe.Files); err != nil { + if t, isTemplate := builder.(Template); isTemplate { + if err := s.buildFileModel(t, files); err != nil { return err } } // Build models for Inserter builders - if i, isInserter := f.(file.Inserter); isInserter { - if err := s.updateFileModel(i, universe.Files); err != nil { + if i, isInserter := builder.(Inserter); isInserter { + if err := s.updateFileModel(i, files); err != nil { return err } } } - // Execute plugins - for _, plugin := range s.plugins { - if err := plugin.Pipe(universe); err != nil { - return model.NewPluginError(err) - } - } - // Persist the files to disk - for _, f := range universe.Files { + for _, f := range files { if err := s.writeFile(f); err != nil { return err } @@ -117,27 +136,27 @@ func (s *scaffold) Execute(universe *model.Universe, files ...file.Builder) erro } // buildFileModel scaffolds a single file -func (scaffold) buildFileModel(t file.Template, models map[string]*file.File) error { +func (scaffold) buildFileModel(t Template, models map[string]*File) error { // Set the template default values err := t.SetTemplateDefaults() if err != nil { - return file.NewSetTemplateDefaultsError(err) + return SetTemplateDefaultsError{err} } // Handle already existing models if _, found := models[t.GetPath()]; found { switch t.GetIfExistsAction() { - case file.Skip: + case SkipFile: return nil - case file.Error: - return modelAlreadyExistsError{t.GetPath()} - case file.Overwrite: + case Error: + return ModelAlreadyExistsError{t.GetPath()} + case OverwriteFile: default: - return unknownIfExistsActionError{t.GetPath(), t.GetIfExistsAction()} + return UnknownIfExistsActionError{t.GetPath(), t.GetIfExistsAction()} } } - m := &file.File{ + m := &File{ Path: t.GetPath(), IfExistsAction: t.GetIfExistsAction(), } @@ -153,7 +172,7 @@ func (scaffold) buildFileModel(t file.Template, models map[string]*file.File) er } // doTemplate executes the template for a file using the input -func doTemplate(t file.Template) ([]byte, error) { +func doTemplate(t Template) ([]byte, error) { temp, err := newTemplate(t).Parse(t.GetBody()) if err != nil { return nil, err @@ -179,9 +198,9 @@ func doTemplate(t file.Template) ([]byte, error) { } // newTemplate a new template with common functions -func newTemplate(t file.Template) *template.Template { - fm := file.DefaultFuncMap() - useFM, ok := t.(file.UseCustomFuncMap) +func newTemplate(t Template) *template.Template { + fm := DefaultFuncMap() + useFM, ok := t.(UseCustomFuncMap) if ok { fm = useFM.GetFuncMap() } @@ -189,7 +208,7 @@ func newTemplate(t file.Template) *template.Template { } // updateFileModel updates a single file -func (s scaffold) updateFileModel(i file.Inserter, models map[string]*file.File) error { +func (s scaffold) updateFileModel(i Inserter, models map[string]*File) error { m, err := s.loadPreviousModel(i, models) if err != nil { return err @@ -224,13 +243,13 @@ func (s scaffold) updateFileModel(i file.Inserter, models map[string]*file.File) } m.Contents = string(formattedContent) - m.IfExistsAction = file.Overwrite + m.IfExistsAction = OverwriteFile models[m.Path] = m return nil } // loadPreviousModel gets the previous model from the models map or the actual file -func (s scaffold) loadPreviousModel(i file.Inserter, models map[string]*file.File) (*file.File, error) { +func (s scaffold) loadPreviousModel(i Inserter, models map[string]*File) (*File, error) { // Lets see if we already have a model for this file if m, found := models[i.GetPath()]; found { // Check if there is already an scaffolded file @@ -246,21 +265,21 @@ func (s scaffold) loadPreviousModel(i file.Inserter, models map[string]*file.Fil // If both a model and a file are found, check which has preference switch m.IfExistsAction { - case file.Skip: + case SkipFile: // File has preference fromFile, err := s.loadModelFromFile(i.GetPath()) if err != nil { return m, nil } return fromFile, nil - case file.Error: + case Error: // Writing will result in an error, so we can return error now - return nil, fileAlreadyExistsError{i.GetPath()} - case file.Overwrite: + return nil, FileAlreadyExistsError{i.GetPath()} + case OverwriteFile: // Model has preference return m, nil default: - return nil, unknownIfExistsActionError{i.GetPath(), m.IfExistsAction} + return nil, UnknownIfExistsActionError{i.GetPath(), m.IfExistsAction} } } @@ -269,7 +288,7 @@ func (s scaffold) loadPreviousModel(i file.Inserter, models map[string]*file.Fil } // loadModelFromFile gets the previous model from the actual file -func (s scaffold) loadModelFromFile(path string) (f *file.File, err error) { +func (s scaffold) loadModelFromFile(path string) (f *File, err error) { reader, err := s.fs.Open(path) if err != nil { return @@ -286,12 +305,12 @@ func (s scaffold) loadModelFromFile(path string) (f *file.File, err error) { return } - f = &file.File{Path: path, Contents: string(content)} + f = &File{Path: path, Contents: string(content)} return } // getValidCodeFragments obtains the code fragments from a file.Inserter -func getValidCodeFragments(i file.Inserter) file.CodeFragmentsMap { +func getValidCodeFragments(i Inserter) CodeFragmentsMap { // Get the code fragments codeFragments := i.GetCodeFragments() @@ -315,7 +334,7 @@ func getValidCodeFragments(i file.Inserter) file.CodeFragmentsMap { // filterExistingValues removes the single-line values that already exists // TODO: Add support for multi-line duplicate values -func filterExistingValues(content string, codeFragmentsMap file.CodeFragmentsMap) error { +func filterExistingValues(content string, codeFragmentsMap CodeFragmentsMap) error { scanner := bufio.NewScanner(strings.NewReader(content)) for scanner.Scan() { line := scanner.Text() @@ -336,7 +355,7 @@ func filterExistingValues(content string, codeFragmentsMap file.CodeFragmentsMap return nil } -func insertStrings(content string, codeFragmentsMap file.CodeFragmentsMap) ([]byte, error) { +func insertStrings(content string, codeFragmentsMap CodeFragmentsMap) ([]byte, error) { out := new(bytes.Buffer) scanner := bufio.NewScanner(strings.NewReader(content)) @@ -360,7 +379,7 @@ func insertStrings(content string, codeFragmentsMap file.CodeFragmentsMap) ([]by return out.Bytes(), nil } -func (s scaffold) writeFile(f *file.File) error { +func (s scaffold) writeFile(f *File) error { // Check if the file to write already exists exists, err := s.fs.Exists(f.Path) if err != nil { @@ -368,14 +387,14 @@ func (s scaffold) writeFile(f *file.File) error { } if exists { switch f.IfExistsAction { - case file.Overwrite: + case OverwriteFile: // By not returning, the file is written as if it didn't exist - case file.Skip: + case SkipFile: // By returning nil, the file is not written but the process will carry on return nil - case file.Error: + case Error: // By returning an error, the file is not written and the process will fail - return fileAlreadyExistsError{f.Path} + return FileAlreadyExistsError{f.Path} } } diff --git a/pkg/plugins/internal/machinery/scaffold_test.go b/pkg/machinery/scaffold_test.go similarity index 64% rename from pkg/plugins/internal/machinery/scaffold_test.go rename to pkg/machinery/scaffold_test.go index 8e48c28d018..8ea8214cb43 100644 --- a/pkg/plugins/internal/machinery/scaffold_test.go +++ b/pkg/machinery/scaffold_test.go @@ -23,74 +23,60 @@ import ( . "github.com/onsi/gomega" "github.com/spf13/afero" - "sigs.k8s.io/kubebuilder/v3/pkg/model" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/filesystem" + cfgv3 "sigs.k8s.io/kubebuilder/v3/pkg/config/v3" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery/internal/filesystem" + "sigs.k8s.io/kubebuilder/v3/pkg/model/resource" ) var _ = Describe("Scaffold", func() { Describe("NewScaffold", func() { - var ( - si Scaffold - s *scaffold - ok bool - ) - - Context("when using no plugins", func() { - BeforeEach(func() { - si = NewScaffold(afero.NewMemMapFs()) - s, ok = si.(*scaffold) - }) - - It("should be a scaffold instance", func() { - Expect(ok).To(BeTrue()) - }) - - It("should not have a nil fs", func() { - Expect(s.fs).NotTo(BeNil()) - }) - - It("should not have any plugin", func() { - Expect(len(s.plugins)).To(Equal(0)) - }) + It("should succeed for no option", func() { + s, ok := NewScaffold(afero.NewMemMapFs()).(*scaffold) + Expect(ok).To(BeTrue()) + Expect(s.fs).NotTo(BeNil()) + Expect(s.injector.config).To(BeNil()) + Expect(s.injector.boilerplate).To(Equal("")) + Expect(s.injector.resource).To(BeNil()) }) - Context("when using one plugin", func() { - BeforeEach(func() { - si = NewScaffold(afero.NewMemMapFs(), fakePlugin{}) - s, ok = si.(*scaffold) - }) + It("should succeed with config option", func() { + cfg := cfgv3.New() - It("should be a scaffold instance", func() { - Expect(ok).To(BeTrue()) - }) - - It("should not have a nil fs", func() { - Expect(s.fs).NotTo(BeNil()) - }) - - It("should have one plugin", func() { - Expect(len(s.plugins)).To(Equal(1)) - }) + s, ok := NewScaffold(afero.NewMemMapFs(), WithConfig(cfg)).(*scaffold) + Expect(ok).To(BeTrue()) + Expect(s.fs).NotTo(BeNil()) + Expect(s.injector.config).NotTo(BeNil()) + Expect(s.injector.config.GetVersion().Compare(cfgv3.Version)).To(Equal(0)) + Expect(s.injector.boilerplate).To(Equal("")) + Expect(s.injector.resource).To(BeNil()) }) - Context("when using several plugins", func() { - BeforeEach(func() { - si = NewScaffold(afero.NewMemMapFs(), fakePlugin{}, fakePlugin{}, fakePlugin{}) - s, ok = si.(*scaffold) - }) + It("should succeed with boilerplate option", func() { + const boilerplate = "Copyright" - It("should be a scaffold instance", func() { - Expect(ok).To(BeTrue()) - }) - - It("should not have a nil fs", func() { - Expect(s.fs).NotTo(BeNil()) - }) + s, ok := NewScaffold(afero.NewMemMapFs(), WithBoilerplate(boilerplate)).(*scaffold) + Expect(ok).To(BeTrue()) + Expect(s.fs).NotTo(BeNil()) + Expect(s.injector.config).To(BeNil()) + Expect(s.injector.boilerplate).To(Equal(boilerplate)) + Expect(s.injector.resource).To(BeNil()) + }) - It("should have several plugins", func() { - Expect(len(s.plugins)).To(Equal(3)) - }) + It("should succeed with resource option", func() { + var res = &resource.Resource{GVK: resource.GVK{ + Group: "group", + Domain: "my.domain", + Version: "v1", + Kind: "Kind", + }} + + s, ok := NewScaffold(afero.NewMemMapFs(), WithResource(res)).(*scaffold) + Expect(ok).To(BeTrue()) + Expect(s.fs).NotTo(BeNil()) + Expect(s.injector.config).To(BeNil()) + Expect(s.injector.boilerplate).To(Equal("")) + Expect(s.injector.resource).NotTo(BeNil()) + Expect(s.injector.resource.GVK.IsEqualTo(res.GVK)).To(BeTrue()) }) }) @@ -107,14 +93,14 @@ var _ = Describe("Scaffold", func() { }) DescribeTable("successes", - func(expected string, files ...file.Builder) { + func(expected string, files ...Builder) { s := &scaffold{ fs: filesystem.NewMock( filesystem.MockOutput(&output), ), } - Expect(s.Execute(model.NewUniverse(), files...)).To(Succeed()) + Expect(s.Execute(files...)).To(Succeed()) Expect(output.String()).To(Equal(expected)) }, Entry("should write the file", @@ -129,7 +115,7 @@ var _ = Describe("Scaffold", func() { Entry("should overwrite required models if already have one", fileContent, fakeTemplate{}, - fakeTemplate{fakeBuilder: fakeBuilder{ifExistsAction: file.Overwrite}, body: fileContent}, + fakeTemplate{fakeBuilder: fakeBuilder{ifExistsAction: OverwriteFile}, body: fileContent}, ), Entry("should format a go file", "package file\n", @@ -138,26 +124,28 @@ var _ = Describe("Scaffold", func() { ) DescribeTable("file builders related errors", - func(f func(error) bool, files ...file.Builder) { + func(errType error, files ...Builder) { s := &scaffold{fs: filesystem.NewMock()} - Expect(f(s.Execute(model.NewUniverse(), files...))).To(BeTrue()) + err := s.Execute(files...) + Expect(err).To(HaveOccurred()) + Expect(errors.As(err, &errType)).To(BeTrue()) }, Entry("should fail if unable to validate a file builder", - file.IsValidateError, + ValidateError{}, fakeRequiresValidation{validateErr: testErr}, ), Entry("should fail if unable to set default values for a template", - file.IsSetTemplateDefaultsError, + SetTemplateDefaultsError{}, fakeTemplate{err: testErr}, ), Entry("should fail if an unexpected previous model is found", - IsModelAlreadyExistsError, + ModelAlreadyExistsError{}, fakeTemplate{fakeBuilder: fakeBuilder{path: "filename"}}, - fakeTemplate{fakeBuilder: fakeBuilder{path: "filename", ifExistsAction: file.Error}}, + fakeTemplate{fakeBuilder: fakeBuilder{path: "filename", ifExistsAction: Error}}, ), Entry("should fail if behavior if file exists is not defined", - IsUnknownIfExistsActionError, + UnknownIfExistsActionError{}, fakeTemplate{fakeBuilder: fakeBuilder{path: "filename"}}, fakeTemplate{fakeBuilder: fakeBuilder{path: "filename", ifExistsAction: -1}}, ), @@ -165,10 +153,10 @@ var _ = Describe("Scaffold", func() { // Following errors are unwrapped, so we need to check for substrings DescribeTable("template related errors", - func(errMsg string, files ...file.Builder) { + func(errMsg string, files ...Builder) { s := &scaffold{fs: filesystem.NewMock()} - err := s.Execute(model.NewUniverse(), files...) + err := s.Execute(files...) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring(errMsg)) }, @@ -187,7 +175,7 @@ var _ = Describe("Scaffold", func() { ) DescribeTable("insert strings", - func(input, expected string, files ...file.Builder) { + func(input, expected string, files ...Builder) { s := &scaffold{ fs: filesystem.NewMock( filesystem.MockInput(bytes.NewBufferString(input)), @@ -196,7 +184,7 @@ var _ = Describe("Scaffold", func() { ), } - Expect(s.Execute(model.NewUniverse(), files...)).To(Succeed()) + Expect(s.Execute(files...)).To(Succeed()) Expect(output.String()).To(Equal(expected)) }, Entry("should insert lines for go files", @@ -208,8 +196,8 @@ var _ = Describe("Scaffold", func() { 2 //+kubebuilder:scaffold:- `, - fakeInserter{codeFragments: file.CodeFragmentsMap{ - file.NewMarkerFor("file.go", "-"): {"1\n", "2\n"}}, + fakeInserter{codeFragments: CodeFragmentsMap{ + NewMarkerFor("file.go", "-"): {"1\n", "2\n"}}, }, ), Entry("should insert lines for yaml files", @@ -221,8 +209,8 @@ var _ = Describe("Scaffold", func() { 2 #+kubebuilder:scaffold:- `, - fakeInserter{codeFragments: file.CodeFragmentsMap{ - file.NewMarkerFor("file.yaml", "-"): {"1\n", "2\n"}}, + fakeInserter{codeFragments: CodeFragmentsMap{ + NewMarkerFor("file.yaml", "-"): {"1\n", "2\n"}}, }, ), Entry("should use models if there is no file", @@ -232,11 +220,11 @@ var _ = Describe("Scaffold", func() { 2 //+kubebuilder:scaffold:- `, - fakeTemplate{fakeBuilder: fakeBuilder{ifExistsAction: file.Overwrite}, body: ` + fakeTemplate{fakeBuilder: fakeBuilder{ifExistsAction: OverwriteFile}, body: ` //+kubebuilder:scaffold:- `}, - fakeInserter{codeFragments: file.CodeFragmentsMap{ - file.NewMarkerFor("file.go", "-"): {"1\n", "2\n"}}, + fakeInserter{codeFragments: CodeFragmentsMap{ + NewMarkerFor("file.go", "-"): {"1\n", "2\n"}}, }, ), Entry("should use required models over files", @@ -246,11 +234,11 @@ var _ = Describe("Scaffold", func() { 2 //+kubebuilder:scaffold:- `, - fakeTemplate{fakeBuilder: fakeBuilder{ifExistsAction: file.Overwrite}, body: ` + fakeTemplate{fakeBuilder: fakeBuilder{ifExistsAction: OverwriteFile}, body: ` //+kubebuilder:scaffold:- `}, - fakeInserter{codeFragments: file.CodeFragmentsMap{ - file.NewMarkerFor("file.go", "-"): {"1\n", "2\n"}}, + fakeInserter{codeFragments: CodeFragmentsMap{ + NewMarkerFor("file.go", "-"): {"1\n", "2\n"}}, }, ), Entry("should use files over optional models", @@ -264,8 +252,8 @@ var _ = Describe("Scaffold", func() { `, fakeTemplate{body: fileContent}, fakeInserter{ - codeFragments: file.CodeFragmentsMap{ - file.NewMarkerFor("file.go", "-"): {"1\n", "2\n"}, + codeFragments: CodeFragmentsMap{ + NewMarkerFor("file.go", "-"): {"1\n", "2\n"}, }, }, ), @@ -281,10 +269,10 @@ var _ = Describe("Scaffold", func() { //+kubebuilder:scaffold:* `, fakeInserter{ - markers: []file.Marker{file.NewMarkerFor("file.go", "-")}, - codeFragments: file.CodeFragmentsMap{ - file.NewMarkerFor("file.go", "-"): {"1\n", "2\n"}, - file.NewMarkerFor("file.go", "*"): {"3\n", "4\n"}, + markers: []Marker{NewMarkerFor("file.go", "-")}, + codeFragments: CodeFragmentsMap{ + NewMarkerFor("file.go", "-"): {"1\n", "2\n"}, + NewMarkerFor("file.go", "*"): {"3\n", "4\n"}, }, }, ), @@ -305,9 +293,9 @@ var _ = Describe("Scaffold", func() { //+kubebuilder:scaffold:* `, fakeInserter{ - codeFragments: file.CodeFragmentsMap{ - file.NewMarkerFor("file.go", "-"): {"1\n", "2\n"}, - file.NewMarkerFor("file.go", "*"): {"3\n", "4\n"}, + codeFragments: CodeFragmentsMap{ + NewMarkerFor("file.go", "-"): {"1\n", "2\n"}, + NewMarkerFor("file.go", "*"): {"3\n", "4\n"}, }, }, ), @@ -320,51 +308,37 @@ var _ = Describe("Scaffold", func() { //+kubebuilder:scaffold:- `}, fakeInserter{ - codeFragments: file.CodeFragmentsMap{ - file.NewMarkerFor("file.go", "-"): {}, + codeFragments: CodeFragmentsMap{ + NewMarkerFor("file.go", "-"): {}, }, }, ), ) DescribeTable("insert strings related errors", - func(f func(error) bool, files ...file.Builder) { + func(errType error, files ...Builder) { s := &scaffold{ fs: filesystem.NewMock( filesystem.MockExists(func(_ string) bool { return true }), ), } - err := s.Execute(model.NewUniverse(), files...) + err := s.Execute(files...) Expect(err).To(HaveOccurred()) - Expect(f(err)).To(BeTrue()) + Expect(errors.As(err, &errType)).To(BeTrue()) }, Entry("should fail if inserting into a model that fails when a file exists and it does exist", - IsFileAlreadyExistsError, - fakeTemplate{fakeBuilder: fakeBuilder{path: "filename", ifExistsAction: file.Error}}, + FileAlreadyExistsError{}, + fakeTemplate{fakeBuilder: fakeBuilder{path: "filename", ifExistsAction: Error}}, fakeInserter{fakeBuilder: fakeBuilder{path: "filename"}}, ), Entry("should fail if inserting into a model with unknown behavior if the file exists and it does exist", - IsUnknownIfExistsActionError, + UnknownIfExistsActionError{}, fakeTemplate{fakeBuilder: fakeBuilder{path: "filename", ifExistsAction: -1}}, fakeInserter{fakeBuilder: fakeBuilder{path: "filename"}}, ), ) - It("should fail if a plugin fails", func() { - s := &scaffold{ - fs: filesystem.NewMock(), - plugins: []model.Plugin{fakePlugin{err: testErr}}, - } - - err := s.Execute( - model.NewUniverse(), - fakeTemplate{}, - ) - Expect(err).To(MatchError(testErr)) - Expect(model.IsPluginError(err)).To(BeTrue()) - }) - Context("write when the file already exists", func() { var s Scaffold @@ -378,28 +352,22 @@ var _ = Describe("Scaffold", func() { }) It("should skip the file by default", func() { - Expect(s.Execute( - model.NewUniverse(), - fakeTemplate{body: fileContent}, - )).To(Succeed()) + Expect(s.Execute(fakeTemplate{body: fileContent})).To(Succeed()) Expect(output.String()).To(BeEmpty()) }) It("should write the file if configured to do so", func() { - Expect(s.Execute( - model.NewUniverse(), - fakeTemplate{fakeBuilder: fakeBuilder{ifExistsAction: file.Overwrite}, body: fileContent}, - )).To(Succeed()) + Expect(s.Execute(fakeTemplate{ + fakeBuilder: fakeBuilder{ifExistsAction: OverwriteFile}, + body: fileContent, + })).To(Succeed()) Expect(output.String()).To(Equal(fileContent)) }) It("should error if configured to do so", func() { - err := s.Execute( - model.NewUniverse(), - fakeTemplate{fakeBuilder: fakeBuilder{path: "filename", ifExistsAction: file.Error}, body: fileContent}, - ) + err := s.Execute(fakeTemplate{fakeBuilder: fakeBuilder{path: "filename", ifExistsAction: Error}, body: fileContent}) Expect(err).To(HaveOccurred()) - Expect(IsFileAlreadyExistsError(err)).To(BeTrue()) + Expect(errors.As(err, &FileAlreadyExistsError{})).To(BeTrue()) Expect(output.String()).To(BeEmpty()) }) }) @@ -408,7 +376,7 @@ var _ = Describe("Scaffold", func() { func( mockErrorF func(error) filesystem.MockOptions, checkErrorF func(error) bool, - files ...file.Builder, + files ...Builder, ) { s := &scaffold{ fs: filesystem.NewMock( @@ -416,7 +384,7 @@ var _ = Describe("Scaffold", func() { ), } - err := s.Execute(model.NewUniverse(), files...) + err := s.Execute(files...) Expect(err).To(HaveOccurred()) Expect(checkErrorF(err)).To(BeTrue()) }, @@ -461,24 +429,12 @@ var _ = Describe("Scaffold", func() { }) }) -var _ model.Plugin = fakePlugin{} - -// fakePlugin is used to mock a model.Plugin in order to test Scaffold -type fakePlugin struct { - err error -} - -// Pipe implements model.Plugin -func (f fakePlugin) Pipe(_ *model.Universe) error { - return f.err -} - -var _ file.Builder = fakeBuilder{} +var _ Builder = fakeBuilder{} // fakeBuilder is used to mock a file.Builder type fakeBuilder struct { path string - ifExistsAction file.IfExistsAction + ifExistsAction IfExistsAction } // GetPath implements file.Builder @@ -487,11 +443,11 @@ func (f fakeBuilder) GetPath() string { } // GetIfExistsAction implements file.Builder -func (f fakeBuilder) GetIfExistsAction() file.IfExistsAction { +func (f fakeBuilder) GetIfExistsAction() IfExistsAction { return f.ifExistsAction } -var _ file.RequiresValidation = fakeRequiresValidation{} +var _ RequiresValidation = fakeRequiresValidation{} // fakeRequiresValidation is used to mock a file.RequiresValidation in order to test Scaffold type fakeRequiresValidation struct { @@ -505,7 +461,7 @@ func (f fakeRequiresValidation) Validate() error { return f.validateErr } -var _ file.Template = fakeTemplate{} +var _ Template = fakeTemplate{} // fakeTemplate is used to mock a file.File in order to test Scaffold type fakeTemplate struct { @@ -532,17 +488,17 @@ func (f fakeTemplate) SetTemplateDefaults() error { type fakeInserter struct { fakeBuilder - markers []file.Marker - codeFragments file.CodeFragmentsMap + markers []Marker + codeFragments CodeFragmentsMap } // GetMarkers implements file.UpdatableTemplate -func (f fakeInserter) GetMarkers() []file.Marker { +func (f fakeInserter) GetMarkers() []Marker { if f.markers != nil { return f.markers } - markers := make([]file.Marker, 0, len(f.codeFragments)) + markers := make([]Marker, 0, len(f.codeFragments)) for marker := range f.codeFragments { markers = append(markers, marker) } @@ -550,6 +506,6 @@ func (f fakeInserter) GetMarkers() []file.Marker { } // GetCodeFragments implements file.UpdatableTemplate -func (f fakeInserter) GetCodeFragments() file.CodeFragmentsMap { +func (f fakeInserter) GetCodeFragments() CodeFragmentsMap { return f.codeFragments } diff --git a/pkg/plugins/internal/util/exec.go b/pkg/machinery/util/exec.go similarity index 100% rename from pkg/plugins/internal/util/exec.go rename to pkg/machinery/util/exec.go diff --git a/pkg/plugins/internal/util/go_version.go b/pkg/machinery/util/go_version.go similarity index 94% rename from pkg/plugins/internal/util/go_version.go rename to pkg/machinery/util/go_version.go index fb71f7589cb..2a769cde048 100644 --- a/pkg/plugins/internal/util/go_version.go +++ b/pkg/machinery/util/go_version.go @@ -28,7 +28,7 @@ import ( func ValidateGoVersion() error { err := fetchAndCheckGoVersion() if err != nil { - return fmt.Errorf("%s. You can skip this check using the --skip-go-version-check flag", err) + return fmt.Errorf("%w. You can skip this check using the --skip-go-version-check flag", err) } return nil } @@ -46,7 +46,7 @@ func fetchAndCheckGoVersion() error { } goVer := split[2] if err := checkGoVersion(goVer); err != nil { - return fmt.Errorf("go version '%s' is incompatible because '%s'", goVer, err) + return fmt.Errorf("go version '%s' is incompatible because '%w'", goVer, err) } return nil } diff --git a/pkg/plugins/internal/util/go_version_test.go b/pkg/machinery/util/go_version_test.go similarity index 100% rename from pkg/plugins/internal/util/go_version_test.go rename to pkg/machinery/util/go_version_test.go diff --git a/pkg/plugins/internal/util/repository.go b/pkg/machinery/util/repository.go similarity index 100% rename from pkg/plugins/internal/util/repository.go rename to pkg/machinery/util/repository.go diff --git a/pkg/plugins/internal/util/stdin.go b/pkg/machinery/util/stdin.go similarity index 100% rename from pkg/plugins/internal/util/stdin.go rename to pkg/machinery/util/stdin.go diff --git a/pkg/model/file/errors.go b/pkg/model/file/errors.go deleted file mode 100644 index 20349f55844..00000000000 --- a/pkg/model/file/errors.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package file - -import ( - "errors" -) - -// validateError is a wrapper error that will be used for errors returned by RequiresValidation.Validate -type validateError struct { - error -} - -// NewValidateError wraps an error to specify it was returned by RequiresValidation.Validate -func NewValidateError(err error) error { - return validateError{err} -} - -// Unwrap implements Wrapper interface -func (e validateError) Unwrap() error { - return e.error -} - -// IsValidateError checks if the error was returned by RequiresValidation.Validate -func IsValidateError(err error) bool { - return errors.As(err, &validateError{}) -} - -// setTemplateDefaultsError is a wrapper error that will be used for errors returned by Template.SetTemplateDefaults -type setTemplateDefaultsError struct { - error -} - -// NewSetTemplateDefaultsError wraps an error to specify it was returned by Template.SetTemplateDefaults -func NewSetTemplateDefaultsError(err error) error { - return setTemplateDefaultsError{err} -} - -// Unwrap implements Wrapper interface -func (e setTemplateDefaultsError) Unwrap() error { - return e.error -} - -// IsSetTemplateDefaultsError checks if the error was returned by Template.SetTemplateDefaults -func IsSetTemplateDefaultsError(err error) bool { - return errors.As(err, &setTemplateDefaultsError{}) -} diff --git a/pkg/model/plugin.go b/pkg/model/plugin.go deleted file mode 100644 index 57d326fa378..00000000000 --- a/pkg/model/plugin.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package model - -import ( - "errors" -) - -// Plugin is the interface that a plugin must implement -// We will (later) have an ExecPlugin that implements this by exec-ing a binary -type Plugin interface { - // Pipe is the core plugin interface, that transforms a UniverseModel - Pipe(*Universe) error -} - -// pluginError is a wrapper error that will be used for errors returned by Plugin.Pipe -type pluginError struct { - error -} - -// NewPluginError wraps an error to specify it was returned by Plugin.Pipe -func NewPluginError(err error) error { - return pluginError{err} -} - -// Unwrap implements Wrapper interface -func (e pluginError) Unwrap() error { - return e.error -} - -// IsPluginError checks if the error was returned by Plugin.Pipe -func IsPluginError(err error) bool { - return errors.As(err, &pluginError{}) -} diff --git a/pkg/model/universe.go b/pkg/model/universe.go deleted file mode 100644 index 15d597c88f7..00000000000 --- a/pkg/model/universe.go +++ /dev/null @@ -1,111 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package model - -import ( - "sigs.k8s.io/kubebuilder/v3/pkg/config" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" - "sigs.k8s.io/kubebuilder/v3/pkg/model/resource" -) - -// Universe describes the entire state of file generation -type Universe struct { - // Config stores the project configuration - Config config.Config `json:"config,omitempty"` - - // Boilerplate is the copyright comment added at the top of scaffolded files - Boilerplate string `json:"boilerplate,omitempty"` - - // Resource contains the information of the API that is being scaffolded - Resource *resource.Resource `json:"resource,omitempty"` - - // Files contains the model of the files that are being scaffolded - Files map[string]*file.File `json:"files,omitempty"` -} - -// NewUniverse creates a new Universe -func NewUniverse(options ...UniverseOption) *Universe { - universe := &Universe{} - - // Apply options - for _, option := range options { - option(universe) - } - - return universe -} - -// UniverseOption configure Universe -type UniverseOption func(*Universe) - -// WithConfig stores the already loaded project configuration -func WithConfig(projectConfig config.Config) UniverseOption { - return func(universe *Universe) { - universe.Config = projectConfig - } -} - -// WithBoilerplate stores the already loaded project configuration -func WithBoilerplate(boilerplate string) UniverseOption { - return func(universe *Universe) { - universe.Boilerplate = boilerplate - } -} - -// WithoutBoilerplate is used for files that do not require a boilerplate -func WithoutBoilerplate(universe *Universe) { - universe.Boilerplate = "" -} - -// WithResource stores the provided resource -func WithResource(resource *resource.Resource) UniverseOption { - return func(universe *Universe) { - universe.Resource = resource - } -} - -// InjectInto injects fields from the universe into the builder -func (u Universe) InjectInto(builder file.Builder) { - // Inject project configuration - if u.Config != nil { - if builderWithDomain, hasDomain := builder.(file.HasDomain); hasDomain { - builderWithDomain.InjectDomain(u.Config.GetDomain()) - } - if builderWithRepository, hasRepository := builder.(file.HasRepository); hasRepository { - builderWithRepository.InjectRepository(u.Config.GetRepository()) - } - if builderWithProjectName, hasProjectName := builder.(file.HasProjectName); hasProjectName { - builderWithProjectName.InjectProjectName(u.Config.GetProjectName()) - } - if builderWithMultiGroup, hasMultiGroup := builder.(file.HasMultiGroup); hasMultiGroup { - builderWithMultiGroup.InjectMultiGroup(u.Config.IsMultiGroup()) - } - if builderWithComponentConfig, hasComponentConfig := builder.(file.HasComponentConfig); hasComponentConfig { - builderWithComponentConfig.InjectComponentConfig(u.Config.IsComponentConfig()) - } - } - // Inject boilerplate - if builderWithBoilerplate, hasBoilerplate := builder.(file.HasBoilerplate); hasBoilerplate { - builderWithBoilerplate.InjectBoilerplate(u.Boilerplate) - } - // Inject resource - if u.Resource != nil { - if builderWithResource, hasResource := builder.(file.HasResource); hasResource { - builderWithResource.InjectResource(u.Resource) - } - } -} diff --git a/pkg/plugins/declarative/v1/api.go b/pkg/plugins/declarative/v1/api.go index fde08f0621e..db2fcfe1c71 100644 --- a/pkg/plugins/declarative/v1/api.go +++ b/pkg/plugins/declarative/v1/api.go @@ -24,13 +24,12 @@ import ( "github.com/spf13/afero" "sigs.k8s.io/kubebuilder/v3/pkg/config" - "sigs.k8s.io/kubebuilder/v3/pkg/model" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery/util" "sigs.k8s.io/kubebuilder/v3/pkg/model/resource" "sigs.k8s.io/kubebuilder/v3/pkg/plugin" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/declarative/v1/internal/templates" goPluginV3 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/machinery" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/util" ) const ( @@ -78,12 +77,14 @@ func (p *createAPISubcommand) Scaffold(fs afero.Fs) error { } boilerplate := string(bp) - if err := machinery.NewScaffold(fs).Execute( - model.NewUniverse( - model.WithConfig(p.config), - model.WithBoilerplate(boilerplate), - model.WithResource(p.resource), - ), + // Initialize the machinery.Scaffold that will write the files to disk + scaffold := machinery.NewScaffold(fs, + machinery.WithConfig(p.config), + machinery.WithBoilerplate(boilerplate), + machinery.WithResource(p.resource), + ) + + if err := scaffold.Execute( &templates.Types{}, &templates.Controller{}, &templates.Channel{ManifestVersion: exampleManifestVersion}, diff --git a/pkg/plugins/declarative/v1/internal/templates/channel.go b/pkg/plugins/declarative/v1/internal/templates/channel.go index c2e4a0bfbb1..9c72df227a7 100644 --- a/pkg/plugins/declarative/v1/internal/templates/channel.go +++ b/pkg/plugins/declarative/v1/internal/templates/channel.go @@ -20,14 +20,14 @@ import ( "fmt" "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Channel{} +var _ machinery.Template = &Channel{} // Channel scaffolds the file for the channel type Channel struct { - file.TemplateMixin + machinery.TemplateMixin ManifestVersion string } @@ -41,7 +41,7 @@ func (f *Channel) SetTemplateDefaults() error { f.TemplateBody = channelTemplate - f.IfExistsAction = file.Skip + f.IfExistsAction = machinery.SkipFile return nil } diff --git a/pkg/plugins/declarative/v1/internal/templates/controller.go b/pkg/plugins/declarative/v1/internal/templates/controller.go index bdbe2c3836d..31e4f11bbfa 100644 --- a/pkg/plugins/declarative/v1/internal/templates/controller.go +++ b/pkg/plugins/declarative/v1/internal/templates/controller.go @@ -19,18 +19,18 @@ package templates import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Controller{} +var _ machinery.Template = &Controller{} // Controller scaffolds the file that defines the controller for a CRD or a builtin resource // nolint:maligned type Controller struct { - file.TemplateMixin - file.MultiGroupMixin - file.BoilerplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.MultiGroupMixin + machinery.BoilerplateMixin + machinery.ResourceMixin } // SetTemplateDefaults implements file.Template @@ -46,7 +46,7 @@ func (f *Controller) SetTemplateDefaults() error { f.TemplateBody = controllerTemplate - f.IfExistsAction = file.Overwrite + f.IfExistsAction = machinery.OverwriteFile return nil } diff --git a/pkg/plugins/declarative/v1/internal/templates/manifest.go b/pkg/plugins/declarative/v1/internal/templates/manifest.go index 5034a20613e..252af3bf888 100644 --- a/pkg/plugins/declarative/v1/internal/templates/manifest.go +++ b/pkg/plugins/declarative/v1/internal/templates/manifest.go @@ -20,15 +20,15 @@ import ( "fmt" "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Manifest{} +var _ machinery.Template = &Manifest{} // Manifest scaffolds the file that acts as a placeholder for the manifest type Manifest struct { - file.TemplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.ResourceMixin ManifestVersion string } @@ -43,7 +43,7 @@ func (f *Manifest) SetTemplateDefaults() error { f.TemplateBody = manifestTemplate - f.IfExistsAction = file.Skip + f.IfExistsAction = machinery.SkipFile return nil } diff --git a/pkg/plugins/declarative/v1/internal/templates/types.go b/pkg/plugins/declarative/v1/internal/templates/types.go index 105a70ea4e6..3a0c2b946c7 100644 --- a/pkg/plugins/declarative/v1/internal/templates/types.go +++ b/pkg/plugins/declarative/v1/internal/templates/types.go @@ -21,18 +21,18 @@ import ( "path/filepath" "text/template" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Types{} +var _ machinery.Template = &Types{} // Types scaffolds the file that defines the schema for a CRD // nolint:maligned type Types struct { - file.TemplateMixin - file.MultiGroupMixin - file.BoilerplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.MultiGroupMixin + machinery.BoilerplateMixin + machinery.ResourceMixin } // SetTemplateDefaults implements file.Template @@ -48,14 +48,14 @@ func (f *Types) SetTemplateDefaults() error { f.TemplateBody = typesTemplate - f.IfExistsAction = file.Overwrite + f.IfExistsAction = machinery.OverwriteFile return nil } // GetFuncMap implements file.UseCustomFuncMap func (f Types) GetFuncMap() template.FuncMap { - funcMap := file.DefaultFuncMap() + funcMap := machinery.DefaultFuncMap() funcMap["JSONTag"] = func(tag string) string { return fmt.Sprintf("`json:%q`", tag) } diff --git a/pkg/plugins/golang/v2/api.go b/pkg/plugins/golang/v2/api.go index 121ac904d5e..e37f3dae476 100644 --- a/pkg/plugins/golang/v2/api.go +++ b/pkg/plugins/golang/v2/api.go @@ -26,13 +26,11 @@ import ( "github.com/spf13/pflag" "sigs.k8s.io/kubebuilder/v3/pkg/config" - "sigs.k8s.io/kubebuilder/v3/pkg/model" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery/util" "sigs.k8s.io/kubebuilder/v3/pkg/model/resource" "sigs.k8s.io/kubebuilder/v3/pkg/plugin" goPlugin "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/util" - "sigs.k8s.io/kubebuilder/v3/plugins/addon" ) var _ plugin.CreateAPISubcommand = &createAPISubcommand{} @@ -40,9 +38,6 @@ var _ plugin.CreateAPISubcommand = &createAPISubcommand{} type createAPISubcommand struct { config config.Config - // pattern indicates that we should use a plugin to build according to a pattern - pattern string - options *goPlugin.Options resource *resource.Resource @@ -90,11 +85,6 @@ After the scaffold is written, api will run make on the project. func (p *createAPISubcommand) BindFlags(fs *pflag.FlagSet) { fs.BoolVar(&p.runMake, "make", true, "if true, run `make generate` after generating files") - if os.Getenv("KUBEBUILDER_ENABLE_PLUGINS") != "" { - fs.StringVar(&p.pattern, "pattern", "", - "generates an API following an extension pattern (addon)") - } - fs.BoolVar(&p.force, "force", false, "attempt to create resource even if it already exists") @@ -158,38 +148,12 @@ func (p *createAPISubcommand) InjectResource(res *resource.Resource) error { } func (p *createAPISubcommand) Scaffold(fs afero.Fs) error { - // Load the requested plugins - plugins := make([]model.Plugin, 0) - switch strings.ToLower(p.pattern) { - case "": - // Default pattern - case "addon": - plugins = append(plugins, &addon.Plugin{}) - default: - return fmt.Errorf("unknown pattern %q", p.pattern) - } - - scaffolder := scaffolds.NewAPIScaffolder(p.config, *p.resource, p.force, plugins) + scaffolder := scaffolds.NewAPIScaffolder(p.config, *p.resource, p.force) scaffolder.InjectFS(fs) return scaffolder.Scaffold() } func (p *createAPISubcommand) PostScaffold() error { - // Load the requested plugins - switch strings.ToLower(p.pattern) { - case "": - // Default pattern - case "addon": - // Ensure that we are pinning sigs.k8s.io/kubebuilder-declarative-pattern version - err := util.RunCmd("Get controller runtime", "go", "get", - "sigs.k8s.io/kubebuilder-declarative-pattern@"+scaffolds.KbDeclarativePattern) - if err != nil { - return err - } - default: - return fmt.Errorf("unknown pattern %q", p.pattern) - } - err := util.RunCmd("Update dependencies", "go", "mod", "tidy") if err != nil { return err diff --git a/pkg/plugins/golang/v2/init.go b/pkg/plugins/golang/v2/init.go index 021db4b9de9..6eec7799c14 100644 --- a/pkg/plugins/golang/v2/init.go +++ b/pkg/plugins/golang/v2/init.go @@ -28,9 +28,9 @@ import ( "sigs.k8s.io/kubebuilder/v3/pkg/config" cfgv2 "sigs.k8s.io/kubebuilder/v3/pkg/config/v2" "sigs.k8s.io/kubebuilder/v3/pkg/internal/validation" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery/util" "sigs.k8s.io/kubebuilder/v3/pkg/plugin" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/util" ) var _ plugin.InitSubcommand = &initSubcommand{} diff --git a/pkg/plugins/golang/v2/scaffolds/api.go b/pkg/plugins/golang/v2/scaffolds/api.go index 030cbb2747e..4ddaf7f5fc8 100644 --- a/pkg/plugins/golang/v2/scaffolds/api.go +++ b/pkg/plugins/golang/v2/scaffolds/api.go @@ -23,8 +23,9 @@ import ( "sigs.k8s.io/kubebuilder/v3/pkg/config" cfgv2 "sigs.k8s.io/kubebuilder/v3/pkg/config/v2" - "sigs.k8s.io/kubebuilder/v3/pkg/model" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" "sigs.k8s.io/kubebuilder/v3/pkg/model/resource" + "sigs.k8s.io/kubebuilder/v3/pkg/plugins" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates/api" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates/config/crd" @@ -33,29 +34,19 @@ import ( "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates/config/samples" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates/controllers" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates/hack" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/cmdutil" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/machinery" ) -// KbDeclarativePattern is the sigs.k8s.io/kubebuilder-declarative-pattern version -// (used only to gen api with --pattern=addon) -const KbDeclarativePattern = "v0.0.0-20200522144838-848d48e5b073" - -var _ cmdutil.Scaffolder = &apiScaffolder{} +var _ plugins.Scaffolder = &apiScaffolder{} // apiScaffolder contains configuration for generating scaffolding for Go type // representing the API and controller that implements the behavior for the API. type apiScaffolder struct { - config config.Config - boilerplate string - resource resource.Resource + config config.Config + resource resource.Resource // fs is the filesystem that will be used by the scaffolder fs afero.Fs - // plugins is the list of plugins we should allow to transform our generated scaffolding - plugins []model.Plugin - // force indicates whether to scaffold controller files even if it exists or not force bool } @@ -65,12 +56,10 @@ func NewAPIScaffolder( config config.Config, res resource.Resource, force bool, - plugins []model.Plugin, -) cmdutil.Scaffolder { +) plugins.Scaffolder { return &apiScaffolder{ config: config, resource: res, - plugins: plugins, force: force, } } @@ -80,24 +69,22 @@ func (s *apiScaffolder) InjectFS(fs afero.Fs) { s.fs = fs } -func (s *apiScaffolder) newUniverse() *model.Universe { - return model.NewUniverse( - model.WithConfig(s.config), - model.WithBoilerplate(s.boilerplate), - model.WithResource(&s.resource), - ) -} - // Scaffold implements cmdutil.Scaffolder func (s *apiScaffolder) Scaffold() error { fmt.Println("Writing scaffold for you to edit...") // Load the boilerplate - bp, err := afero.ReadFile(s.fs, hack.DefaultBoilerplatePath) + boilerplate, err := afero.ReadFile(s.fs, hack.DefaultBoilerplatePath) if err != nil { return fmt.Errorf("error scaffolding API/controller: unable to load boilerplate: %w", err) } - s.boilerplate = string(bp) + + // Initialize the machinery.Scaffold that will write the files to disk + scaffold := machinery.NewScaffold(s.fs, + machinery.WithConfig(s.config), + machinery.WithBoilerplate(string(boilerplate)), + machinery.WithResource(&s.resource), + ) // Keep track of these values before the update doAPI := s.resource.HasAPI() @@ -116,9 +103,7 @@ func (s *apiScaffolder) Scaffold() error { } if doAPI { - - if err := machinery.NewScaffold(s.fs, s.plugins...).Execute( - s.newUniverse(), + if err := scaffold.Execute( &api.Types{Force: s.force}, &api.Group{}, &samples.CRDSample{Force: s.force}, @@ -130,19 +115,16 @@ func (s *apiScaffolder) Scaffold() error { return fmt.Errorf("error scaffolding APIs: %w", err) } - if err := machinery.NewScaffold(s.fs).Execute( - s.newUniverse(), + if err := scaffold.Execute( &crd.Kustomization{}, &crd.KustomizeConfig{}, ); err != nil { return fmt.Errorf("error scaffolding kustomization: %v", err) } - } if doController { - if err := machinery.NewScaffold(s.fs, s.plugins...).Execute( - s.newUniverse(), + if err := scaffold.Execute( &controllers.SuiteTest{Force: s.force}, &controllers.Controller{ControllerRuntimeVersion: ControllerRuntimeVersion, Force: s.force}, ); err != nil { @@ -150,8 +132,7 @@ func (s *apiScaffolder) Scaffold() error { } } - if err := machinery.NewScaffold(s.fs, s.plugins...).Execute( - s.newUniverse(), + if err := scaffold.Execute( &templates.MainUpdater{WireResource: doAPI, WireController: doController}, ); err != nil { return fmt.Errorf("error updating main.go: %v", err) diff --git a/pkg/plugins/golang/v2/scaffolds/edit.go b/pkg/plugins/golang/v2/scaffolds/edit.go index e3096729381..fe7c9564ce7 100644 --- a/pkg/plugins/golang/v2/scaffolds/edit.go +++ b/pkg/plugins/golang/v2/scaffolds/edit.go @@ -23,10 +23,10 @@ import ( "github.com/spf13/afero" "sigs.k8s.io/kubebuilder/v3/pkg/config" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/cmdutil" + "sigs.k8s.io/kubebuilder/v3/pkg/plugins" ) -var _ cmdutil.Scaffolder = &editScaffolder{} +var _ plugins.Scaffolder = &editScaffolder{} type editScaffolder struct { config config.Config @@ -37,7 +37,7 @@ type editScaffolder struct { } // NewEditScaffolder returns a new Scaffolder for configuration edit operations -func NewEditScaffolder(config config.Config, multigroup bool) cmdutil.Scaffolder { +func NewEditScaffolder(config config.Config, multigroup bool) plugins.Scaffolder { return &editScaffolder{ config: config, multigroup: multigroup, diff --git a/pkg/plugins/golang/v2/scaffolds/init.go b/pkg/plugins/golang/v2/scaffolds/init.go index e938ffeebab..57febe08ad3 100644 --- a/pkg/plugins/golang/v2/scaffolds/init.go +++ b/pkg/plugins/golang/v2/scaffolds/init.go @@ -23,7 +23,8 @@ import ( "github.com/spf13/afero" "sigs.k8s.io/kubebuilder/v3/pkg/config" - "sigs.k8s.io/kubebuilder/v3/pkg/model" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" + "sigs.k8s.io/kubebuilder/v3/pkg/plugins" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates/config/certmanager" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates/config/kdefault" @@ -32,8 +33,6 @@ import ( "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates/config/webhook" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates/hack" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/cmdutil" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/machinery" ) const ( @@ -47,7 +46,7 @@ const ( imageName = "controller:latest" ) -var _ cmdutil.Scaffolder = &initScaffolder{} +var _ plugins.Scaffolder = &initScaffolder{} type initScaffolder struct { config config.Config @@ -60,7 +59,7 @@ type initScaffolder struct { } // NewInitScaffolder returns a new Scaffolder for project initialization operations -func NewInitScaffolder(config config.Config, license, owner string) cmdutil.Scaffolder { +func NewInitScaffolder(config config.Config, license, owner string) plugins.Scaffolder { return &initScaffolder{ config: config, boilerplatePath: filepath.Join("hack", "boilerplate.go.txt"), @@ -74,25 +73,23 @@ func (s *initScaffolder) InjectFS(fs afero.Fs) { s.fs = fs } -func (s *initScaffolder) newUniverse(boilerplate string) *model.Universe { - return model.NewUniverse( - model.WithConfig(s.config), - model.WithBoilerplate(boilerplate), - ) -} - // Scaffold implements cmdutil.Scaffolder func (s *initScaffolder) Scaffold() error { fmt.Println("Writing scaffold for you to edit...") - bpFile := &hack.Boilerplate{} + // Initialize the machinery.Scaffold that will write the boilerplate file to disk + // The boilerplate file needs to be scaffolded as a separate step as it is going to + // be used by the rest of the files, even those scaffolded in this command call. + scaffold := machinery.NewScaffold(s.fs, + machinery.WithConfig(s.config), + ) + + bpFile := &hack.Boilerplate{ + License: s.license, + Owner: s.owner, + } bpFile.Path = s.boilerplatePath - bpFile.License = s.license - bpFile.Owner = s.owner - if err := machinery.NewScaffold(s.fs).Execute( - s.newUniverse(""), - bpFile, - ); err != nil { + if err := scaffold.Execute(bpFile); err != nil { return err } @@ -101,17 +98,26 @@ func (s *initScaffolder) Scaffold() error { return err } - return machinery.NewScaffold(s.fs).Execute( - s.newUniverse(string(boilerplate)), - &templates.GitIgnore{}, + // Initialize the machinery.Scaffold that will write the files to disk + scaffold = machinery.NewScaffold(s.fs, + machinery.WithConfig(s.config), + machinery.WithBoilerplate(string(boilerplate)), + ) + + return scaffold.Execute( + &rbac.Kustomization{}, &rbac.AuthProxyRole{}, &rbac.AuthProxyRoleBinding{}, - &kdefault.ManagerAuthProxyPatch{}, &rbac.AuthProxyService{}, &rbac.AuthProxyClientRole{}, + &rbac.RoleBinding{}, + &rbac.LeaderElectionRole{}, + &rbac.LeaderElectionRoleBinding{}, + &manager.Kustomization{}, &manager.Config{Image: imageName}, &templates.Main{}, &templates.GoMod{ControllerRuntimeVersion: ControllerRuntimeVersion}, + &templates.GitIgnore{}, &templates.Makefile{ Image: imageName, BoilerplatePath: s.boilerplatePath, @@ -120,16 +126,12 @@ func (s *initScaffolder) Scaffold() error { }, &templates.Dockerfile{}, &kdefault.Kustomization{}, + &kdefault.ManagerAuthProxyPatch{}, &kdefault.ManagerWebhookPatch{}, - &rbac.RoleBinding{}, - &rbac.LeaderElectionRole{}, - &rbac.LeaderElectionRoleBinding{}, - &rbac.Kustomization{}, - &manager.Kustomization{}, + &kdefault.WebhookCAInjectionPatch{}, &webhook.Kustomization{}, &webhook.KustomizeConfig{}, &webhook.Service{}, - &kdefault.WebhookCAInjectionPatch{}, &prometheus.Kustomization{}, &prometheus.Monitor{}, &certmanager.Certificate{}, diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/api/group.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/api/group.go index bccba858d49..ba9f21f6acc 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/api/group.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/api/group.go @@ -19,17 +19,17 @@ package api import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Group{} +var _ machinery.Template = &Group{} // Group scaffolds the file that defines the registration methods for a certain group and version type Group struct { - file.TemplateMixin - file.MultiGroupMixin - file.BoilerplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.MultiGroupMixin + machinery.BoilerplateMixin + machinery.ResourceMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/api/types.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/api/types.go index cd0907121cf..d80e5f33b93 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/api/types.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/api/types.go @@ -20,18 +20,18 @@ import ( "fmt" "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Types{} +var _ machinery.Template = &Types{} // Types scaffolds the file that defines the schema for a CRD // nolint:maligned type Types struct { - file.TemplateMixin - file.MultiGroupMixin - file.BoilerplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.MultiGroupMixin + machinery.BoilerplateMixin + machinery.ResourceMixin Force bool } @@ -51,9 +51,9 @@ func (f *Types) SetTemplateDefaults() error { f.TemplateBody = typesTemplate if f.Force { - f.IfExistsAction = file.Overwrite + f.IfExistsAction = machinery.OverwriteFile } else { - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error } return nil diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/api/webhook.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/api/webhook.go index 806a37d5524..5def3986d32 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/api/webhook.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/api/webhook.go @@ -21,17 +21,17 @@ import ( "path/filepath" "strings" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Webhook{} +var _ machinery.Template = &Webhook{} // Webhook scaffolds the file that defines a webhook for a CRD or a builtin resource type Webhook struct { // nolint:maligned - file.TemplateMixin - file.MultiGroupMixin - file.BoilerplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.MultiGroupMixin + machinery.BoilerplateMixin + machinery.ResourceMixin // Is the Group domain for the Resource replacing '.' with '-' QualifiedGroupWithDash string @@ -58,7 +58,7 @@ func (f *Webhook) SetTemplateDefaults() error { } f.TemplateBody = webhookTemplate - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error f.QualifiedGroupWithDash = strings.Replace(f.Resource.QualifiedGroup(), ".", "-", -1) diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/certmanager/certificate.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/certmanager/certificate.go index c8ced013fc8..4d17b8dff60 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/certmanager/certificate.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/certmanager/certificate.go @@ -19,14 +19,14 @@ package certmanager import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Certificate{} +var _ machinery.Template = &Certificate{} // Certificate scaffolds a file that defines the issuer CR and the certificate CR type Certificate struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/certmanager/kustomization.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/certmanager/kustomization.go index 7437ab18bf1..78b2c5e9484 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/certmanager/kustomization.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/certmanager/kustomization.go @@ -19,14 +19,14 @@ package certmanager import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Kustomization{} +var _ machinery.Template = &Kustomization{} // Kustomization scaffolds a file that defines the kustomization scheme for the certmanager folder type Kustomization struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/certmanager/kustomizeconfig.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/certmanager/kustomizeconfig.go index 8eada694a10..e7dbcf8986d 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/certmanager/kustomizeconfig.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/certmanager/kustomizeconfig.go @@ -19,14 +19,14 @@ package certmanager import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &KustomizeConfig{} +var _ machinery.Template = &KustomizeConfig{} // KustomizeConfig scaffolds a file that configures the kustomization for the certmanager folder type KustomizeConfig struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/crd/kustomization.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/crd/kustomization.go index fd06bdf7848..37ec7556cb1 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/crd/kustomization.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/crd/kustomization.go @@ -20,16 +20,16 @@ import ( "fmt" "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Kustomization{} -var _ file.Inserter = &Kustomization{} +var _ machinery.Template = &Kustomization{} +var _ machinery.Inserter = &Kustomization{} // Kustomization scaffolds a file that defines the kustomization scheme for the crd folder type Kustomization struct { - file.TemplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.ResourceMixin } // SetTemplateDefaults implements file.Template @@ -40,9 +40,9 @@ func (f *Kustomization) SetTemplateDefaults() error { f.Path = f.Resource.Replacer().Replace(f.Path) f.TemplateBody = fmt.Sprintf(kustomizationTemplate, - file.NewMarkerFor(f.Path, resourceMarker), - file.NewMarkerFor(f.Path, webhookPatchMarker), - file.NewMarkerFor(f.Path, caInjectionPatchMarker), + machinery.NewMarkerFor(f.Path, resourceMarker), + machinery.NewMarkerFor(f.Path, webhookPatchMarker), + machinery.NewMarkerFor(f.Path, caInjectionPatchMarker), ) return nil @@ -55,11 +55,11 @@ const ( ) // GetMarkers implements file.Inserter -func (f *Kustomization) GetMarkers() []file.Marker { - return []file.Marker{ - file.NewMarkerFor(f.Path, resourceMarker), - file.NewMarkerFor(f.Path, webhookPatchMarker), - file.NewMarkerFor(f.Path, caInjectionPatchMarker), +func (f *Kustomization) GetMarkers() []machinery.Marker { + return []machinery.Marker{ + machinery.NewMarkerFor(f.Path, resourceMarker), + machinery.NewMarkerFor(f.Path, webhookPatchMarker), + machinery.NewMarkerFor(f.Path, caInjectionPatchMarker), } } @@ -73,8 +73,8 @@ const ( ) // GetCodeFragments implements file.Inserter -func (f *Kustomization) GetCodeFragments() file.CodeFragmentsMap { - fragments := make(file.CodeFragmentsMap, 3) +func (f *Kustomization) GetCodeFragments() machinery.CodeFragmentsMap { + fragments := make(machinery.CodeFragmentsMap, 3) // Generate resource code fragments res := make([]string, 0) @@ -90,13 +90,13 @@ func (f *Kustomization) GetCodeFragments() file.CodeFragmentsMap { // Only store code fragments in the map if the slices are non-empty if len(res) != 0 { - fragments[file.NewMarkerFor(f.Path, resourceMarker)] = res + fragments[machinery.NewMarkerFor(f.Path, resourceMarker)] = res } if len(webhookPatch) != 0 { - fragments[file.NewMarkerFor(f.Path, webhookPatchMarker)] = webhookPatch + fragments[machinery.NewMarkerFor(f.Path, webhookPatchMarker)] = webhookPatch } if len(caInjectionPatch) != 0 { - fragments[file.NewMarkerFor(f.Path, caInjectionPatchMarker)] = caInjectionPatch + fragments[machinery.NewMarkerFor(f.Path, caInjectionPatchMarker)] = caInjectionPatch } return fragments diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/crd/kustomizeconfig.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/crd/kustomizeconfig.go index 84025c65e3a..0013026f81c 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/crd/kustomizeconfig.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/crd/kustomizeconfig.go @@ -19,14 +19,14 @@ package crd import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &KustomizeConfig{} +var _ machinery.Template = &KustomizeConfig{} // KustomizeConfig scaffolds a file that configures the kustomization for the crd folder type KustomizeConfig struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/crd/patches/enablecainjection_patch.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/crd/patches/enablecainjection_patch.go index 00d03f090d1..376a058a01c 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/crd/patches/enablecainjection_patch.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/crd/patches/enablecainjection_patch.go @@ -19,15 +19,15 @@ package patches import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &EnableCAInjectionPatch{} +var _ machinery.Template = &EnableCAInjectionPatch{} // EnableCAInjectionPatch scaffolds a file that defines the patch that injects CA into the CRD type EnableCAInjectionPatch struct { - file.TemplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.ResourceMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/crd/patches/enablewebhook_patch.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/crd/patches/enablewebhook_patch.go index 8e3fc5d051a..1472028b627 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/crd/patches/enablewebhook_patch.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/crd/patches/enablewebhook_patch.go @@ -19,15 +19,15 @@ package patches import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &EnableWebhookPatch{} +var _ machinery.Template = &EnableWebhookPatch{} // EnableWebhookPatch scaffolds a file that defines the patch that enables conversion webhook for the CRD type EnableWebhookPatch struct { - file.TemplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.ResourceMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/kdefault/enablecainection_patch.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/kdefault/enablecainection_patch.go index c51474d4cb5..3cee6b8595d 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/kdefault/enablecainection_patch.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/kdefault/enablecainection_patch.go @@ -19,14 +19,14 @@ package kdefault import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &WebhookCAInjectionPatch{} +var _ machinery.Template = &WebhookCAInjectionPatch{} // WebhookCAInjectionPatch scaffolds a file that defines the patch that adds annotation to webhooks type WebhookCAInjectionPatch struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template @@ -37,7 +37,7 @@ func (f *WebhookCAInjectionPatch) SetTemplateDefaults() error { f.TemplateBody = injectCAPatchTemplate - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error return nil } diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/kdefault/kustomization.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/kdefault/kustomization.go index 1250bcfcdaf..68ecc351cd7 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/kdefault/kustomization.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/kdefault/kustomization.go @@ -21,15 +21,15 @@ import ( "path/filepath" "strings" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Kustomization{} +var _ machinery.Template = &Kustomization{} // Kustomization scaffolds a file that defines the kustomization scheme for the default overlay folder type Kustomization struct { - file.TemplateMixin - file.ProjectNameMixin + machinery.TemplateMixin + machinery.ProjectNameMixin } // SetTemplateDefaults implements file.Template @@ -40,7 +40,7 @@ func (f *Kustomization) SetTemplateDefaults() error { f.TemplateBody = kustomizeTemplate - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error if f.ProjectName == "" { // Use directory name as project name, which will be empty if the project version is < v3. diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/kdefault/manager_auth_proxy_patch.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/kdefault/manager_auth_proxy_patch.go index 8f8be890a7e..7d49171c16f 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/kdefault/manager_auth_proxy_patch.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/kdefault/manager_auth_proxy_patch.go @@ -19,14 +19,14 @@ package kdefault import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &ManagerAuthProxyPatch{} +var _ machinery.Template = &ManagerAuthProxyPatch{} // ManagerAuthProxyPatch scaffolds a file that defines the patch that enables prometheus metrics for the manager type ManagerAuthProxyPatch struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template @@ -37,7 +37,7 @@ func (f *ManagerAuthProxyPatch) SetTemplateDefaults() error { f.TemplateBody = kustomizeAuthProxyPatchTemplate - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error return nil } diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/kdefault/webhook_manager_patch.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/kdefault/webhook_manager_patch.go index 65e34c7d793..a9e0844bf18 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/kdefault/webhook_manager_patch.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/kdefault/webhook_manager_patch.go @@ -19,14 +19,14 @@ package kdefault import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &ManagerWebhookPatch{} +var _ machinery.Template = &ManagerWebhookPatch{} // ManagerWebhookPatch scaffolds a file that defines the patch that enables webhooks on the manager type ManagerWebhookPatch struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/manager/config.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/manager/config.go index 0a1bc1cdeb7..1e08e134923 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/manager/config.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/manager/config.go @@ -19,14 +19,14 @@ package manager import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Config{} +var _ machinery.Template = &Config{} // Config scaffolds a file that defines the namespace and the manager deployment type Config struct { - file.TemplateMixin + machinery.TemplateMixin // Image is controller manager image name Image string diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/manager/kustomization.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/manager/kustomization.go index 1832137b95b..f8d5ecd7ec9 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/manager/kustomization.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/manager/kustomization.go @@ -19,14 +19,14 @@ package manager import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Kustomization{} +var _ machinery.Template = &Kustomization{} // Kustomization scaffolds a file that defines the kustomization scheme for the manager folder type Kustomization struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template @@ -37,7 +37,7 @@ func (f *Kustomization) SetTemplateDefaults() error { f.TemplateBody = kustomizeManagerTemplate - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error return nil } diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/prometheus/kustomization.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/prometheus/kustomization.go index 16b9bb4b563..c271a6a3dbb 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/prometheus/kustomization.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/prometheus/kustomization.go @@ -19,14 +19,14 @@ package prometheus import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Kustomization{} +var _ machinery.Template = &Kustomization{} // Kustomization scaffolds a file that defines the kustomization scheme for the prometheus folder type Kustomization struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/prometheus/monitor.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/prometheus/monitor.go index 4ee7d32c1c2..41870f6850a 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/prometheus/monitor.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/prometheus/monitor.go @@ -19,14 +19,14 @@ package prometheus import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Monitor{} +var _ machinery.Template = &Monitor{} // Monitor scaffolds a file that defines the prometheus service monitor type Monitor struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/auth_proxy_client_role.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/auth_proxy_client_role.go index 2b6d77e596f..1eee0af2031 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/auth_proxy_client_role.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/auth_proxy_client_role.go @@ -19,14 +19,14 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &AuthProxyClientRole{} +var _ machinery.Template = &AuthProxyClientRole{} // AuthProxyClientRole scaffolds a file that defines the role for the metrics reader type AuthProxyClientRole struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/auth_proxy_role.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/auth_proxy_role.go index 01b8413b855..df22ef8dc39 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/auth_proxy_role.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/auth_proxy_role.go @@ -19,14 +19,14 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &AuthProxyRole{} +var _ machinery.Template = &AuthProxyRole{} // AuthProxyRole scaffolds a file that defines the role for the auth proxy type AuthProxyRole struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/auth_proxy_role_binding.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/auth_proxy_role_binding.go index 1aaf9ebbf85..eafc45f6ee9 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/auth_proxy_role_binding.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/auth_proxy_role_binding.go @@ -19,14 +19,14 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &AuthProxyRoleBinding{} +var _ machinery.Template = &AuthProxyRoleBinding{} // AuthProxyRoleBinding scaffolds a file that defines the role binding for the auth proxy type AuthProxyRoleBinding struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/auth_proxy_service.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/auth_proxy_service.go index e84ec0e322c..6287d360ebb 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/auth_proxy_service.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/auth_proxy_service.go @@ -19,14 +19,14 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &AuthProxyService{} +var _ machinery.Template = &AuthProxyService{} // AuthProxyService scaffolds a file that defines the service for the auth proxy type AuthProxyService struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/crd_editor_role.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/crd_editor_role.go index 3de358308bd..7024549629d 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/crd_editor_role.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/crd_editor_role.go @@ -19,15 +19,15 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &CRDEditorRole{} +var _ machinery.Template = &CRDEditorRole{} // CRDEditorRole scaffolds a file that defines the role that allows to edit plurals type CRDEditorRole struct { - file.TemplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.ResourceMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/crd_viewer_role.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/crd_viewer_role.go index 5898a8fe334..74177476661 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/crd_viewer_role.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/crd_viewer_role.go @@ -19,15 +19,15 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &CRDViewerRole{} +var _ machinery.Template = &CRDViewerRole{} // CRDViewerRole scaffolds a file that defines the role that allows to view plurals type CRDViewerRole struct { - file.TemplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.ResourceMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/kustomization.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/kustomization.go index d8d9b41b180..f5b164e5b79 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/kustomization.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/kustomization.go @@ -19,14 +19,14 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Kustomization{} +var _ machinery.Template = &Kustomization{} // Kustomization scaffolds a file that defines the kustomization scheme for the rbac folder type Kustomization struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template @@ -37,7 +37,7 @@ func (f *Kustomization) SetTemplateDefaults() error { f.TemplateBody = kustomizeRBACTemplate - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error return nil } diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/leader_election_role.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/leader_election_role.go index b787f441f59..6de4d48b784 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/leader_election_role.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/leader_election_role.go @@ -19,14 +19,14 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &LeaderElectionRole{} +var _ machinery.Template = &LeaderElectionRole{} // LeaderElectionRole scaffolds a file that defines the role that allows leader election type LeaderElectionRole struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/leader_election_role_binding.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/leader_election_role_binding.go index f196868a3f8..9dd75b7ff6b 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/leader_election_role_binding.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/leader_election_role_binding.go @@ -19,14 +19,14 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &LeaderElectionRoleBinding{} +var _ machinery.Template = &LeaderElectionRoleBinding{} // LeaderElectionRoleBinding scaffolds a file that defines the role binding that allows leader election type LeaderElectionRoleBinding struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/role_binding.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/role_binding.go index 6786223d648..0cc6687e8c3 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/role_binding.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac/role_binding.go @@ -19,14 +19,14 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &RoleBinding{} +var _ machinery.Template = &RoleBinding{} // RoleBinding scaffolds a file that defines the role binding for the manager type RoleBinding struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/samples/crd_sample.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/samples/crd_sample.go index b9b349ff336..af9e29f6f6c 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/samples/crd_sample.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/samples/crd_sample.go @@ -19,15 +19,15 @@ package samples import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &CRDSample{} +var _ machinery.Template = &CRDSample{} // CRDSample scaffolds a file that defines a sample manifest for the CRD type CRDSample struct { - file.TemplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.ResourceMixin Force bool } @@ -40,9 +40,9 @@ func (f *CRDSample) SetTemplateDefaults() error { f.Path = f.Resource.Replacer().Replace(f.Path) if f.Force { - f.IfExistsAction = file.Overwrite + f.IfExistsAction = machinery.OverwriteFile } else { - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error } f.TemplateBody = crdSampleTemplate diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/webhook/kustomization.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/webhook/kustomization.go index c16ee89b9f6..7157dd8380c 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/webhook/kustomization.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/webhook/kustomization.go @@ -19,14 +19,14 @@ package webhook import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Kustomization{} +var _ machinery.Template = &Kustomization{} // Kustomization scaffolds a file that defines the kustomization scheme for the webhook folder type Kustomization struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template @@ -37,7 +37,7 @@ func (f *Kustomization) SetTemplateDefaults() error { f.TemplateBody = kustomizeWebhookTemplate - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error return nil } diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/webhook/kustomizeconfig.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/webhook/kustomizeconfig.go index 1b43d4ee825..ac2c92cc89e 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/webhook/kustomizeconfig.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/webhook/kustomizeconfig.go @@ -19,14 +19,14 @@ package webhook import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &KustomizeConfig{} +var _ machinery.Template = &KustomizeConfig{} // KustomizeConfig scaffolds a file that configures the kustomization for the webhook folder type KustomizeConfig struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template @@ -37,7 +37,7 @@ func (f *KustomizeConfig) SetTemplateDefaults() error { f.TemplateBody = kustomizeConfigWebhookTemplate - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error return nil } diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/webhook/service.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/webhook/service.go index 3a2689c4d42..7783aa136c4 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/config/webhook/service.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/config/webhook/service.go @@ -19,14 +19,14 @@ package webhook import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Service{} +var _ machinery.Template = &Service{} // Service scaffolds a file that defines the webhook service type Service struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template @@ -37,7 +37,7 @@ func (f *Service) SetTemplateDefaults() error { f.TemplateBody = serviceTemplate - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error return nil } diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/controllers/controller.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/controllers/controller.go index ee059001455..3d400d399e1 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/controllers/controller.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/controllers/controller.go @@ -20,18 +20,18 @@ import ( "fmt" "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Controller{} +var _ machinery.Template = &Controller{} // Controller scaffolds the file that defines the controller for a CRD or a builtin resource // nolint:maligned type Controller struct { - file.TemplateMixin - file.MultiGroupMixin - file.BoilerplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.MultiGroupMixin + machinery.BoilerplateMixin + machinery.ResourceMixin ControllerRuntimeVersion string @@ -53,9 +53,9 @@ func (f *Controller) SetTemplateDefaults() error { f.TemplateBody = controllerTemplate if f.Force { - f.IfExistsAction = file.Overwrite + f.IfExistsAction = machinery.OverwriteFile } else { - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error } return nil diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/controllers/controller_suitetest.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/controllers/controller_suitetest.go index 61bd1d584d7..31cef7a8650 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/controllers/controller_suitetest.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/controllers/controller_suitetest.go @@ -20,19 +20,19 @@ import ( "fmt" "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &SuiteTest{} -var _ file.Inserter = &SuiteTest{} +var _ machinery.Template = &SuiteTest{} +var _ machinery.Inserter = &SuiteTest{} // SuiteTest scaffolds the file that sets up the controller tests // nolint:maligned type SuiteTest struct { - file.TemplateMixin - file.MultiGroupMixin - file.BoilerplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.MultiGroupMixin + machinery.BoilerplateMixin + machinery.ResourceMixin // CRDDirectoryRelativePath define the Path for the CRD CRDDirectoryRelativePath string @@ -52,8 +52,8 @@ func (f *SuiteTest) SetTemplateDefaults() error { f.Path = f.Resource.Replacer().Replace(f.Path) f.TemplateBody = fmt.Sprintf(controllerSuiteTestTemplate, - file.NewMarkerFor(f.Path, importMarker), - file.NewMarkerFor(f.Path, addSchemeMarker), + machinery.NewMarkerFor(f.Path, importMarker), + machinery.NewMarkerFor(f.Path, addSchemeMarker), ) // If is multigroup the path needs to be ../../ since it has @@ -64,7 +64,7 @@ func (f *SuiteTest) SetTemplateDefaults() error { } if f.Force { - f.IfExistsAction = file.Overwrite + f.IfExistsAction = machinery.OverwriteFile } return nil @@ -76,10 +76,10 @@ const ( ) // GetMarkers implements file.Inserter -func (f *SuiteTest) GetMarkers() []file.Marker { - return []file.Marker{ - file.NewMarkerFor(f.Path, importMarker), - file.NewMarkerFor(f.Path, addSchemeMarker), +func (f *SuiteTest) GetMarkers() []machinery.Marker { + return []machinery.Marker{ + machinery.NewMarkerFor(f.Path, importMarker), + machinery.NewMarkerFor(f.Path, addSchemeMarker), } } @@ -93,8 +93,8 @@ Expect(err).NotTo(HaveOccurred()) ) // GetCodeFragments implements file.Inserter -func (f *SuiteTest) GetCodeFragments() file.CodeFragmentsMap { - fragments := make(file.CodeFragmentsMap, 2) +func (f *SuiteTest) GetCodeFragments() machinery.CodeFragmentsMap { + fragments := make(machinery.CodeFragmentsMap, 2) // Generate import code fragments imports := make([]string, 0) @@ -110,10 +110,10 @@ func (f *SuiteTest) GetCodeFragments() file.CodeFragmentsMap { // Only store code fragments in the map if the slices are non-empty if len(imports) != 0 { - fragments[file.NewMarkerFor(f.Path, importMarker)] = imports + fragments[machinery.NewMarkerFor(f.Path, importMarker)] = imports } if len(addScheme) != 0 { - fragments[file.NewMarkerFor(f.Path, addSchemeMarker)] = addScheme + fragments[machinery.NewMarkerFor(f.Path, addSchemeMarker)] = addScheme } return fragments diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/dockerfile.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/dockerfile.go index 1d20cafef78..38e4c47167c 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/dockerfile.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/dockerfile.go @@ -17,14 +17,14 @@ limitations under the License. package templates import ( - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Dockerfile{} +var _ machinery.Template = &Dockerfile{} // Dockerfile scaffolds a file that defines the containerized build process type Dockerfile struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/gitignore.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/gitignore.go index 4505799177b..a60f46d6760 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/gitignore.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/gitignore.go @@ -17,14 +17,14 @@ limitations under the License. package templates import ( - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &GitIgnore{} +var _ machinery.Template = &GitIgnore{} // GitIgnore scaffolds a file that defines which files should be ignored by git type GitIgnore struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/gomod.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/gomod.go index f40e8eda54d..e369bc98567 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/gomod.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/gomod.go @@ -17,15 +17,15 @@ limitations under the License. package templates import ( - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &GoMod{} +var _ machinery.Template = &GoMod{} // GoMod scaffolds a file that defines the project dependencies type GoMod struct { - file.TemplateMixin - file.RepositoryMixin + machinery.TemplateMixin + machinery.RepositoryMixin ControllerRuntimeVersion string } @@ -38,7 +38,7 @@ func (f *GoMod) SetTemplateDefaults() error { f.TemplateBody = goModTemplate - f.IfExistsAction = file.Overwrite + f.IfExistsAction = machinery.OverwriteFile return nil } diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/hack/boilerplate.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/hack/boilerplate.go index a7b6dac612e..1d07c79b45a 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/hack/boilerplate.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/hack/boilerplate.go @@ -21,18 +21,18 @@ import ( "path/filepath" "time" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) // DefaultBoilerplatePath is the default path to the boilerplate file var DefaultBoilerplatePath = filepath.Join("hack", "boilerplate.go.txt") -var _ file.Template = &Boilerplate{} +var _ machinery.Template = &Boilerplate{} // Boilerplate scaffolds a file that defines the common header for the rest of the files type Boilerplate struct { - file.TemplateMixin - file.BoilerplateMixin + machinery.TemplateMixin + machinery.BoilerplateMixin // License is the License type to write License string diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/main.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/main.go index f234d80970a..c2bd6928d85 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/main.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/main.go @@ -20,19 +20,19 @@ import ( "fmt" "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) const defaultMainPath = "main.go" -var _ file.Template = &Main{} +var _ machinery.Template = &Main{} // Main scaffolds a file that defines the controller manager entry point type Main struct { - file.TemplateMixin - file.BoilerplateMixin - file.DomainMixin - file.RepositoryMixin + machinery.TemplateMixin + machinery.BoilerplateMixin + machinery.DomainMixin + machinery.RepositoryMixin } // SetTemplateDefaults implements file.Template @@ -42,21 +42,21 @@ func (f *Main) SetTemplateDefaults() error { } f.TemplateBody = fmt.Sprintf(mainTemplate, - file.NewMarkerFor(f.Path, importMarker), - file.NewMarkerFor(f.Path, addSchemeMarker), - file.NewMarkerFor(f.Path, setupMarker), + machinery.NewMarkerFor(f.Path, importMarker), + machinery.NewMarkerFor(f.Path, addSchemeMarker), + machinery.NewMarkerFor(f.Path, setupMarker), ) return nil } -var _ file.Inserter = &MainUpdater{} +var _ machinery.Inserter = &MainUpdater{} // MainUpdater updates main.go to run Controllers type MainUpdater struct { //nolint:maligned - file.RepositoryMixin - file.MultiGroupMixin - file.ResourceMixin + machinery.RepositoryMixin + machinery.MultiGroupMixin + machinery.ResourceMixin // Flags to indicate which parts need to be included when updating the file WireResource, WireController, WireWebhook bool @@ -68,8 +68,8 @@ func (*MainUpdater) GetPath() string { } // GetIfExistsAction implements file.Builder -func (*MainUpdater) GetIfExistsAction() file.IfExistsAction { - return file.Overwrite +func (*MainUpdater) GetIfExistsAction() machinery.IfExistsAction { + return machinery.OverwriteFile } const ( @@ -79,11 +79,11 @@ const ( ) // GetMarkers implements file.Inserter -func (f *MainUpdater) GetMarkers() []file.Marker { - return []file.Marker{ - file.NewMarkerFor(defaultMainPath, importMarker), - file.NewMarkerFor(defaultMainPath, addSchemeMarker), - file.NewMarkerFor(defaultMainPath, setupMarker), +func (f *MainUpdater) GetMarkers() []machinery.Marker { + return []machinery.Marker{ + machinery.NewMarkerFor(defaultMainPath, importMarker), + machinery.NewMarkerFor(defaultMainPath, addSchemeMarker), + machinery.NewMarkerFor(defaultMainPath, setupMarker), } } @@ -122,8 +122,8 @@ const ( ) // GetCodeFragments implements file.Inserter -func (f *MainUpdater) GetCodeFragments() file.CodeFragmentsMap { - fragments := make(file.CodeFragmentsMap, 3) +func (f *MainUpdater) GetCodeFragments() machinery.CodeFragmentsMap { + fragments := make(machinery.CodeFragmentsMap, 3) // If resource is not being provided we are creating the file, not updating it if f.Resource == nil { @@ -169,13 +169,13 @@ func (f *MainUpdater) GetCodeFragments() file.CodeFragmentsMap { // Only store code fragments in the map if the slices are non-empty if len(imports) != 0 { - fragments[file.NewMarkerFor(defaultMainPath, importMarker)] = imports + fragments[machinery.NewMarkerFor(defaultMainPath, importMarker)] = imports } if len(addScheme) != 0 { - fragments[file.NewMarkerFor(defaultMainPath, addSchemeMarker)] = addScheme + fragments[machinery.NewMarkerFor(defaultMainPath, addSchemeMarker)] = addScheme } if len(setup) != 0 { - fragments[file.NewMarkerFor(defaultMainPath, setupMarker)] = setup + fragments[machinery.NewMarkerFor(defaultMainPath, setupMarker)] = setup } return fragments diff --git a/pkg/plugins/golang/v2/scaffolds/internal/templates/makefile.go b/pkg/plugins/golang/v2/scaffolds/internal/templates/makefile.go index cea72da1141..e799bd05cc9 100644 --- a/pkg/plugins/golang/v2/scaffolds/internal/templates/makefile.go +++ b/pkg/plugins/golang/v2/scaffolds/internal/templates/makefile.go @@ -17,14 +17,14 @@ limitations under the License. package templates import ( - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Makefile{} +var _ machinery.Template = &Makefile{} // Makefile scaffolds a file that defines project management CLI commands type Makefile struct { - file.TemplateMixin + machinery.TemplateMixin // Image is controller manager image name Image string @@ -44,7 +44,7 @@ func (f *Makefile) SetTemplateDefaults() error { f.TemplateBody = makefileTemplate - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error if f.Image == "" { f.Image = "controller:latest" diff --git a/pkg/plugins/golang/v2/scaffolds/webhook.go b/pkg/plugins/golang/v2/scaffolds/webhook.go index f2d973ce4ce..c7ac711a127 100644 --- a/pkg/plugins/golang/v2/scaffolds/webhook.go +++ b/pkg/plugins/golang/v2/scaffolds/webhook.go @@ -22,28 +22,26 @@ import ( "github.com/spf13/afero" "sigs.k8s.io/kubebuilder/v3/pkg/config" - "sigs.k8s.io/kubebuilder/v3/pkg/model" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" "sigs.k8s.io/kubebuilder/v3/pkg/model/resource" + "sigs.k8s.io/kubebuilder/v3/pkg/plugins" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates/api" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates/hack" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/cmdutil" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/machinery" ) -var _ cmdutil.Scaffolder = &webhookScaffolder{} +var _ plugins.Scaffolder = &webhookScaffolder{} type webhookScaffolder struct { - config config.Config - boilerplate string - resource resource.Resource + config config.Config + resource resource.Resource // fs is the filesystem that will be used by the scaffolder fs afero.Fs } // NewWebhookScaffolder returns a new Scaffolder for v2 webhook creation operations -func NewWebhookScaffolder(config config.Config, resource resource.Resource) cmdutil.Scaffolder { +func NewWebhookScaffolder(config config.Config, resource resource.Resource) plugins.Scaffolder { return &webhookScaffolder{ config: config, resource: resource, @@ -55,31 +53,28 @@ func (s *webhookScaffolder) InjectFS(fs afero.Fs) { s.fs = fs } -func (s *webhookScaffolder) newUniverse() *model.Universe { - return model.NewUniverse( - model.WithConfig(s.config), - model.WithBoilerplate(s.boilerplate), - model.WithResource(&s.resource), - ) -} - // Scaffold implements cmdutil.Scaffolder func (s *webhookScaffolder) Scaffold() error { fmt.Println("Writing scaffold for you to edit...") // Load the boilerplate - bp, err := afero.ReadFile(s.fs, hack.DefaultBoilerplatePath) + boilerplate, err := afero.ReadFile(s.fs, hack.DefaultBoilerplatePath) if err != nil { return fmt.Errorf("error scaffolding webhook: unable to load boilerplate: %w", err) } - s.boilerplate = string(bp) + + // Initialize the machinery.Scaffold that will write the files to disk + scaffold := machinery.NewScaffold(s.fs, + machinery.WithConfig(s.config), + machinery.WithBoilerplate(string(boilerplate)), + machinery.WithResource(&s.resource), + ) if err := s.config.UpdateResource(s.resource); err != nil { return fmt.Errorf("error updating resource: %w", err) } - if err := machinery.NewScaffold(s.fs).Execute( - s.newUniverse(), + if err := scaffold.Execute( &api.Webhook{}, &templates.MainUpdater{WireWebhook: true}, ); err != nil { diff --git a/pkg/plugins/golang/v3/api.go b/pkg/plugins/golang/v3/api.go index e912f415a29..76d398475d1 100644 --- a/pkg/plugins/golang/v3/api.go +++ b/pkg/plugins/golang/v3/api.go @@ -26,22 +26,15 @@ import ( "github.com/spf13/pflag" "sigs.k8s.io/kubebuilder/v3/pkg/config" - "sigs.k8s.io/kubebuilder/v3/pkg/model" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery/util" "sigs.k8s.io/kubebuilder/v3/pkg/model/resource" "sigs.k8s.io/kubebuilder/v3/pkg/plugin" pluginutil "sigs.k8s.io/kubebuilder/v3/pkg/plugin/util" goPlugin "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/util" - "sigs.k8s.io/kubebuilder/v3/plugins/addon" ) const ( - // KbDeclarativePatternVersion is the sigs.k8s.io/kubebuilder-declarative-pattern version - // (used only to gen api with --pattern=addon) - // TODO: remove this when a better solution for using addons is implemented. - KbDeclarativePatternVersion = "b84d99da021778217217885dd9582ed3cc879ebe" - // defaultCRDVersion is the default CRD API version to scaffold. defaultCRDVersion = "v1" ) @@ -54,9 +47,6 @@ var _ plugin.CreateAPISubcommand = &createAPISubcommand{} type createAPISubcommand struct { config config.Config - // pattern indicates that we should use a plugin to build according to a pattern - pattern string - options *goPlugin.Options resource *resource.Resource @@ -104,12 +94,6 @@ After the scaffold is written, api will run make on the project. func (p *createAPISubcommand) BindFlags(fs *pflag.FlagSet) { fs.BoolVar(&p.runMake, "make", true, "if true, run `make generate` after generating files") - // TODO: remove this when a better solution for using addons is implemented. - if os.Getenv("KUBEBUILDER_ENABLE_PLUGINS") != "" { - fs.StringVar(&p.pattern, "pattern", "", - "generates an API following an extension pattern (addon)") - } - fs.BoolVar(&p.force, "force", false, "attempt to create resource even if it already exists") @@ -190,44 +174,16 @@ func (p *createAPISubcommand) PreScaffold(afero.Fs) error { } func (p *createAPISubcommand) Scaffold(fs afero.Fs) error { - // Load the requested plugins - plugins := make([]model.Plugin, 0) - switch strings.ToLower(p.pattern) { - case "": - // Default pattern - case "addon": - plugins = append(plugins, &addon.Plugin{}) - default: - return fmt.Errorf("unknown pattern %q", p.pattern) - } - - scaffolder := scaffolds.NewAPIScaffolder(p.config, *p.resource, p.force, plugins) + scaffolder := scaffolds.NewAPIScaffolder(p.config, *p.resource, p.force) scaffolder.InjectFS(fs) return scaffolder.Scaffold() } func (p *createAPISubcommand) PostScaffold() error { - // Load the requested plugins - switch strings.ToLower(p.pattern) { - case "": - // Default pattern - case "addon": - // Ensure that we are pinning sigs.k8s.io/kubebuilder-declarative-pattern version - // TODO: either find a better way to inject this version (ex. tools.go). - err := util.RunCmd("Get kubebuilder-declarative-pattern dependency", "go", "get", - "sigs.k8s.io/kubebuilder-declarative-pattern@"+KbDeclarativePatternVersion) - if err != nil { - return err - } - default: - return fmt.Errorf("unknown pattern %q", p.pattern) - } - err := util.RunCmd("Update dependencies", "go", "mod", "tidy") if err != nil { return err } - if p.runMake && p.resource.HasAPI() { err = util.RunCmd("Running make", "make", "generate") if err != nil { diff --git a/pkg/plugins/golang/v3/init.go b/pkg/plugins/golang/v3/init.go index 91e31046528..c7bcc5cdf00 100644 --- a/pkg/plugins/golang/v3/init.go +++ b/pkg/plugins/golang/v3/init.go @@ -27,9 +27,9 @@ import ( "sigs.k8s.io/kubebuilder/v3/pkg/config" "sigs.k8s.io/kubebuilder/v3/pkg/internal/validation" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery/util" "sigs.k8s.io/kubebuilder/v3/pkg/plugin" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/util" ) var _ plugin.InitSubcommand = &initSubcommand{} diff --git a/pkg/plugins/golang/v3/scaffolds/api.go b/pkg/plugins/golang/v3/scaffolds/api.go index 5c200d00067..f2797f6c524 100644 --- a/pkg/plugins/golang/v3/scaffolds/api.go +++ b/pkg/plugins/golang/v3/scaffolds/api.go @@ -22,8 +22,9 @@ import ( "github.com/spf13/afero" "sigs.k8s.io/kubebuilder/v3/pkg/config" - "sigs.k8s.io/kubebuilder/v3/pkg/model" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" "sigs.k8s.io/kubebuilder/v3/pkg/model/resource" + "sigs.k8s.io/kubebuilder/v3/pkg/plugins" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates/api" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates/config/crd" @@ -32,25 +33,19 @@ import ( "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates/config/samples" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates/controllers" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates/hack" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/cmdutil" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/machinery" ) -var _ cmdutil.Scaffolder = &apiScaffolder{} +var _ plugins.Scaffolder = &apiScaffolder{} // apiScaffolder contains configuration for generating scaffolding for Go type // representing the API and controller that implements the behavior for the API. type apiScaffolder struct { - config config.Config - boilerplate string - resource resource.Resource + config config.Config + resource resource.Resource // fs is the filesystem that will be used by the scaffolder fs afero.Fs - // plugins is the list of plugins we should allow to transform our generated scaffolding - plugins []model.Plugin - // force indicates whether to scaffold controller files even if it exists or not force bool } @@ -60,12 +55,10 @@ func NewAPIScaffolder( config config.Config, res resource.Resource, force bool, - plugins []model.Plugin, -) cmdutil.Scaffolder { +) plugins.Scaffolder { return &apiScaffolder{ config: config, resource: res, - plugins: plugins, force: force, } } @@ -75,24 +68,22 @@ func (s *apiScaffolder) InjectFS(fs afero.Fs) { s.fs = fs } -func (s *apiScaffolder) newUniverse() *model.Universe { - return model.NewUniverse( - model.WithConfig(s.config), - model.WithBoilerplate(s.boilerplate), - model.WithResource(&s.resource), - ) -} - // Scaffold implements cmdutil.Scaffolder func (s *apiScaffolder) Scaffold() error { fmt.Println("Writing scaffold for you to edit...") // Load the boilerplate - bp, err := afero.ReadFile(s.fs, hack.DefaultBoilerplatePath) + boilerplate, err := afero.ReadFile(s.fs, hack.DefaultBoilerplatePath) if err != nil { return fmt.Errorf("error scaffolding API/controller: unable to load boilerplate: %w", err) } - s.boilerplate = string(bp) + + // Initialize the machinery.Scaffold that will write the files to disk + scaffold := machinery.NewScaffold(s.fs, + machinery.WithConfig(s.config), + machinery.WithBoilerplate(string(boilerplate)), + machinery.WithResource(&s.resource), + ) // Keep track of these values before the update doAPI := s.resource.HasAPI() @@ -104,8 +95,7 @@ func (s *apiScaffolder) Scaffold() error { if doAPI { - if err := machinery.NewScaffold(s.fs, s.plugins...).Execute( - s.newUniverse(), + if err := scaffold.Execute( &api.Types{Force: s.force}, &api.Group{}, &samples.CRDSample{Force: s.force}, @@ -117,8 +107,7 @@ func (s *apiScaffolder) Scaffold() error { return fmt.Errorf("error scaffolding APIs: %v", err) } - if err := machinery.NewScaffold(s.fs).Execute( - s.newUniverse(), + if err := scaffold.Execute( &crd.Kustomization{}, &crd.KustomizeConfig{}, ); err != nil { @@ -128,8 +117,7 @@ func (s *apiScaffolder) Scaffold() error { } if doController { - if err := machinery.NewScaffold(s.fs, s.plugins...).Execute( - s.newUniverse(), + if err := scaffold.Execute( &controllers.SuiteTest{Force: s.force}, &controllers.Controller{ControllerRuntimeVersion: ControllerRuntimeVersion, Force: s.force}, ); err != nil { @@ -137,8 +125,7 @@ func (s *apiScaffolder) Scaffold() error { } } - if err := machinery.NewScaffold(s.fs, s.plugins...).Execute( - s.newUniverse(), + if err := scaffold.Execute( &templates.MainUpdater{WireResource: doAPI, WireController: doController}, ); err != nil { return fmt.Errorf("error updating main.go: %v", err) diff --git a/pkg/plugins/golang/v3/scaffolds/edit.go b/pkg/plugins/golang/v3/scaffolds/edit.go index 2b15a83339e..e62d95c6deb 100644 --- a/pkg/plugins/golang/v3/scaffolds/edit.go +++ b/pkg/plugins/golang/v3/scaffolds/edit.go @@ -23,10 +23,10 @@ import ( "github.com/spf13/afero" "sigs.k8s.io/kubebuilder/v3/pkg/config" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/cmdutil" + "sigs.k8s.io/kubebuilder/v3/pkg/plugins" ) -var _ cmdutil.Scaffolder = &editScaffolder{} +var _ plugins.Scaffolder = &editScaffolder{} type editScaffolder struct { config config.Config @@ -37,7 +37,7 @@ type editScaffolder struct { } // NewEditScaffolder returns a new Scaffolder for configuration edit operations -func NewEditScaffolder(config config.Config, multigroup bool) cmdutil.Scaffolder { +func NewEditScaffolder(config config.Config, multigroup bool) plugins.Scaffolder { return &editScaffolder{ config: config, multigroup: multigroup, diff --git a/pkg/plugins/golang/v3/scaffolds/init.go b/pkg/plugins/golang/v3/scaffolds/init.go index 92592d60368..ae53ea95444 100644 --- a/pkg/plugins/golang/v3/scaffolds/init.go +++ b/pkg/plugins/golang/v3/scaffolds/init.go @@ -23,7 +23,8 @@ import ( "github.com/spf13/afero" "sigs.k8s.io/kubebuilder/v3/pkg/config" - "sigs.k8s.io/kubebuilder/v3/pkg/model" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" + "sigs.k8s.io/kubebuilder/v3/pkg/plugins" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates/config/certmanager" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault" @@ -31,8 +32,6 @@ import ( "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates/config/prometheus" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates/hack" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/cmdutil" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/machinery" ) const ( @@ -46,7 +45,7 @@ const ( imageName = "controller:latest" ) -var _ cmdutil.Scaffolder = &initScaffolder{} +var _ plugins.Scaffolder = &initScaffolder{} type initScaffolder struct { config config.Config @@ -59,7 +58,7 @@ type initScaffolder struct { } // NewInitScaffolder returns a new Scaffolder for project initialization operations -func NewInitScaffolder(config config.Config, license, owner string) cmdutil.Scaffolder { +func NewInitScaffolder(config config.Config, license, owner string) plugins.Scaffolder { return &initScaffolder{ config: config, boilerplatePath: filepath.Join("hack", "boilerplate.go.txt"), @@ -73,25 +72,23 @@ func (s *initScaffolder) InjectFS(fs afero.Fs) { s.fs = fs } -func (s *initScaffolder) newUniverse(boilerplate string) *model.Universe { - return model.NewUniverse( - model.WithConfig(s.config), - model.WithBoilerplate(boilerplate), - ) -} - // Scaffold implements cmdutil.Scaffolder func (s *initScaffolder) Scaffold() error { fmt.Println("Writing scaffold for you to edit...") - bpFile := &hack.Boilerplate{} + // Initialize the machinery.Scaffold that will write the boilerplate file to disk + // The boilerplate file needs to be scaffolded as a separate step as it is going to + // be used by the rest of the files, even those scaffolded in this command call. + scaffold := machinery.NewScaffold(s.fs, + machinery.WithConfig(s.config), + ) + + bpFile := &hack.Boilerplate{ + License: s.license, + Owner: s.owner, + } bpFile.Path = s.boilerplatePath - bpFile.License = s.license - bpFile.Owner = s.owner - if err := machinery.NewScaffold(s.fs).Execute( - s.newUniverse(""), - bpFile, - ); err != nil { + if err := scaffold.Execute(bpFile); err != nil { return err } @@ -100,8 +97,13 @@ func (s *initScaffolder) Scaffold() error { return err } - return machinery.NewScaffold(s.fs).Execute( - s.newUniverse(string(boilerplate)), + // Initialize the machinery.Scaffold that will write the files to disk + scaffold = machinery.NewScaffold(s.fs, + machinery.WithConfig(s.config), + machinery.WithBoilerplate(string(boilerplate)), + ) + + return scaffold.Execute( &rbac.Kustomization{}, &rbac.AuthProxyRole{}, &rbac.AuthProxyRoleBinding{}, diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/api/group.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/api/group.go index f8c1faa7e2b..8c93af689a0 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/api/group.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/api/group.go @@ -19,17 +19,17 @@ package api import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Group{} +var _ machinery.Template = &Group{} // Group scaffolds the file that defines the registration methods for a certain group and version type Group struct { - file.TemplateMixin - file.MultiGroupMixin - file.BoilerplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.MultiGroupMixin + machinery.BoilerplateMixin + machinery.ResourceMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/api/types.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/api/types.go index 4c253344db0..a76e3cb1391 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/api/types.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/api/types.go @@ -20,18 +20,18 @@ import ( "fmt" "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Types{} +var _ machinery.Template = &Types{} // Types scaffolds the file that defines the schema for a CRD // nolint:maligned type Types struct { - file.TemplateMixin - file.MultiGroupMixin - file.BoilerplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.MultiGroupMixin + machinery.BoilerplateMixin + machinery.ResourceMixin Force bool } @@ -55,9 +55,9 @@ func (f *Types) SetTemplateDefaults() error { f.TemplateBody = typesTemplate if f.Force { - f.IfExistsAction = file.Overwrite + f.IfExistsAction = machinery.OverwriteFile } else { - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error } return nil diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/api/webhook.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/api/webhook.go index f3f9c6ccd76..f51ef49bda0 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/api/webhook.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/api/webhook.go @@ -21,17 +21,17 @@ import ( "path/filepath" "strings" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Webhook{} +var _ machinery.Template = &Webhook{} // Webhook scaffolds the file that defines a webhook for a CRD or a builtin resource type Webhook struct { // nolint:maligned - file.TemplateMixin - file.MultiGroupMixin - file.BoilerplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.MultiGroupMixin + machinery.BoilerplateMixin + machinery.ResourceMixin // Is the Group domain for the Resource replacing '.' with '-' QualifiedGroupWithDash string @@ -65,9 +65,9 @@ func (f *Webhook) SetTemplateDefaults() error { f.TemplateBody = webhookTemplate if f.Force { - f.IfExistsAction = file.Overwrite + f.IfExistsAction = machinery.OverwriteFile } else { - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error } f.QualifiedGroupWithDash = strings.Replace(f.Resource.QualifiedGroup(), ".", "-", -1) diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/api/webhook_suitetest.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/api/webhook_suitetest.go index f708a8afbb8..7f30dd89f37 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/api/webhook_suitetest.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/api/webhook_suitetest.go @@ -4,18 +4,18 @@ import ( "fmt" "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &WebhookSuite{} -var _ file.Inserter = &WebhookSuite{} +var _ machinery.Template = &WebhookSuite{} +var _ machinery.Inserter = &WebhookSuite{} // WebhookSuite scaffolds the file that sets up the webhook tests type WebhookSuite struct { //nolint:maligned - file.TemplateMixin - file.MultiGroupMixin - file.BoilerplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.MultiGroupMixin + machinery.BoilerplateMixin + machinery.ResourceMixin // todo: currently is not possible to know if an API was or not scaffolded. We can fix it when #1826 be addressed WireResource bool @@ -40,9 +40,9 @@ func (f *WebhookSuite) SetTemplateDefaults() error { f.Path = f.Resource.Replacer().Replace(f.Path) f.TemplateBody = fmt.Sprintf(webhookTestSuiteTemplate, - file.NewMarkerFor(f.Path, importMarker), - file.NewMarkerFor(f.Path, addSchemeMarker), - file.NewMarkerFor(f.Path, addWebhookManagerMarker), + machinery.NewMarkerFor(f.Path, importMarker), + machinery.NewMarkerFor(f.Path, addSchemeMarker), + machinery.NewMarkerFor(f.Path, addWebhookManagerMarker), "%s", "%d", ) @@ -66,11 +66,11 @@ const ( ) // GetMarkers implements file.Inserter -func (f *WebhookSuite) GetMarkers() []file.Marker { - return []file.Marker{ - file.NewMarkerFor(f.Path, importMarker), - file.NewMarkerFor(f.Path, addSchemeMarker), - file.NewMarkerFor(f.Path, addWebhookManagerMarker), +func (f *WebhookSuite) GetMarkers() []machinery.Marker { + return []machinery.Marker{ + machinery.NewMarkerFor(f.Path, importMarker), + machinery.NewMarkerFor(f.Path, addSchemeMarker), + machinery.NewMarkerFor(f.Path, addWebhookManagerMarker), } } @@ -88,8 +88,8 @@ Expect(err).NotTo(HaveOccurred()) ) // GetCodeFragments implements file.Inserter -func (f *WebhookSuite) GetCodeFragments() file.CodeFragmentsMap { - fragments := make(file.CodeFragmentsMap, 3) +func (f *WebhookSuite) GetCodeFragments() machinery.CodeFragmentsMap { + fragments := make(machinery.CodeFragmentsMap, 3) // Generate import code fragments imports := make([]string, 0) @@ -105,13 +105,13 @@ func (f *WebhookSuite) GetCodeFragments() file.CodeFragmentsMap { // Only store code fragments in the map if the slices are non-empty if len(addWebhookManager) != 0 { - fragments[file.NewMarkerFor(f.Path, addWebhookManagerMarker)] = addWebhookManager + fragments[machinery.NewMarkerFor(f.Path, addWebhookManagerMarker)] = addWebhookManager } if len(imports) != 0 { - fragments[file.NewMarkerFor(f.Path, importMarker)] = imports + fragments[machinery.NewMarkerFor(f.Path, importMarker)] = imports } if len(addScheme) != 0 { - fragments[file.NewMarkerFor(f.Path, addSchemeMarker)] = addScheme + fragments[machinery.NewMarkerFor(f.Path, addSchemeMarker)] = addScheme } return fragments diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/certmanager/certificate.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/certmanager/certificate.go index a654f82951f..76c2b186f65 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/certmanager/certificate.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/certmanager/certificate.go @@ -19,14 +19,14 @@ package certmanager import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Certificate{} +var _ machinery.Template = &Certificate{} // Certificate scaffolds a file that defines the issuer CR and the certificate CR type Certificate struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/certmanager/kustomization.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/certmanager/kustomization.go index 4210f6f133b..522bdd9b67f 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/certmanager/kustomization.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/certmanager/kustomization.go @@ -19,14 +19,14 @@ package certmanager import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Kustomization{} +var _ machinery.Template = &Kustomization{} // Kustomization scaffolds a file that defines the kustomization scheme for the certmanager folder type Kustomization struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/certmanager/kustomizeconfig.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/certmanager/kustomizeconfig.go index 8ade67534fc..573a7e8f602 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/certmanager/kustomizeconfig.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/certmanager/kustomizeconfig.go @@ -19,14 +19,14 @@ package certmanager import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &KustomizeConfig{} +var _ machinery.Template = &KustomizeConfig{} // KustomizeConfig scaffolds a file that configures the kustomization for the certmanager folder type KustomizeConfig struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/crd/kustomization.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/crd/kustomization.go index 9a87af34668..23690588e9f 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/crd/kustomization.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/crd/kustomization.go @@ -20,16 +20,16 @@ import ( "fmt" "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Kustomization{} -var _ file.Inserter = &Kustomization{} +var _ machinery.Template = &Kustomization{} +var _ machinery.Inserter = &Kustomization{} // Kustomization scaffolds a file that defines the kustomization scheme for the crd folder type Kustomization struct { - file.TemplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.ResourceMixin } // SetTemplateDefaults implements file.Template @@ -40,9 +40,9 @@ func (f *Kustomization) SetTemplateDefaults() error { f.Path = f.Resource.Replacer().Replace(f.Path) f.TemplateBody = fmt.Sprintf(kustomizationTemplate, - file.NewMarkerFor(f.Path, resourceMarker), - file.NewMarkerFor(f.Path, webhookPatchMarker), - file.NewMarkerFor(f.Path, caInjectionPatchMarker), + machinery.NewMarkerFor(f.Path, resourceMarker), + machinery.NewMarkerFor(f.Path, webhookPatchMarker), + machinery.NewMarkerFor(f.Path, caInjectionPatchMarker), ) return nil @@ -55,11 +55,11 @@ const ( ) // GetMarkers implements file.Inserter -func (f *Kustomization) GetMarkers() []file.Marker { - return []file.Marker{ - file.NewMarkerFor(f.Path, resourceMarker), - file.NewMarkerFor(f.Path, webhookPatchMarker), - file.NewMarkerFor(f.Path, caInjectionPatchMarker), +func (f *Kustomization) GetMarkers() []machinery.Marker { + return []machinery.Marker{ + machinery.NewMarkerFor(f.Path, resourceMarker), + machinery.NewMarkerFor(f.Path, webhookPatchMarker), + machinery.NewMarkerFor(f.Path, caInjectionPatchMarker), } } @@ -73,8 +73,8 @@ const ( ) // GetCodeFragments implements file.Inserter -func (f *Kustomization) GetCodeFragments() file.CodeFragmentsMap { - fragments := make(file.CodeFragmentsMap, 3) +func (f *Kustomization) GetCodeFragments() machinery.CodeFragmentsMap { + fragments := make(machinery.CodeFragmentsMap, 3) // Generate resource code fragments res := make([]string, 0) @@ -90,13 +90,13 @@ func (f *Kustomization) GetCodeFragments() file.CodeFragmentsMap { // Only store code fragments in the map if the slices are non-empty if len(res) != 0 { - fragments[file.NewMarkerFor(f.Path, resourceMarker)] = res + fragments[machinery.NewMarkerFor(f.Path, resourceMarker)] = res } if len(webhookPatch) != 0 { - fragments[file.NewMarkerFor(f.Path, webhookPatchMarker)] = webhookPatch + fragments[machinery.NewMarkerFor(f.Path, webhookPatchMarker)] = webhookPatch } if len(caInjectionPatch) != 0 { - fragments[file.NewMarkerFor(f.Path, caInjectionPatchMarker)] = caInjectionPatch + fragments[machinery.NewMarkerFor(f.Path, caInjectionPatchMarker)] = caInjectionPatch } return fragments diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/crd/kustomizeconfig.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/crd/kustomizeconfig.go index 7b56a21c9df..428bfde8b88 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/crd/kustomizeconfig.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/crd/kustomizeconfig.go @@ -19,15 +19,15 @@ package crd import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &KustomizeConfig{} +var _ machinery.Template = &KustomizeConfig{} // KustomizeConfig scaffolds a file that configures the kustomization for the crd folder type KustomizeConfig struct { - file.TemplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.ResourceMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/crd/patches/enablecainjection_patch.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/crd/patches/enablecainjection_patch.go index c954670d1db..cc688e50f63 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/crd/patches/enablecainjection_patch.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/crd/patches/enablecainjection_patch.go @@ -19,15 +19,15 @@ package patches import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &EnableCAInjectionPatch{} +var _ machinery.Template = &EnableCAInjectionPatch{} // EnableCAInjectionPatch scaffolds a file that defines the patch that injects CA into the CRD type EnableCAInjectionPatch struct { - file.TemplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.ResourceMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/crd/patches/enablewebhook_patch.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/crd/patches/enablewebhook_patch.go index 7cc1da1d65e..1bf0e7ac071 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/crd/patches/enablewebhook_patch.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/crd/patches/enablewebhook_patch.go @@ -19,15 +19,15 @@ package patches import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &EnableWebhookPatch{} +var _ machinery.Template = &EnableWebhookPatch{} // EnableWebhookPatch scaffolds a file that defines the patch that enables conversion webhook for the CRD type EnableWebhookPatch struct { - file.TemplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.ResourceMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/enablecainection_patch.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/enablecainection_patch.go index a3ba80da2b9..d93780f7dfa 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/enablecainection_patch.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/enablecainection_patch.go @@ -19,15 +19,15 @@ package kdefault import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &WebhookCAInjectionPatch{} +var _ machinery.Template = &WebhookCAInjectionPatch{} // WebhookCAInjectionPatch scaffolds a file that defines the patch that adds annotation to webhooks type WebhookCAInjectionPatch struct { - file.TemplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.ResourceMixin } // SetTemplateDefaults implements file.Template @@ -39,7 +39,7 @@ func (f *WebhookCAInjectionPatch) SetTemplateDefaults() error { f.TemplateBody = injectCAPatchTemplate // If file exists (ex. because a webhook was already created), skip creation. - f.IfExistsAction = file.Skip + f.IfExistsAction = machinery.SkipFile return nil } diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/kustomization.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/kustomization.go index c7aea4259fb..b6860c307d0 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/kustomization.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/kustomization.go @@ -19,16 +19,16 @@ package kdefault import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Kustomization{} +var _ machinery.Template = &Kustomization{} // Kustomization scaffolds a file that defines the kustomization scheme for the default overlay folder type Kustomization struct { - file.TemplateMixin - file.ProjectNameMixin - file.ComponentConfigMixin + machinery.TemplateMixin + machinery.ProjectNameMixin + machinery.ComponentConfigMixin } // SetTemplateDefaults implements file.Template @@ -39,7 +39,7 @@ func (f *Kustomization) SetTemplateDefaults() error { f.TemplateBody = kustomizeTemplate - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error return nil } diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/manager_auth_proxy_patch.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/manager_auth_proxy_patch.go index 8cf97588bc9..c47ab74426f 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/manager_auth_proxy_patch.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/manager_auth_proxy_patch.go @@ -19,15 +19,15 @@ package kdefault import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &ManagerAuthProxyPatch{} +var _ machinery.Template = &ManagerAuthProxyPatch{} // ManagerAuthProxyPatch scaffolds a file that defines the patch that enables prometheus metrics for the manager type ManagerAuthProxyPatch struct { - file.TemplateMixin - file.ComponentConfigMixin + machinery.TemplateMixin + machinery.ComponentConfigMixin } // SetTemplateDefaults implements file.Template @@ -38,7 +38,7 @@ func (f *ManagerAuthProxyPatch) SetTemplateDefaults() error { f.TemplateBody = kustomizeAuthProxyPatchTemplate - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error return nil } diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/manager_config_patch.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/manager_config_patch.go index 8b32276fe7b..fb620573bbe 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/manager_config_patch.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/manager_config_patch.go @@ -19,14 +19,14 @@ package kdefault import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &ManagerConfigPatch{} +var _ machinery.Template = &ManagerConfigPatch{} // ManagerConfigPatch scaffolds a ManagerConfigPatch for a Resource type ManagerConfigPatch struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements input.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/webhook_manager_patch.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/webhook_manager_patch.go index 3d86dd4f091..7f993dbd31c 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/webhook_manager_patch.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/webhook_manager_patch.go @@ -19,14 +19,14 @@ package kdefault import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &ManagerWebhookPatch{} +var _ machinery.Template = &ManagerWebhookPatch{} // ManagerWebhookPatch scaffolds a file that defines the patch that enables webhooks on the manager type ManagerWebhookPatch struct { - file.TemplateMixin + machinery.TemplateMixin Force bool } @@ -40,10 +40,10 @@ func (f *ManagerWebhookPatch) SetTemplateDefaults() error { f.TemplateBody = managerWebhookPatchTemplate if f.Force { - f.IfExistsAction = file.Overwrite + f.IfExistsAction = machinery.OverwriteFile } else { // If file exists (ex. because a webhook was already created), skip creation. - f.IfExistsAction = file.Skip + f.IfExistsAction = machinery.SkipFile } return nil diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/config.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/config.go index 96663a7a6c9..eb972d5c2b3 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/config.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/config.go @@ -19,15 +19,15 @@ package manager import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Config{} +var _ machinery.Template = &Config{} // Config scaffolds a file that defines the namespace and the manager deployment type Config struct { - file.TemplateMixin - file.ComponentConfigMixin + machinery.TemplateMixin + machinery.ComponentConfigMixin // Image is controller manager image name Image string diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/controller_manager_config.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/controller_manager_config.go index ea18f2145a0..fa977d90ecb 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/controller_manager_config.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/controller_manager_config.go @@ -19,16 +19,16 @@ package manager import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &ControllerManagerConfig{} +var _ machinery.Template = &ControllerManagerConfig{} // ControllerManagerConfig scaffolds the config file in config/manager folder. type ControllerManagerConfig struct { - file.TemplateMixin - file.DomainMixin - file.RepositoryMixin + machinery.TemplateMixin + machinery.DomainMixin + machinery.RepositoryMixin } // SetTemplateDefaults implements input.Template @@ -39,7 +39,7 @@ func (f *ControllerManagerConfig) SetTemplateDefaults() error { f.TemplateBody = controllerManagerConfigTemplate - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error return nil } diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/kustomization.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/kustomization.go index 5b3f307acfb..eec807da3d1 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/kustomization.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/manager/kustomization.go @@ -19,14 +19,14 @@ package manager import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Kustomization{} +var _ machinery.Template = &Kustomization{} // Kustomization scaffolds a file that defines the kustomization scheme for the manager folder type Kustomization struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template @@ -37,7 +37,7 @@ func (f *Kustomization) SetTemplateDefaults() error { f.TemplateBody = kustomizeManagerTemplate - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error return nil } diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/prometheus/kustomization.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/prometheus/kustomization.go index e2cd771253a..76bf6e1c5e1 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/prometheus/kustomization.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/prometheus/kustomization.go @@ -19,14 +19,14 @@ package prometheus import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Kustomization{} +var _ machinery.Template = &Kustomization{} // Kustomization scaffolds a file that defines the kustomization scheme for the prometheus folder type Kustomization struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/prometheus/monitor.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/prometheus/monitor.go index 4ee7d32c1c2..41870f6850a 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/prometheus/monitor.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/prometheus/monitor.go @@ -19,14 +19,14 @@ package prometheus import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Monitor{} +var _ machinery.Template = &Monitor{} // Monitor scaffolds a file that defines the prometheus service monitor type Monitor struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/auth_proxy_client_role.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/auth_proxy_client_role.go index d7bfee31882..e41eeceb55e 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/auth_proxy_client_role.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/auth_proxy_client_role.go @@ -19,14 +19,14 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &AuthProxyClientRole{} +var _ machinery.Template = &AuthProxyClientRole{} // AuthProxyClientRole scaffolds a file that defines the role for the metrics reader type AuthProxyClientRole struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/auth_proxy_role.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/auth_proxy_role.go index f5900ec2b8e..0f359d78e4c 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/auth_proxy_role.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/auth_proxy_role.go @@ -19,14 +19,14 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &AuthProxyRole{} +var _ machinery.Template = &AuthProxyRole{} // AuthProxyRole scaffolds a file that defines the role for the auth proxy type AuthProxyRole struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/auth_proxy_role_binding.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/auth_proxy_role_binding.go index 3834de9bce4..b858591fae6 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/auth_proxy_role_binding.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/auth_proxy_role_binding.go @@ -19,14 +19,14 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &AuthProxyRoleBinding{} +var _ machinery.Template = &AuthProxyRoleBinding{} // AuthProxyRoleBinding scaffolds a file that defines the role binding for the auth proxy type AuthProxyRoleBinding struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/auth_proxy_service.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/auth_proxy_service.go index ffd9cd2ab19..f9c7249c829 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/auth_proxy_service.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/auth_proxy_service.go @@ -19,14 +19,14 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &AuthProxyService{} +var _ machinery.Template = &AuthProxyService{} // AuthProxyService scaffolds a file that defines the service for the auth proxy type AuthProxyService struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/crd_editor_role.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/crd_editor_role.go index a099b595e9b..a8832864277 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/crd_editor_role.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/crd_editor_role.go @@ -19,15 +19,15 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &CRDEditorRole{} +var _ machinery.Template = &CRDEditorRole{} // CRDEditorRole scaffolds a file that defines the role that allows to edit plurals type CRDEditorRole struct { - file.TemplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.ResourceMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/crd_viewer_role.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/crd_viewer_role.go index 0b3311650b7..d83c3295f53 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/crd_viewer_role.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/crd_viewer_role.go @@ -19,15 +19,15 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &CRDViewerRole{} +var _ machinery.Template = &CRDViewerRole{} // CRDViewerRole scaffolds a file that defines the role that allows to view plurals type CRDViewerRole struct { - file.TemplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.ResourceMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/kustomization.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/kustomization.go index 0966bd6d5d9..a4d285d508e 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/kustomization.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/kustomization.go @@ -19,14 +19,14 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Kustomization{} +var _ machinery.Template = &Kustomization{} // Kustomization scaffolds a file that defines the kustomization scheme for the rbac folder type Kustomization struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template @@ -37,7 +37,7 @@ func (f *Kustomization) SetTemplateDefaults() error { f.TemplateBody = kustomizeRBACTemplate - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error return nil } diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/leader_election_role.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/leader_election_role.go index 3f85432601f..1008bf2c387 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/leader_election_role.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/leader_election_role.go @@ -19,14 +19,14 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &LeaderElectionRole{} +var _ machinery.Template = &LeaderElectionRole{} // LeaderElectionRole scaffolds a file that defines the role that allows leader election type LeaderElectionRole struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/leader_election_role_binding.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/leader_election_role_binding.go index 8c67aac8a54..0d9401a9ba3 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/leader_election_role_binding.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/leader_election_role_binding.go @@ -19,14 +19,14 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &LeaderElectionRoleBinding{} +var _ machinery.Template = &LeaderElectionRoleBinding{} // LeaderElectionRoleBinding scaffolds a file that defines the role binding that allows leader election type LeaderElectionRoleBinding struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/role_binding.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/role_binding.go index 40f1bd783e1..659dc5a4316 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/role_binding.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/rbac/role_binding.go @@ -19,14 +19,14 @@ package rbac import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &RoleBinding{} +var _ machinery.Template = &RoleBinding{} // RoleBinding scaffolds a file that defines the role binding for the manager type RoleBinding struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/samples/crd_sample.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/samples/crd_sample.go index ab68ba16e4c..f813a2353b7 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/samples/crd_sample.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/samples/crd_sample.go @@ -19,15 +19,15 @@ package samples import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &CRDSample{} +var _ machinery.Template = &CRDSample{} // CRDSample scaffolds a file that defines a sample manifest for the CRD type CRDSample struct { - file.TemplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.ResourceMixin Force bool } @@ -40,9 +40,9 @@ func (f *CRDSample) SetTemplateDefaults() error { f.Path = f.Resource.Replacer().Replace(f.Path) if f.Force { - f.IfExistsAction = file.Overwrite + f.IfExistsAction = machinery.OverwriteFile } else { - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error } f.TemplateBody = crdSampleTemplate diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/webhook/kustomization.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/webhook/kustomization.go index 74546ab10ae..3f55f70a12f 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/webhook/kustomization.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/webhook/kustomization.go @@ -19,15 +19,15 @@ package webhook import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Kustomization{} +var _ machinery.Template = &Kustomization{} // Kustomization scaffolds a file that defines the kustomization scheme for the webhook folder type Kustomization struct { - file.TemplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.ResourceMixin Force bool } @@ -41,10 +41,10 @@ func (f *Kustomization) SetTemplateDefaults() error { f.TemplateBody = kustomizeWebhookTemplate if f.Force { - f.IfExistsAction = file.Overwrite + f.IfExistsAction = machinery.OverwriteFile } else { // If file exists (ex. because a webhook was already created), skip creation. - f.IfExistsAction = file.Skip + f.IfExistsAction = machinery.SkipFile } return nil diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/webhook/kustomizeconfig.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/webhook/kustomizeconfig.go index a719ae63c46..524f11e71c1 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/webhook/kustomizeconfig.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/webhook/kustomizeconfig.go @@ -19,14 +19,14 @@ package webhook import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &KustomizeConfig{} +var _ machinery.Template = &KustomizeConfig{} // KustomizeConfig scaffolds a file that configures the kustomization for the webhook folder type KustomizeConfig struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template @@ -38,7 +38,7 @@ func (f *KustomizeConfig) SetTemplateDefaults() error { f.TemplateBody = kustomizeConfigWebhookTemplate // If file exists (ex. because a webhook was already created), skip creation. - f.IfExistsAction = file.Skip + f.IfExistsAction = machinery.SkipFile return nil } diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/webhook/service.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/webhook/service.go index f05e6bc719a..a7052dbb3bc 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/config/webhook/service.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/config/webhook/service.go @@ -19,14 +19,14 @@ package webhook import ( "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Service{} +var _ machinery.Template = &Service{} // Service scaffolds a file that defines the webhook service type Service struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template @@ -38,7 +38,7 @@ func (f *Service) SetTemplateDefaults() error { f.TemplateBody = serviceTemplate // If file exists (ex. because a webhook was already created), skip creation. - f.IfExistsAction = file.Skip + f.IfExistsAction = machinery.SkipFile return nil } diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/controllers/controller.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/controllers/controller.go index 779edb04b45..32d64bcf006 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/controllers/controller.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/controllers/controller.go @@ -20,18 +20,18 @@ import ( "fmt" "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Controller{} +var _ machinery.Template = &Controller{} // Controller scaffolds the file that defines the controller for a CRD or a builtin resource // nolint:maligned type Controller struct { - file.TemplateMixin - file.MultiGroupMixin - file.BoilerplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.MultiGroupMixin + machinery.BoilerplateMixin + machinery.ResourceMixin ControllerRuntimeVersion string @@ -53,9 +53,9 @@ func (f *Controller) SetTemplateDefaults() error { f.TemplateBody = controllerTemplate if f.Force { - f.IfExistsAction = file.Overwrite + f.IfExistsAction = machinery.OverwriteFile } else { - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error } return nil diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/controllers/controller_suitetest.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/controllers/controller_suitetest.go index d6e6ac95af5..1dbb649a40c 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/controllers/controller_suitetest.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/controllers/controller_suitetest.go @@ -20,19 +20,19 @@ import ( "fmt" "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &SuiteTest{} -var _ file.Inserter = &SuiteTest{} +var _ machinery.Template = &SuiteTest{} +var _ machinery.Inserter = &SuiteTest{} // SuiteTest scaffolds the file that sets up the controller tests // nolint:maligned type SuiteTest struct { - file.TemplateMixin - file.MultiGroupMixin - file.BoilerplateMixin - file.ResourceMixin + machinery.TemplateMixin + machinery.MultiGroupMixin + machinery.BoilerplateMixin + machinery.ResourceMixin // CRDDirectoryRelativePath define the Path for the CRD CRDDirectoryRelativePath string @@ -52,8 +52,8 @@ func (f *SuiteTest) SetTemplateDefaults() error { f.Path = f.Resource.Replacer().Replace(f.Path) f.TemplateBody = fmt.Sprintf(controllerSuiteTestTemplate, - file.NewMarkerFor(f.Path, importMarker), - file.NewMarkerFor(f.Path, addSchemeMarker), + machinery.NewMarkerFor(f.Path, importMarker), + machinery.NewMarkerFor(f.Path, addSchemeMarker), ) // If is multigroup the path needs to be ../../ since it has @@ -64,7 +64,7 @@ func (f *SuiteTest) SetTemplateDefaults() error { } if f.Force { - f.IfExistsAction = file.Overwrite + f.IfExistsAction = machinery.OverwriteFile } return nil @@ -76,10 +76,10 @@ const ( ) // GetMarkers implements file.Inserter -func (f *SuiteTest) GetMarkers() []file.Marker { - return []file.Marker{ - file.NewMarkerFor(f.Path, importMarker), - file.NewMarkerFor(f.Path, addSchemeMarker), +func (f *SuiteTest) GetMarkers() []machinery.Marker { + return []machinery.Marker{ + machinery.NewMarkerFor(f.Path, importMarker), + machinery.NewMarkerFor(f.Path, addSchemeMarker), } } @@ -93,8 +93,8 @@ Expect(err).NotTo(HaveOccurred()) ) // GetCodeFragments implements file.Inserter -func (f *SuiteTest) GetCodeFragments() file.CodeFragmentsMap { - fragments := make(file.CodeFragmentsMap, 2) +func (f *SuiteTest) GetCodeFragments() machinery.CodeFragmentsMap { + fragments := make(machinery.CodeFragmentsMap, 2) // Generate import code fragments imports := make([]string, 0) @@ -110,10 +110,10 @@ func (f *SuiteTest) GetCodeFragments() file.CodeFragmentsMap { // Only store code fragments in the map if the slices are non-empty if len(imports) != 0 { - fragments[file.NewMarkerFor(f.Path, importMarker)] = imports + fragments[machinery.NewMarkerFor(f.Path, importMarker)] = imports } if len(addScheme) != 0 { - fragments[file.NewMarkerFor(f.Path, addSchemeMarker)] = addScheme + fragments[machinery.NewMarkerFor(f.Path, addSchemeMarker)] = addScheme } return fragments diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/dockerfile.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/dockerfile.go index 359a0a2ebc5..7794ab4e08c 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/dockerfile.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/dockerfile.go @@ -17,14 +17,14 @@ limitations under the License. package templates import ( - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Dockerfile{} +var _ machinery.Template = &Dockerfile{} // Dockerfile scaffolds a file that defines the containerized build process type Dockerfile struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/dockerignore.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/dockerignore.go index 7aa0150303d..2051adc956c 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/dockerignore.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/dockerignore.go @@ -17,14 +17,14 @@ limitations under the License. package templates import ( - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &DockerIgnore{} +var _ machinery.Template = &DockerIgnore{} // DockerIgnore scaffolds a file that defines which files should be ignored by the containerized build process type DockerIgnore struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/gitignore.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/gitignore.go index bbf1e92bf53..2b5ef060f98 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/gitignore.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/gitignore.go @@ -17,14 +17,14 @@ limitations under the License. package templates import ( - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &GitIgnore{} +var _ machinery.Template = &GitIgnore{} // GitIgnore scaffolds a file that defines which files should be ignored by git type GitIgnore struct { - file.TemplateMixin + machinery.TemplateMixin } // SetTemplateDefaults implements file.Template diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/gomod.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/gomod.go index fdb3ce26764..e79e17bf47a 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/gomod.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/gomod.go @@ -17,15 +17,15 @@ limitations under the License. package templates import ( - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &GoMod{} +var _ machinery.Template = &GoMod{} // GoMod scaffolds a file that defines the project dependencies type GoMod struct { - file.TemplateMixin - file.RepositoryMixin + machinery.TemplateMixin + machinery.RepositoryMixin ControllerRuntimeVersion string } @@ -38,7 +38,7 @@ func (f *GoMod) SetTemplateDefaults() error { f.TemplateBody = goModTemplate - f.IfExistsAction = file.Overwrite + f.IfExistsAction = machinery.OverwriteFile return nil } diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/hack/boilerplate.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/hack/boilerplate.go index 8603a6cd699..3efbe592a54 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/hack/boilerplate.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/hack/boilerplate.go @@ -21,18 +21,18 @@ import ( "path/filepath" "time" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) // DefaultBoilerplatePath is the default path to the boilerplate file var DefaultBoilerplatePath = filepath.Join("hack", "boilerplate.go.txt") -var _ file.Template = &Boilerplate{} +var _ machinery.Template = &Boilerplate{} // Boilerplate scaffolds a file that defines the common header for the rest of the files type Boilerplate struct { - file.TemplateMixin - file.BoilerplateMixin + machinery.TemplateMixin + machinery.BoilerplateMixin // License is the License type to write License string diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/main.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/main.go index 65863974cb7..df7abb4751f 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/main.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/main.go @@ -20,20 +20,20 @@ import ( "fmt" "path/filepath" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) const defaultMainPath = "main.go" -var _ file.Template = &Main{} +var _ machinery.Template = &Main{} // Main scaffolds a file that defines the controller manager entry point type Main struct { - file.TemplateMixin - file.BoilerplateMixin - file.DomainMixin - file.RepositoryMixin - file.ComponentConfigMixin + machinery.TemplateMixin + machinery.BoilerplateMixin + machinery.DomainMixin + machinery.RepositoryMixin + machinery.ComponentConfigMixin } // SetTemplateDefaults implements file.Template @@ -43,21 +43,21 @@ func (f *Main) SetTemplateDefaults() error { } f.TemplateBody = fmt.Sprintf(mainTemplate, - file.NewMarkerFor(f.Path, importMarker), - file.NewMarkerFor(f.Path, addSchemeMarker), - file.NewMarkerFor(f.Path, setupMarker), + machinery.NewMarkerFor(f.Path, importMarker), + machinery.NewMarkerFor(f.Path, addSchemeMarker), + machinery.NewMarkerFor(f.Path, setupMarker), ) return nil } -var _ file.Inserter = &MainUpdater{} +var _ machinery.Inserter = &MainUpdater{} // MainUpdater updates main.go to run Controllers type MainUpdater struct { //nolint:maligned - file.RepositoryMixin - file.MultiGroupMixin - file.ResourceMixin + machinery.RepositoryMixin + machinery.MultiGroupMixin + machinery.ResourceMixin // Flags to indicate which parts need to be included when updating the file WireResource, WireController, WireWebhook bool @@ -69,8 +69,8 @@ func (*MainUpdater) GetPath() string { } // GetIfExistsAction implements file.Builder -func (*MainUpdater) GetIfExistsAction() file.IfExistsAction { - return file.Overwrite +func (*MainUpdater) GetIfExistsAction() machinery.IfExistsAction { + return machinery.OverwriteFile } const ( @@ -80,11 +80,11 @@ const ( ) // GetMarkers implements file.Inserter -func (f *MainUpdater) GetMarkers() []file.Marker { - return []file.Marker{ - file.NewMarkerFor(defaultMainPath, importMarker), - file.NewMarkerFor(defaultMainPath, addSchemeMarker), - file.NewMarkerFor(defaultMainPath, setupMarker), +func (f *MainUpdater) GetMarkers() []machinery.Marker { + return []machinery.Marker{ + machinery.NewMarkerFor(defaultMainPath, importMarker), + machinery.NewMarkerFor(defaultMainPath, addSchemeMarker), + machinery.NewMarkerFor(defaultMainPath, setupMarker), } } @@ -123,8 +123,8 @@ const ( ) // GetCodeFragments implements file.Inserter -func (f *MainUpdater) GetCodeFragments() file.CodeFragmentsMap { - fragments := make(file.CodeFragmentsMap, 3) +func (f *MainUpdater) GetCodeFragments() machinery.CodeFragmentsMap { + fragments := make(machinery.CodeFragmentsMap, 3) // If resource is not being provided we are creating the file, not updating it if f.Resource == nil { @@ -170,13 +170,13 @@ func (f *MainUpdater) GetCodeFragments() file.CodeFragmentsMap { // Only store code fragments in the map if the slices are non-empty if len(imports) != 0 { - fragments[file.NewMarkerFor(defaultMainPath, importMarker)] = imports + fragments[machinery.NewMarkerFor(defaultMainPath, importMarker)] = imports } if len(addScheme) != 0 { - fragments[file.NewMarkerFor(defaultMainPath, addSchemeMarker)] = addScheme + fragments[machinery.NewMarkerFor(defaultMainPath, addSchemeMarker)] = addScheme } if len(setup) != 0 { - fragments[file.NewMarkerFor(defaultMainPath, setupMarker)] = setup + fragments[machinery.NewMarkerFor(defaultMainPath, setupMarker)] = setup } return fragments diff --git a/pkg/plugins/golang/v3/scaffolds/internal/templates/makefile.go b/pkg/plugins/golang/v3/scaffolds/internal/templates/makefile.go index 09b983942fa..787c1ef34f2 100644 --- a/pkg/plugins/golang/v3/scaffolds/internal/templates/makefile.go +++ b/pkg/plugins/golang/v3/scaffolds/internal/templates/makefile.go @@ -17,15 +17,15 @@ limitations under the License. package templates import ( - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" ) -var _ file.Template = &Makefile{} +var _ machinery.Template = &Makefile{} // Makefile scaffolds a file that defines project management CLI commands type Makefile struct { - file.TemplateMixin - file.ComponentConfigMixin + machinery.TemplateMixin + machinery.ComponentConfigMixin // Image is controller manager image name Image string @@ -47,7 +47,7 @@ func (f *Makefile) SetTemplateDefaults() error { f.TemplateBody = makefileTemplate - f.IfExistsAction = file.Error + f.IfExistsAction = machinery.Error if f.Image == "" { f.Image = "controller:latest" diff --git a/pkg/plugins/golang/v3/scaffolds/webhook.go b/pkg/plugins/golang/v3/scaffolds/webhook.go index 0e2545faa5b..3403411628b 100644 --- a/pkg/plugins/golang/v3/scaffolds/webhook.go +++ b/pkg/plugins/golang/v3/scaffolds/webhook.go @@ -22,23 +22,21 @@ import ( "github.com/spf13/afero" "sigs.k8s.io/kubebuilder/v3/pkg/config" - "sigs.k8s.io/kubebuilder/v3/pkg/model" + "sigs.k8s.io/kubebuilder/v3/pkg/machinery" "sigs.k8s.io/kubebuilder/v3/pkg/model/resource" + "sigs.k8s.io/kubebuilder/v3/pkg/plugins" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates/api" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates/config/webhook" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds/internal/templates/hack" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/cmdutil" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/machinery" ) -var _ cmdutil.Scaffolder = &webhookScaffolder{} +var _ plugins.Scaffolder = &webhookScaffolder{} type webhookScaffolder struct { - config config.Config - boilerplate string - resource resource.Resource + config config.Config + resource resource.Resource // fs is the filesystem that will be used by the scaffolder fs afero.Fs @@ -48,7 +46,7 @@ type webhookScaffolder struct { } // NewWebhookScaffolder returns a new Scaffolder for v2 webhook creation operations -func NewWebhookScaffolder(config config.Config, resource resource.Resource, force bool) cmdutil.Scaffolder { +func NewWebhookScaffolder(config config.Config, resource resource.Resource, force bool) plugins.Scaffolder { return &webhookScaffolder{ config: config, resource: resource, @@ -61,24 +59,22 @@ func (s *webhookScaffolder) InjectFS(fs afero.Fs) { s.fs = fs } -func (s *webhookScaffolder) newUniverse() *model.Universe { - return model.NewUniverse( - model.WithConfig(s.config), - model.WithBoilerplate(s.boilerplate), - model.WithResource(&s.resource), - ) -} - // Scaffold implements cmdutil.Scaffolder func (s *webhookScaffolder) Scaffold() error { fmt.Println("Writing scaffold for you to edit...") // Load the boilerplate - bp, err := afero.ReadFile(s.fs, hack.DefaultBoilerplatePath) + boilerplate, err := afero.ReadFile(s.fs, hack.DefaultBoilerplatePath) if err != nil { return fmt.Errorf("error scaffolding webhook: unable to load boilerplate: %w", err) } - s.boilerplate = string(bp) + + // Initialize the machinery.Scaffold that will write the files to disk + scaffold := machinery.NewScaffold(s.fs, + machinery.WithConfig(s.config), + machinery.WithBoilerplate(string(boilerplate)), + machinery.WithResource(&s.resource), + ) // Keep track of these values before the update doDefaulting := s.resource.HasDefaultingWebhook() @@ -89,8 +85,7 @@ func (s *webhookScaffolder) Scaffold() error { return fmt.Errorf("error updating resource: %w", err) } - if err := machinery.NewScaffold(s.fs).Execute( - s.newUniverse(), + if err := scaffold.Execute( &api.Webhook{Force: s.force}, &templates.MainUpdater{WireWebhook: true}, &kdefault.WebhookCAInjectionPatch{}, @@ -109,8 +104,7 @@ You need to implement the conversion.Hub and conversion.Convertible interfaces f // TODO: Add test suite for conversion webhook after #1664 has been merged & conversion tests supported in envtest. if doDefaulting || doValidation { - if err := machinery.NewScaffold(s.fs).Execute( - s.newUniverse(), + if err := scaffold.Execute( &api.WebhookSuite{}, ); err != nil { return err diff --git a/pkg/plugins/internal/machinery/errors.go b/pkg/plugins/internal/machinery/errors.go deleted file mode 100644 index faba57a1d05..00000000000 --- a/pkg/plugins/internal/machinery/errors.go +++ /dev/null @@ -1,74 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package machinery - -import ( - "errors" - "fmt" - - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" -) - -// This file contains the errors returned by the scaffolding machinery -// They are not exported as they should not be created outside of this package -// Exported functions are provided to check which kind of error was returned - -// fileAlreadyExistsError is returned if the file is expected not to exist but it does -type fileAlreadyExistsError struct { - path string -} - -// Error implements error interface -func (e fileAlreadyExistsError) Error() string { - return fmt.Sprintf("failed to create %s: file already exists", e.path) -} - -// IsFileAlreadyExistsError checks if the returned error is because the file already existed when expected not to -func IsFileAlreadyExistsError(err error) bool { - return errors.As(err, &fileAlreadyExistsError{}) -} - -// modelAlreadyExistsError is returned if the file is expected not to exist but a previous model does -type modelAlreadyExistsError struct { - path string -} - -// Error implements error interface -func (e modelAlreadyExistsError) Error() string { - return fmt.Sprintf("failed to create %s: model already exists", e.path) -} - -// IsModelAlreadyExistsError checks if the returned error is because the model already existed when expected not to -func IsModelAlreadyExistsError(err error) bool { - return errors.As(err, &modelAlreadyExistsError{}) -} - -// unknownIfExistsActionError is returned if the if-exists-action is unknown -type unknownIfExistsActionError struct { - path string - ifExistsAction file.IfExistsAction -} - -// Error implements error interface -func (e unknownIfExistsActionError) Error() string { - return fmt.Sprintf("unknown behavior if file exists (%d) for %s", e.ifExistsAction, e.path) -} - -// IsUnknownIfExistsActionError checks if the returned error is because the if-exists-action is unknown -func IsUnknownIfExistsActionError(err error) bool { - return errors.As(err, &unknownIfExistsActionError{}) -} diff --git a/pkg/plugins/internal/machinery/errors_test.go b/pkg/plugins/internal/machinery/errors_test.go deleted file mode 100644 index 3d6b8ce14e4..00000000000 --- a/pkg/plugins/internal/machinery/errors_test.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package machinery - -import ( - "errors" - "path/filepath" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/ginkgo/extensions/table" - . "github.com/onsi/gomega" -) - -var _ = Describe("Errors", func() { - var ( - path = filepath.Join("path", "to", "file") - err = errors.New("test error") - fileAlreadyExistsErr = fileAlreadyExistsError{path} - modelAlreadyExistsErr = modelAlreadyExistsError{path} - unknownIfExistsActionErr = unknownIfExistsActionError{path, -1} - ) - - DescribeTable("IsXxxxError should return true for themselves and false for the rest", - func(f func(error) bool, itself error, rest ...error) { - Expect(f(itself)).To(BeTrue()) - for _, err := range rest { - Expect(f(err)).To(BeFalse()) - } - }, - Entry("file exists", IsFileAlreadyExistsError, fileAlreadyExistsErr, - err, modelAlreadyExistsErr, unknownIfExistsActionErr), - Entry("model exists", IsModelAlreadyExistsError, modelAlreadyExistsErr, - err, fileAlreadyExistsErr, unknownIfExistsActionErr), - Entry("unknown if exists action", IsUnknownIfExistsActionError, unknownIfExistsActionErr, - err, fileAlreadyExistsErr, modelAlreadyExistsErr), - ) - - DescribeTable("should contain the wrapped error and error message", - func(err error) { - Expect(err).To(MatchError(err)) - Expect(err.Error()).To(ContainSubstring(err.Error())) - }, - ) - - // NOTE: the following test increases coverage - It("should print a descriptive error message", func() { - Expect(fileAlreadyExistsErr.Error()).To(ContainSubstring("file already exists")) - Expect(modelAlreadyExistsErr.Error()).To(ContainSubstring("model already exists")) - Expect(unknownIfExistsActionErr.Error()).To(ContainSubstring("unknown behavior if file exists")) - }) -}) diff --git a/pkg/plugins/internal/cmdutil/cmdutil.go b/pkg/plugins/scaffolder.go similarity index 98% rename from pkg/plugins/internal/cmdutil/cmdutil.go rename to pkg/plugins/scaffolder.go index e7538e6e79f..f487d0caa5a 100644 --- a/pkg/plugins/internal/cmdutil/cmdutil.go +++ b/pkg/plugins/scaffolder.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cmdutil +package plugins import ( "github.com/spf13/afero" diff --git a/plugins/README.md b/plugins/README.md deleted file mode 100644 index 4cab5423bc2..00000000000 --- a/plugins/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Kubebuilder plugins - -**Status: Experimental** - -We are developing a plugin system to kubebuilder, so that we can generate -operators that follow other patterns. - -While plugins remain experimental, you must pass the `KUBEBUILDER_ENABLE_PLUGINS=1` -environment variable to enable plugin functionality. (Any non-empty -value will work!) - -When you specify `KUBEBUILDER_ENABLE_PLUGINS=1`, a flag `--pattern` will become -available for resource generation. Specifying `--pattern=addon` will change -resource code generation to generate code that follows the addon pattern, as -being developed in the -[cluster-addons](https://github.com/kubernetes-sigs/cluster-addons) -subproject. - -The `pattern=addon` plugin is intended to serve both as an example of a plugin, -and as a real-world use case for driving development of the plugin system. We -don't intend for the plugin system to become an emacs competitor, but it must be -sufficiently flexible to support the various patterns of operators that -kubebuilder will generate. - -## Plugin model - -We intend for plugins to be packaged in a separate binary, which will be -executed by the `kubebuilder` main binary. Data will be piped to the binary via -stdin, and returned over stdout. The serialization format will likely either be -yaml or json (to be determined!). - -While we are developing this functionality though, we are developing it using an -in-process golang interface named `Plugin`, defined in -[pkg/plugin/scaffold/scaffold.go](../pkg/plugin/scaffold/scaffold.go). The interface is a -simple single-method interface that is intended to mirror the data-in / data-out -approach that will be used when executing a plugin in a separate binary. When -we have more stability of the plugin, we intend to replace the in-process -implementation with a implementation that `exec`s a plugin in a separate binary. - -The approach being prototyped is that we pass a model of the full state of the -generation world to the Plugin, which returns the full state of the generation -world after making appropriate changes. We are starting to define a `model` -package which includes a `Universe` comprising the various `File`s that are -being generated, along with the inputs like the `Boilerplate` and the `Resource` -we are currently generating. A plugin can change the `Contents` of `File`s, or -add/remove `File`s entirely. diff --git a/plugins/addon/channel.go b/plugins/addon/channel.go deleted file mode 100644 index f4804e5d528..00000000000 --- a/plugins/addon/channel.go +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package addon - -import ( - "path/filepath" - - "sigs.k8s.io/kubebuilder/v3/pkg/model" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" -) - -const exampleChannel = `# Versions for the stable channel -manifests: -- version: 0.0.1 -` - -// ExampleChannel adds a model file for the channel -func ExampleChannel(u *model.Universe) error { - m := &file.File{ - Path: filepath.Join("channels", "stable"), - Contents: exampleChannel, - IfExistsAction: file.Skip, - } - - _, err := AddFile(u, m) - return err -} diff --git a/plugins/addon/controller.go b/plugins/addon/controller.go deleted file mode 100644 index d84615feafb..00000000000 --- a/plugins/addon/controller.go +++ /dev/null @@ -1,108 +0,0 @@ -package addon - -import ( - "path/filepath" - "strings" - - "sigs.k8s.io/kubebuilder/v3/pkg/model" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" -) - -// ReplaceController replaces the controller with a modified version -func ReplaceController(u *model.Universe) error { - templateBody := controllerTemplate - - funcs := DefaultTemplateFunctions() - contents, err := RunTemplate("controller", templateBody, u, funcs) - if err != nil { - return err - } - - m := &file.File{ - Path: filepath.Join("controllers", strings.ToLower(u.Resource.Kind)+"_controller.go"), - Contents: contents, - IfExistsAction: file.Error, - } - - ReplaceFileIfExists(u, m) - - return nil -} - -//nolint:lll -const controllerTemplate = `{{ .Boilerplate }} - -package controllers - -import ( - "github.com/go-logr/logr" - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - "sigs.k8s.io/controller-runtime/pkg/source" - "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon" - "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/status" - "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/declarative" - - {{ .Resource.ImportAlias }} "{{ .Resource.Path }}" -) - -var _ reconcile.Reconciler = &{{ .Resource.Kind }}Reconciler{} - -// {{ .Resource.Kind }}Reconciler reconciles a {{ .Resource.Kind }} object -type {{ .Resource.Kind }}Reconciler struct { - client.Client - Log logr.Logger - Scheme *runtime.Scheme - - declarative.Reconciler -} - -//+kubebuilder:rbac:groups={{ .Resource.QualifiedGroup }},resources={{ .Resource.Plural }},verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups={{ .Resource.QualifiedGroup }},resources={{ .Resource.Plural }}/status,verbs=get;update;patch - -// SetupWithManager sets up the controller with the Manager. -func (r *{{ .Resource.Kind }}Reconciler) SetupWithManager(mgr ctrl.Manager) error { - addon.Init() - - labels := map[string]string{ - "k8s-app": "{{ lower .Resource.Kind }}", - } - - watchLabels := declarative.SourceLabel(mgr.GetScheme()) - - if err := r.Reconciler.Init(mgr, &{{ .Resource.ImportAlias }}.{{ .Resource.Kind }}{}, - declarative.WithObjectTransform(declarative.AddLabels(labels)), - declarative.WithOwner(declarative.SourceAsOwner), - declarative.WithLabels(watchLabels), - declarative.WithStatus(status.NewBasic(mgr.GetClient())), - // TODO: add an application to your manifest: declarative.WithObjectTransform(addon.TransformApplicationFromStatus), - // TODO: add an application to your manifest: declarative.WithManagedApplication(watchLabels), - declarative.WithObjectTransform(addon.ApplyPatches), - ); err != nil { - return err - } - - c, err := controller.New("{{ lower .Resource.Kind }}-controller", mgr, controller.Options{Reconciler: r}) - if err != nil { - return err - } - - // Watch for changes to {{ .Resource.Kind }} - err = c.Watch(&source.Kind{Type: &{{ .Resource.ImportAlias }}.{{ .Resource.Kind }}{}}, &handler.EnqueueRequestForObject{}) - if err != nil { - return err - } - - // Watch for changes to deployed objects - _, err = declarative.WatchAll(mgr.GetConfig(), c, r, watchLabels) - if err != nil { - return err - } - - return nil -} -` diff --git a/plugins/addon/helpers.go b/plugins/addon/helpers.go deleted file mode 100644 index 48f91e89d8d..00000000000 --- a/plugins/addon/helpers.go +++ /dev/null @@ -1,88 +0,0 @@ -package addon - -import ( - "bytes" - "fmt" - "strings" - "text/template" - - "github.com/gobuffalo/flect" - - "sigs.k8s.io/kubebuilder/v3/pkg/model" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" -) - -// This file gathers functions that are likely to be useful to other -// plugins. Once we have validated they are used in more than one -// place, we can promote them to a shared location. - -// PluginFunc executes a step of Plugin -type PluginFunc func(u *model.Universe) error - -// AddFile adds the specified file to the model. -// If the file exists the function returns false and does not modify the Universe -// If the file does not exist, the function returns true and adds the file to the Universe -// If there is a problem with the file the function returns an error -func AddFile(u *model.Universe, add *file.File) (bool, error) { - p := add.Path - if p == "" { - return false, fmt.Errorf("path must be set") - } - - if _, found := u.Files[p]; found { - return false, nil - } - - u.Files[p] = add - return true, nil -} - -// ReplaceFileIfExists replaces the specified file in the model by path -// Returns true if the file was replaced. -func ReplaceFileIfExists(u *model.Universe, add *file.File) bool { - p := add.Path - if p == "" { - panic("path must be set") - } - - if _, found := u.Files[p]; found { - u.Files[p] = add - return true - } - - return false -} - -// ReplaceFile replaces the specified file in the model by path -// If the file does not exist, it returns an error -func ReplaceFile(u *model.Universe, add *file.File) error { - found := ReplaceFileIfExists(u, add) - if !found { - return fmt.Errorf("file not found %q", add.Path) - } - return nil -} - -// DefaultTemplateFunctions returns a map of template helpers -func DefaultTemplateFunctions() template.FuncMap { - return template.FuncMap{ - "title": strings.Title, - "lower": strings.ToLower, - "plural": flect.Pluralize, - } -} - -// RunTemplate parses a template -func RunTemplate(templateName, templateValue string, data interface{}, funcMap template.FuncMap) (string, error) { - t, err := template.New(templateName).Funcs(funcMap).Parse(templateValue) - if err != nil { - return "", fmt.Errorf("error building template %s: %v", templateName, err) - } - - var b bytes.Buffer - if err := t.Execute(&b, data); err != nil { - return "", fmt.Errorf("error rending template %s: %v", templateName, err) - } - - return b.String(), nil -} diff --git a/plugins/addon/manifest.go b/plugins/addon/manifest.go deleted file mode 100644 index 227f1300ef1..00000000000 --- a/plugins/addon/manifest.go +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package addon - -import ( - "path/filepath" - "strings" - - "sigs.k8s.io/kubebuilder/v3/pkg/model" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" -) - -const exampleManifestVersion = "0.0.1" - -const exampleManifestContents = `# Placeholder manifest - replace with the manifest for your addon -` - -// ExampleManifest adds a model file for the manifest placeholder -func ExampleManifest(u *model.Universe) error { - packageName := getPackageName(u) - - m := &file.File{ - Path: filepath.Join("channels", "packages", packageName, exampleManifestVersion, "manifest.yaml"), - Contents: exampleManifestContents, - IfExistsAction: file.Skip, - } - - _, err := AddFile(u, m) - - return err -} - -// getPackageName returns the (default) name of the declarative package -func getPackageName(u *model.Universe) string { - return strings.ToLower(u.Resource.Kind) -} diff --git a/plugins/addon/plugin.go b/plugins/addon/plugin.go deleted file mode 100644 index 3da0363b929..00000000000 --- a/plugins/addon/plugin.go +++ /dev/null @@ -1,28 +0,0 @@ -package addon - -import ( - "sigs.k8s.io/kubebuilder/v3/pkg/model" -) - -// Plugin implements model.Plugin -type Plugin struct { -} - -// Pipe implements model.Plugin -func (p *Plugin) Pipe(u *model.Universe) error { - functions := []PluginFunc{ - ExampleManifest, - ExampleChannel, - ReplaceController, - ReplaceTypes, - } - - for _, fn := range functions { - if err := fn(u); err != nil { - return err - } - - } - - return nil -} diff --git a/plugins/addon/type.go b/plugins/addon/type.go deleted file mode 100644 index ebcbeab56b7..00000000000 --- a/plugins/addon/type.go +++ /dev/null @@ -1,126 +0,0 @@ -package addon - -import ( - "fmt" - "path/filepath" - "strings" - - "sigs.k8s.io/kubebuilder/v3/pkg/model" - "sigs.k8s.io/kubebuilder/v3/pkg/model/file" -) - -// ReplaceTypes replaces the API types with a modified version -func ReplaceTypes(u *model.Universe) error { - funcs := DefaultTemplateFunctions() - funcs["JSONTag"] = JSONTag - - contents, err := RunTemplate("types", typesTemplate, u, funcs) - if err != nil { - return err - } - - var path string - if u.Config.IsMultiGroup() { - path = filepath.Join("apis", u.Resource.Version, strings.ToLower(u.Resource.Kind)+"_types.go") - } else { - path = filepath.Join("api", u.Resource.Version, strings.ToLower(u.Resource.Kind)+"_types.go") - } - - m := &file.File{ - Path: path, - Contents: contents, - IfExistsAction: file.Error, - } - - ReplaceFileIfExists(u, m) - - return nil -} - -// JSONTag is a helper to build the json tag for a struct -// It works around escaping problems for the json tag syntax -func JSONTag(tag string) string { - return fmt.Sprintf("`json:\"%s\"`", tag) -} - -// Resource.Resource - -const typesTemplate = `{{ .Boilerplate }} - -package {{ .Resource.Version }} - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - addonv1alpha1 "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/apis/v1alpha1" -) - -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. - -// {{ .Resource.Kind }}Spec defines the desired state of {{ .Resource.Kind }} -type {{ .Resource.Kind }}Spec struct { - addonv1alpha1.CommonSpec {{ JSONTag ",inline" }} - addonv1alpha1.PatchSpec {{ JSONTag ",inline" }} - - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file -} - -// {{ .Resource.Kind }}Status defines the observed state of {{ .Resource.Kind }} -type {{ .Resource.Kind }}Status struct { - addonv1alpha1.CommonStatus {{ JSONTag ",inline" }} - - // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster - // Important: Run "make" to regenerate code after modifying this file -} - -//+kubebuilder:object:root=true -//+kubebuilder:subresource:status -{{- if not .Resource.API.Namespaced }} -//+kubebuilder:resource:scope=Cluster -{{- end }} - -// {{ .Resource.Kind }} is the Schema for the {{ .Resource.Plural }} API -type {{ .Resource.Kind }} struct { - metav1.TypeMeta ` + "`" + `json:",inline"` + "`" + ` - metav1.ObjectMeta ` + "`" + `json:"metadata,omitempty"` + "`" + ` - - Spec {{ .Resource.Kind }}Spec ` + "`" + `json:"spec,omitempty"` + "`" + ` - Status {{ .Resource.Kind }}Status ` + "`" + `json:"status,omitempty"` + "`" + ` -} - -var _ addonv1alpha1.CommonObject = &{{ .Resource.Kind }}{} - -func (o *{{ .Resource.Kind }}) ComponentName() string { - return "{{ lower .Resource.Kind }}" -} - -func (o *{{ .Resource.Kind }}) CommonSpec() addonv1alpha1.CommonSpec { - return o.Spec.CommonSpec -} - -func (o *{{ .Resource.Kind }}) PatchSpec() addonv1alpha1.PatchSpec { - return o.Spec.PatchSpec -} - -func (o *{{ .Resource.Kind }}) GetCommonStatus() addonv1alpha1.CommonStatus { - return o.Status.CommonStatus -} - -func (o *{{ .Resource.Kind }}) SetCommonStatus(s addonv1alpha1.CommonStatus) { - o.Status.CommonStatus = s -} - -//+kubebuilder:object:root=true - -// {{ .Resource.Kind }}List contains a list of {{ .Resource.Kind }} -type {{ .Resource.Kind }}List struct { - metav1.TypeMeta ` + "`" + `json:",inline"` + "`" + ` - metav1.ListMeta ` + "`" + `json:"metadata,omitempty"` + "`" + ` - Items []{{ .Resource.Kind }} ` + "`" + `json:"items"` + "`" + ` -} - -func init() { - SchemeBuilder.Register(&{{ .Resource.Kind }}{}, &{{ .Resource.Kind }}List{}) -} -`