Skip to content

Commit 7109cc2

Browse files
committed
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 <[email protected]>
1 parent 278efb7 commit 7109cc2

File tree

142 files changed

+2169
-3552
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

142 files changed

+2169
-3552
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ test-unit: ## Run the unit tests
9797
.PHONY: test-coverage
9898
test-coverage: ## Run unit tests creating the output to report coverage
9999
- rm -rf *.out # Remove all coverage files if exists
100-
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/...
100+
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/...
101101

102102
.PHONY: test-integration
103103
test-integration: ## Run the integration tests

pkg/machinery/errors.go

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package machinery
18+
19+
import (
20+
"fmt"
21+
)
22+
23+
// This file contains the errors returned by the scaffolding machinery
24+
// They are exported to be able to check which kind of error was returned
25+
26+
// ValidateError is a wrapper error that will be used for errors returned by RequiresValidation.Validate
27+
type ValidateError struct {
28+
error
29+
}
30+
31+
// Unwrap implements Wrapper interface
32+
func (e ValidateError) Unwrap() error {
33+
return e.error
34+
}
35+
36+
// SetTemplateDefaultsError is a wrapper error that will be used for errors returned by Template.SetTemplateDefaults
37+
type SetTemplateDefaultsError struct {
38+
error
39+
}
40+
41+
// Unwrap implements Wrapper interface
42+
func (e SetTemplateDefaultsError) Unwrap() error {
43+
return e.error
44+
}
45+
46+
// ExistsFileError is a wrapper error that will be used for errors when checking for a file existence
47+
type ExistsFileError struct {
48+
error
49+
}
50+
51+
// Unwrap implements Wrapper interface
52+
func (e ExistsFileError) Unwrap() error {
53+
return e.error
54+
}
55+
56+
// OpenFileError is a wrapper error that will be used for errors when opening a file
57+
type OpenFileError struct {
58+
error
59+
}
60+
61+
// Unwrap implements Wrapper interface
62+
func (e OpenFileError) Unwrap() error {
63+
return e.error
64+
}
65+
66+
// CreateDirectoryError is a wrapper error that will be used for errors when creating a directory
67+
type CreateDirectoryError struct {
68+
error
69+
}
70+
71+
// Unwrap implements Wrapper interface
72+
func (e CreateDirectoryError) Unwrap() error {
73+
return e.error
74+
}
75+
76+
// CreateFileError is a wrapper error that will be used for errors when creating a file
77+
type CreateFileError struct {
78+
error
79+
}
80+
81+
// Unwrap implements Wrapper interface
82+
func (e CreateFileError) Unwrap() error {
83+
return e.error
84+
}
85+
86+
// ReadFileError is a wrapper error that will be used for errors when reading a file
87+
type ReadFileError struct {
88+
error
89+
}
90+
91+
// Unwrap implements Wrapper interface
92+
func (e ReadFileError) Unwrap() error {
93+
return e.error
94+
}
95+
96+
// WriteFileError is a wrapper error that will be used for errors when writing a file
97+
type WriteFileError struct {
98+
error
99+
}
100+
101+
// Unwrap implements Wrapper interface
102+
func (e WriteFileError) Unwrap() error {
103+
return e.error
104+
}
105+
106+
// CloseFileError is a wrapper error that will be used for errors when closing a file
107+
type CloseFileError struct {
108+
error
109+
}
110+
111+
// Unwrap implements Wrapper interface
112+
func (e CloseFileError) Unwrap() error {
113+
return e.error
114+
}
115+
116+
// ModelAlreadyExistsError is returned if the file is expected not to exist but a previous model does
117+
type ModelAlreadyExistsError struct {
118+
path string
119+
}
120+
121+
// Error implements error interface
122+
func (e ModelAlreadyExistsError) Error() string {
123+
return fmt.Sprintf("failed to create %s: model already exists", e.path)
124+
}
125+
126+
// UnknownIfExistsActionError is returned if the if-exists-action is unknown
127+
type UnknownIfExistsActionError struct {
128+
path string
129+
ifExistsAction IfExistsAction
130+
}
131+
132+
// Error implements error interface
133+
func (e UnknownIfExistsActionError) Error() string {
134+
return fmt.Sprintf("unknown behavior if file exists (%d) for %s", e.ifExistsAction, e.path)
135+
}
136+
137+
// FileAlreadyExistsError is returned if the file is expected not to exist but it does
138+
type FileAlreadyExistsError struct {
139+
path string
140+
}
141+
142+
// Error implements error interface
143+
func (e FileAlreadyExistsError) Error() string {
144+
return fmt.Sprintf("failed to create %s: file already exists", e.path)
145+
}

pkg/machinery/errors_test.go

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package machinery
18+
19+
import (
20+
"errors"
21+
"path/filepath"
22+
23+
. "github.com/onsi/ginkgo"
24+
. "github.com/onsi/ginkgo/extensions/table"
25+
. "github.com/onsi/gomega"
26+
)
27+
28+
var _ = Describe("Errors", func() {
29+
var (
30+
path = filepath.Join("path", "to", "file")
31+
testErr = errors.New("test error")
32+
)
33+
34+
DescribeTable("should contain the wrapped error",
35+
func(err error) {
36+
Expect(errors.Is(err, testErr)).To(BeTrue())
37+
},
38+
Entry("for validate errors", ValidateError{testErr}),
39+
Entry("for set template defaults errors", SetTemplateDefaultsError{testErr}),
40+
Entry("for file existence errors", ExistsFileError{testErr}),
41+
Entry("for file opening errors", OpenFileError{testErr}),
42+
Entry("for directory creation errors", CreateDirectoryError{testErr}),
43+
Entry("for file creation errors", CreateFileError{testErr}),
44+
Entry("for file reading errors", ReadFileError{testErr}),
45+
Entry("for file writing errors", WriteFileError{testErr}),
46+
Entry("for file closing errors", CloseFileError{testErr}),
47+
)
48+
49+
// NOTE: the following test increases coverage
50+
It("should print a descriptive error message", func() {
51+
Expect(ModelAlreadyExistsError{path}.Error()).To(ContainSubstring("model already exists"))
52+
Expect(UnknownIfExistsActionError{path, -1}.Error()).To(ContainSubstring("unknown behavior if file exists"))
53+
Expect(FileAlreadyExistsError{path}.Error()).To(ContainSubstring("file already exists"))
54+
})
55+
})

pkg/model/file/file.go renamed to pkg/machinery/file.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,30 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
package file
17+
package machinery
1818

1919
// IfExistsAction determines what to do if the scaffold file already exists
2020
type IfExistsAction int
2121

2222
const (
23-
// Skip skips the file and moves to the next one
24-
Skip IfExistsAction = iota
23+
// SkipFile skips the file and moves to the next one
24+
SkipFile IfExistsAction = iota
2525

2626
// Error returns an error and stops processing
2727
Error
2828

29-
// Overwrite truncates and overwrites the existing file
30-
Overwrite
29+
// OverwriteFile truncates and overwrites the existing file
30+
OverwriteFile
3131
)
3232

3333
// File describes a file that will be written
3434
type File struct {
3535
// Path is the file to write
36-
Path string `json:"path,omitempty"`
36+
Path string
3737

3838
// Contents is the generated output
39-
Contents string `json:"contents,omitempty"`
39+
Contents string
4040

4141
// IfExistsAction determines what to do if the file exists
42-
IfExistsAction IfExistsAction `json:"ifExistsAction,omitempty"`
42+
IfExistsAction IfExistsAction
4343
}

pkg/model/file/funcmap.go renamed to pkg/machinery/funcmap.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
package file
17+
package machinery
1818

1919
import (
2020
"fmt"
@@ -39,10 +39,9 @@ func isEmptyString(s string) bool {
3939
}
4040

4141
// hashFNV will generate a random string useful for generating a unique string
42-
func hashFNV(s string) (string, error) {
42+
func hashFNV(s string) string {
4343
hasher := fnv.New32a()
44-
if _, err := hasher.Write([]byte(s)); err != nil {
45-
return "", err
46-
}
47-
return fmt.Sprintf("%x", hasher.Sum(nil)), nil
44+
// Hash.Write never returns an error
45+
_, _ = hasher.Write([]byte(s))
46+
return fmt.Sprintf("%x", hasher.Sum(nil))
4847
}

pkg/plugins/internal/filesystem/filesystem_suite_test.go renamed to pkg/machinery/funcmap_test.go

+23-7
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,32 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
package filesystem
17+
package machinery
1818

1919
import (
20-
"testing"
21-
2220
. "github.com/onsi/ginkgo"
21+
. "github.com/onsi/ginkgo/extensions/table"
2322
. "github.com/onsi/gomega"
2423
)
2524

26-
func TestFilesystem(t *testing.T) {
27-
RegisterFailHandler(Fail)
28-
RunSpecs(t, "Filesystem suite")
29-
}
25+
var _ = Describe("funcmap functions", func() {
26+
Context("isEmptyString", func() {
27+
It("should return true for empty strings", func() {
28+
Expect(isEmptyString("")).To(BeTrue())
29+
})
30+
31+
DescribeTable("should return false for any other string",
32+
func(str string) { Expect(isEmptyString(str)).To(BeFalse()) },
33+
Entry(`for "a"`, "a"),
34+
Entry(`for "1"`, "1"),
35+
Entry(`for "-"`, "-"),
36+
Entry(`for "."`, "."),
37+
)
38+
})
39+
40+
Context("hashFNV", func() {
41+
It("should hash the input", func() {
42+
Expect(hashFNV("test")).To(Equal("afd071e5"))
43+
})
44+
})
45+
})

pkg/machinery/injector.go

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
Copyright 2021 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package machinery
18+
19+
import (
20+
"sigs.k8s.io/kubebuilder/v3/pkg/config"
21+
"sigs.k8s.io/kubebuilder/v3/pkg/model/resource"
22+
)
23+
24+
// injector is used to inject certain fields to file templates.
25+
type injector struct {
26+
// config stores the project configuration.
27+
config config.Config
28+
29+
// boilerplate is the copyright comment added at the top of scaffolded files.
30+
boilerplate string
31+
32+
// resource contains the information of the API that is being scaffolded.
33+
resource *resource.Resource
34+
}
35+
36+
// injectInto injects fields from the universe into the builder
37+
func (i injector) injectInto(builder Builder) {
38+
// Inject project configuration
39+
if i.config != nil {
40+
if builderWithDomain, hasDomain := builder.(HasDomain); hasDomain {
41+
builderWithDomain.InjectDomain(i.config.GetDomain())
42+
}
43+
if builderWithRepository, hasRepository := builder.(HasRepository); hasRepository {
44+
builderWithRepository.InjectRepository(i.config.GetRepository())
45+
}
46+
if builderWithProjectName, hasProjectName := builder.(HasProjectName); hasProjectName {
47+
builderWithProjectName.InjectProjectName(i.config.GetProjectName())
48+
}
49+
if builderWithMultiGroup, hasMultiGroup := builder.(HasMultiGroup); hasMultiGroup {
50+
builderWithMultiGroup.InjectMultiGroup(i.config.IsMultiGroup())
51+
}
52+
if builderWithComponentConfig, hasComponentConfig := builder.(HasComponentConfig); hasComponentConfig {
53+
builderWithComponentConfig.InjectComponentConfig(i.config.IsComponentConfig())
54+
}
55+
}
56+
// Inject boilerplate
57+
if builderWithBoilerplate, hasBoilerplate := builder.(HasBoilerplate); hasBoilerplate {
58+
builderWithBoilerplate.InjectBoilerplate(i.boilerplate)
59+
}
60+
// Inject resource
61+
if i.resource != nil {
62+
if builderWithResource, hasResource := builder.(HasResource); hasResource {
63+
builderWithResource.InjectResource(i.resource)
64+
}
65+
}
66+
}

0 commit comments

Comments
 (0)