Skip to content

Commit 84f357b

Browse files
authored
Merge pull request #2112 from Adirio/bundle-recursion
✨ Allow bundles to be used as input to other bundles
2 parents f65ddb2 + 39ec8f8 commit 84f357b

File tree

3 files changed

+42
-9
lines changed

3 files changed

+42
-9
lines changed

pkg/plugin/bundle.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,22 @@ func NewBundle(name string, version Version, plugins ...Plugin) (Bundle, error)
3838
return nil, fmt.Errorf("in order to bundle plugins, they must all support at least one common project version")
3939
}
4040

41+
// Plugins may be bundles themselves, so unbundle here
42+
// NOTE(Adirio): unbundling here ensures that Bundle.Plugin always returns a flat list of Plugins instead of also
43+
// including Bundles, and therefore we don't have to use a recursive algorithm when resolving.
44+
allPlugins := make([]Plugin, 0, len(plugins))
45+
for _, plugin := range plugins {
46+
if pluginBundle, isBundle := plugin.(Bundle); isBundle {
47+
allPlugins = append(allPlugins, pluginBundle.Plugins()...)
48+
} else {
49+
allPlugins = append(allPlugins, plugin)
50+
}
51+
}
52+
4153
return bundle{
4254
name: name,
4355
version: version,
44-
plugins: plugins,
56+
plugins: allPlugins,
4557
supportedProjectVersions: supportedProjectVersions,
4658
}, nil
4759
}

pkg/plugin/bundle_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,26 @@ var _ = Describe("Bundle", func() {
8484
}
8585
})
8686

87+
It("should accept bundles as input", func() {
88+
var a, b Bundle
89+
var err error
90+
plugins := []Plugin{p1, p2, p3}
91+
a, err = NewBundle("a", version, p1, p2)
92+
Expect(err).NotTo(HaveOccurred())
93+
b, err = NewBundle("b", version, a, p3)
94+
Expect(err).NotTo(HaveOccurred())
95+
versions := b.SupportedProjectVersions()
96+
sort.Slice(versions, func(i int, j int) bool {
97+
return versions[i].Compare(versions[j]) == -1
98+
})
99+
expectedVersions := CommonSupportedProjectVersions(plugins...)
100+
sort.Slice(expectedVersions, func(i int, j int) bool {
101+
return expectedVersions[i].Compare(expectedVersions[j]) == -1
102+
})
103+
Expect(versions).To(Equal(expectedVersions))
104+
Expect(b.Plugins()).To(Equal(plugins))
105+
})
106+
87107
It("should fail for plugins with no common supported project version", func() {
88108
for _, plugins := range [][]Plugin{
89109
{p2, p4},

pkg/plugin/plugin.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020
"sigs.k8s.io/kubebuilder/v3/pkg/config"
2121
)
2222

23-
// Plugin is an interface that defines the common base for all plugins
23+
// Plugin is an interface that defines the common base for all plugins.
2424
type Plugin interface {
2525
// Name returns a DNS1123 label string identifying the plugin uniquely. This name should be fully-qualified,
2626
// i.e. have a short prefix describing the plugin type (like a language) followed by a domain.
@@ -41,45 +41,46 @@ type Deprecated interface {
4141
DeprecationWarning() string
4242
}
4343

44-
// Init is an interface for plugins that provide an `init` subcommand
44+
// Init is an interface for plugins that provide an `init` subcommand.
4545
type Init interface {
4646
Plugin
4747
// GetInitSubcommand returns the underlying InitSubcommand interface.
4848
GetInitSubcommand() InitSubcommand
4949
}
5050

51-
// CreateAPI is an interface for plugins that provide a `create api` subcommand
51+
// CreateAPI is an interface for plugins that provide a `create api` subcommand.
5252
type CreateAPI interface {
5353
Plugin
5454
// GetCreateAPISubcommand returns the underlying CreateAPISubcommand interface.
5555
GetCreateAPISubcommand() CreateAPISubcommand
5656
}
5757

58-
// CreateWebhook is an interface for plugins that provide a `create webhook` subcommand
58+
// CreateWebhook is an interface for plugins that provide a `create webhook` subcommand.
5959
type CreateWebhook interface {
6060
Plugin
6161
// GetCreateWebhookSubcommand returns the underlying CreateWebhookSubcommand interface.
6262
GetCreateWebhookSubcommand() CreateWebhookSubcommand
6363
}
6464

65-
// Edit is an interface for plugins that provide a `edit` subcommand
65+
// Edit is an interface for plugins that provide a `edit` subcommand.
6666
type Edit interface {
6767
Plugin
6868
// GetEditSubcommand returns the underlying EditSubcommand interface.
6969
GetEditSubcommand() EditSubcommand
7070
}
7171

72-
// Full is an interface for plugins that provide `init`, `create api`, `create webhook` and `edit` subcommands
72+
// Full is an interface for plugins that provide `init`, `create api`, `create webhook` and `edit` subcommands.
7373
type Full interface {
7474
Init
7575
CreateAPI
7676
CreateWebhook
7777
Edit
7878
}
7979

80-
// Bundle allows to group plugins under a single key
80+
// Bundle allows to group plugins under a single key.
8181
type Bundle interface {
8282
Plugin
83-
// Plugins returns a list of the bundled plugins
83+
// Plugins returns a list of the bundled plugins.
84+
// The returned list should be flattened, i.e., no plugin bundles should be part of this list.
8485
Plugins() []Plugin
8586
}

0 commit comments

Comments
 (0)