@@ -30,6 +30,7 @@ import (
3030 "sigs.k8s.io/kubebuilder/v4/pkg/config"
3131 cfgv3 "sigs.k8s.io/kubebuilder/v4/pkg/config/v3"
3232 "sigs.k8s.io/kubebuilder/v4/pkg/machinery"
33+ "sigs.k8s.io/kubebuilder/v4/pkg/model/resource"
3334 "sigs.k8s.io/kubebuilder/v4/pkg/model/stage"
3435 "sigs.k8s.io/kubebuilder/v4/pkg/plugin"
3536 golangv4 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/v4"
@@ -77,6 +78,56 @@ func hasSubCommand(cmd *cobra.Command, name string) bool {
7778 return false
7879}
7980
81+ type testCreateAPIPlugin struct {
82+ name string
83+ version plugin.Version
84+ subcommand * testCreateAPISubcommand
85+ projectVers []config.Version
86+ }
87+
88+ func newTestCreateAPIPlugin (name string , version plugin.Version ) testCreateAPIPlugin {
89+ return testCreateAPIPlugin {
90+ name : name ,
91+ version : version ,
92+ subcommand : & testCreateAPISubcommand {},
93+ projectVers : []config.Version {{Number : 3 }},
94+ }
95+ }
96+
97+ func (p testCreateAPIPlugin ) Name () string { return p .name }
98+ func (p testCreateAPIPlugin ) Version () plugin.Version { return p .version }
99+ func (p testCreateAPIPlugin ) SupportedProjectVersions () []config.Version { return p .projectVers }
100+ func (p testCreateAPIPlugin ) GetCreateAPISubcommand () plugin.CreateAPISubcommand {
101+ return p .subcommand
102+ }
103+
104+ type testCreateAPISubcommand struct {}
105+
106+ func (s * testCreateAPISubcommand ) InjectResource (* resource.Resource ) error {
107+ return nil
108+ }
109+
110+ func (s * testCreateAPISubcommand ) Scaffold (machinery.Filesystem ) error {
111+ return nil
112+ }
113+
114+ type fakeStore struct {
115+ cfg config.Config
116+ }
117+
118+ func (f * fakeStore ) New (config.Version ) error { return nil }
119+ func (f * fakeStore ) Load () error { return nil }
120+ func (f * fakeStore ) LoadFrom (string ) error { return nil }
121+ func (f * fakeStore ) Save () error { return nil }
122+ func (f * fakeStore ) SaveTo (string ) error { return nil }
123+ func (f * fakeStore ) Config () config.Config { return f .cfg }
124+
125+ type captureSubcommand struct {
126+ lastChain []string
127+ }
128+
129+ func (c * captureSubcommand ) Scaffold (machinery.Filesystem ) error { return nil }
130+
80131var _ = Describe ("CLI" , func () {
81132 var (
82133 c * CLI
@@ -91,6 +142,83 @@ var _ = Describe("CLI", func() {
91142 projectVersion = config.Version {Number : 3 }
92143 })
93144
145+ Describe ("filterSubcommands" , func () {
146+ It ("propagates bundle keys to wrapped subcommands" , func () {
147+ bundleVersion := plugin.Version {Number : 1 , Stage : stage .Alpha }
148+
149+ fooPlugin := newTestCreateAPIPlugin ("deploy-image.go.kubebuilder.io" , plugin.Version {Number : 1 , Stage : stage .Alpha })
150+ barPlugin := newTestCreateAPIPlugin ("deploy-image.go.kubebuilder.io" , plugin.Version {Number : 1 , Stage : stage .Alpha })
151+
152+ fooBundle , err := plugin .NewBundleWithOptions (
153+ plugin .WithName ("deploy-image.foo.example.com" ),
154+ plugin .WithVersion (bundleVersion ),
155+ plugin .WithPlugins (fooPlugin ),
156+ )
157+ Expect (err ).NotTo (HaveOccurred ())
158+
159+ barBundle , err := plugin .NewBundleWithOptions (
160+ plugin .WithName ("deploy-image.bar.example.com" ),
161+ plugin .WithVersion (bundleVersion ),
162+ plugin .WithPlugins (barPlugin ),
163+ )
164+ Expect (err ).NotTo (HaveOccurred ())
165+
166+ c .resolvedPlugins = []plugin.Plugin {fooBundle , barBundle }
167+
168+ tuples := c .filterSubcommands (
169+ func (p plugin.Plugin ) bool {
170+ _ , isCreateAPI := p .(plugin.CreateAPI )
171+ return isCreateAPI
172+ },
173+ func (p plugin.Plugin ) plugin.Subcommand {
174+ return p .(plugin.CreateAPI ).GetCreateAPISubcommand ()
175+ },
176+ )
177+
178+ Expect (tuples ).To (HaveLen (2 ))
179+ Expect (tuples [0 ].key ).To (Equal ("deploy-image.go.kubebuilder.io/v1-alpha" ))
180+ Expect (tuples [0 ].configKey ).To (Equal ("deploy-image.foo.example.com/v1-alpha" ))
181+ Expect (tuples [1 ].key ).To (Equal ("deploy-image.go.kubebuilder.io/v1-alpha" ))
182+ Expect (tuples [1 ].configKey ).To (Equal ("deploy-image.bar.example.com/v1-alpha" ))
183+ })
184+ })
185+
186+ Describe ("executionHooksFactory" , func () {
187+ It ("temporarily reorders the plugin chain while invoking bundled subcommands" , func () {
188+ cfg := cfgv3 .New ()
189+ Expect (cfg .SetPluginChain ([]string {
190+ "deploy-image.foo.example.com/v1-alpha" ,
191+ "deploy-image.bar.example.com/v1-alpha" ,
192+ })).To (Succeed ())
193+
194+ store := & fakeStore {cfg : cfg }
195+ first := & captureSubcommand {}
196+ second := & captureSubcommand {}
197+
198+ factory := executionHooksFactory {
199+ store : store ,
200+ subcommands : []keySubcommandTuple {
201+ {configKey : "deploy-image.foo.example.com/v1-alpha" , subcommand : first },
202+ {configKey : "deploy-image.bar.example.com/v1-alpha" , subcommand : second },
203+ },
204+ errorMessage : "test" ,
205+ }
206+
207+ callErr := factory .forEach (func (sub plugin.Subcommand ) error {
208+ cs := sub .(* captureSubcommand )
209+ cs .lastChain = append ([]string (nil ), store .Config ().GetPluginChain ()... )
210+ return nil
211+ }, "scaffold" )
212+ Expect (callErr ).NotTo (HaveOccurred ())
213+ Expect (first .lastChain [0 ]).To (Equal ("deploy-image.foo.example.com/v1-alpha" ))
214+ Expect (second .lastChain [0 ]).To (Equal ("deploy-image.bar.example.com/v1-alpha" ))
215+ Expect (store .Config ().GetPluginChain ()).To (Equal ([]string {
216+ "deploy-image.foo.example.com/v1-alpha" ,
217+ "deploy-image.bar.example.com/v1-alpha" ,
218+ }))
219+ })
220+ })
221+
94222 Context ("buildCmd" , func () {
95223 var projectFile string
96224
0 commit comments