Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨use bundle options struct for creating new bundles #3379

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,21 @@ import (
grafanav1alpha1 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/optional/grafana/v1alpha"
)

// nolint:lll
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any specific reason for adding this?

func main() {

const deprecateMessageGoV3Bundle = "This version is deprecated." +
"The `go/v3` cannot scaffold projects using kustomize versions v4x+" +
" and cannot fully support Kubernetes 1.25+." +
"It is recommended to upgrade your project to the latest versions available (go/v4)." +
"Please, check the migration guide to learn how to upgrade your project"

// Bundle plugin which built the golang projects scaffold by Kubebuilder go/v3
gov3Bundle, _ := plugin.NewBundleWithOptions(plugin.WithName(golang.DefaultNameQualifier),
plugin.WithVersion(plugin.Version{Number: 3}),
plugin.WithDeprecationMessage(deprecateMessageGoV3Bundle),
plugin.WithPlugins(kustomizecommonv1.Plugin{}, golangv3.Plugin{}),
)
gov3 := plugin.NewBundlePluginBuilder()
gov3Bundle, _ := gov3.WithName(golang.DefaultNameQualifier).WithVersion(plugin.Version{Number: 3}).WithDeprecationMessage(deprecateMessageGoV3Bundle).WithPlugins(kustomizecommonv1.Plugin{}, golangv3.Plugin{}).Build()

// Bundle plugin which built the golang projects scaffold by Kubebuilder go/v4 with kustomize alpha-v2
gov4Bundle, _ := plugin.NewBundleWithOptions(plugin.WithName(golang.DefaultNameQualifier),
plugin.WithVersion(plugin.Version{Number: 4}),
plugin.WithPlugins(kustomizecommonv2alpha.Plugin{}, golangv4.Plugin{}),
)
gov4 := plugin.NewBundlePluginBuilder()
gov4Bundle, _ := gov4.WithName(golang.DefaultNameQualifier).WithVersion(plugin.Version{Number: 4}).WithPlugins(kustomizecommonv2alpha.Plugin{}, golangv4.Plugin{}).Build()

fs := machinery.Filesystem{
FS: afero.NewOsFs(),
Expand Down
58 changes: 28 additions & 30 deletions pkg/plugin/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,31 +31,35 @@ type bundle struct {
deprecateWarning string
}

type BundleOption func(*bundle)
type BundlePluginBuilder struct {
name string
version Version
plugins []Plugin
deprecateWarning string
}

func WithName(name string) BundleOption {
return func(opts *bundle) {
opts.name = name
}
func NewBundlePluginBuilder() BundlePluginBuilder {
return BundlePluginBuilder{}
}

func WithVersion(version Version) BundleOption {
return func(opts *bundle) {
opts.version = version
}
func (bp *BundlePluginBuilder) WithName(name string) *BundlePluginBuilder {
bp.name = name
return bp
}

func WithPlugins(plugins ...Plugin) BundleOption {
return func(opts *bundle) {
opts.plugins = plugins
}
func (bp *BundlePluginBuilder) WithVersion(version Version) *BundlePluginBuilder {
bp.version = version
return bp
}

func WithDeprecationMessage(msg string) BundleOption {
return func(opts *bundle) {
opts.deprecateWarning = msg
}
func (bp *BundlePluginBuilder) WithPlugins(plugins ...Plugin) *BundlePluginBuilder {
bp.plugins = plugins
return bp
}

func (bp *BundlePluginBuilder) WithDeprecationMessage(msg string) *BundlePluginBuilder {
bp.deprecateWarning = msg
return bp
}

// NewBundle creates a new Bundle with the provided name and version, and that wraps the provided plugins.
Expand Down Expand Up @@ -96,23 +100,17 @@ func NewBundle(name string, version Version, deprecateWarning string, plugins ..

// NewBundleWithOptions creates a new Bundle with the provided BundleOptions.
// The list of supported project versions is computed from the provided plugins in options.
func NewBundleWithOptions(opts ...BundleOption) (Bundle, error) {
bundleOpts := bundle{}

for _, opts := range opts {
opts(&bundleOpts)
}

supportedProjectVersions := CommonSupportedProjectVersions(bundleOpts.plugins...)
func (bp *BundlePluginBuilder) Build() (Bundle, error) {
supportedProjectVersions := CommonSupportedProjectVersions(bp.plugins...)
if len(supportedProjectVersions) == 0 {
return nil, fmt.Errorf("in order to bundle plugins, they must all support at least one common project version")
}

// Plugins may be bundles themselves, so unbundle here
// NOTE(Adirio): unbundling here ensures that Bundle.Plugin always returns a flat list of Plugins instead of also
// including Bundles, and therefore we don't have to use a recursive algorithm when resolving.
allPlugins := make([]Plugin, 0, len(bundleOpts.plugins))
for _, plugin := range bundleOpts.plugins {
allPlugins := make([]Plugin, 0, len(bp.plugins))
for _, plugin := range bp.plugins {
if pluginBundle, isBundle := plugin.(Bundle); isBundle {
allPlugins = append(allPlugins, pluginBundle.Plugins()...)
} else {
Expand All @@ -121,11 +119,11 @@ func NewBundleWithOptions(opts ...BundleOption) (Bundle, error) {
}

return bundle{
name: bundleOpts.name,
version: bundleOpts.version,
name: bp.name,
version: bp.version,
plugins: allPlugins,
supportedProjectVersions: supportedProjectVersions,
deprecateWarning: bundleOpts.deprecateWarning,
deprecateWarning: bp.deprecateWarning,
}, nil
}

Expand Down
31 changes: 10 additions & 21 deletions pkg/plugin/bundle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ var _ = Describe("Bundle", func() {
}
})
})

// nolint:lll
Context("NewBundleWithOptions", func() {
It("should succeed for plugins with common supported project versions", func() {
for _, plugins := range [][]Plugin{
Expand All @@ -131,11 +131,8 @@ var _ = Describe("Bundle", func() {
{p1, p2, p3},
{p1, p3, p4},
} {
b, err := NewBundleWithOptions(WithName(name),
WithVersion(version),
WithDeprecationMessage(""),
WithPlugins(plugins...),
)
bp := NewBundlePluginBuilder()
b, err := bp.WithName(name).WithVersion(version).WithDeprecationMessage("").WithPlugins(plugins...).Build()
Expect(err).NotTo(HaveOccurred())
Expect(b.Name()).To(Equal(name))
Expect(b.Version().Compare(version)).To(Equal(0))
Expand All @@ -156,17 +153,12 @@ var _ = Describe("Bundle", func() {
var a, b Bundle
var err error
plugins := []Plugin{p1, p2, p3}
a, err = NewBundleWithOptions(WithName("a"),
WithVersion(version),
WithDeprecationMessage(""),
WithPlugins(p1, p2),
)
bpa := NewBundlePluginBuilder()
a, err = bpa.WithName("a").WithVersion(version).WithDeprecationMessage("").WithPlugins(p1, p2).Build()

Expect(err).NotTo(HaveOccurred())
b, err = NewBundleWithOptions(WithName("b"),
WithVersion(version),
WithDeprecationMessage(""),
WithPlugins(a, p3),
)
bpb := NewBundlePluginBuilder()
b, err = bpb.WithName("b").WithVersion(version).WithDeprecationMessage("").WithPlugins(a, p3).Build()
Expect(err).NotTo(HaveOccurred())
versions := b.SupportedProjectVersions()
sort.Slice(versions, func(i int, j int) bool {
Expand All @@ -189,11 +181,8 @@ var _ = Describe("Bundle", func() {

{p1, p2, p3, p4},
} {
_, err := NewBundleWithOptions(WithName(name),
WithVersion(version),
WithDeprecationMessage(""),
WithPlugins(plugins...),
)
bp := NewBundlePluginBuilder()
_, err := bp.WithName(name).WithVersion(version).WithDeprecationMessage("").WithPlugins(plugins...).Build()
Expect(err).To(HaveOccurred())
}
})
Expand Down