@@ -28,11 +28,19 @@ import (
28
28
29
29
"github.com/spf13/pflag"
30
30
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
31
+ "sigs.k8s.io/kubebuilder/v3/pkg/plugin"
31
32
"sigs.k8s.io/kubebuilder/v3/pkg/plugin/external"
32
33
)
33
34
34
35
var outputGetter ExecOutputGetter = & execOutputGetter {}
35
36
37
+ const defaultMetadataTemplate = `
38
+ %s is an external plugin for scaffolding files to help with your Operator development.
39
+
40
+ For more information on how to use this external plugin, it is recommended to
41
+ consult the external plugin's documentation.
42
+ `
43
+
36
44
// ExecOutputGetter is an interface that implements the exec output method.
37
45
type ExecOutputGetter interface {
38
46
GetExecOutput (req []byte , path string ) ([]byte , error )
@@ -70,27 +78,36 @@ func (o *osWdGetter) GetCurrentDir() (string, error) {
70
78
return currentDir , nil
71
79
}
72
80
73
- func handlePluginResponse (fs machinery.Filesystem , req external.PluginRequest , path string ) error {
74
- req .Universe = map [string ]string {}
75
-
81
+ func makePluginRequest (req external.PluginRequest , path string ) (* external.PluginResponse , error ) {
76
82
reqBytes , err := json .Marshal (req )
77
83
if err != nil {
78
- return err
84
+ return nil , err
79
85
}
80
86
81
87
out , err := outputGetter .GetExecOutput (reqBytes , path )
82
88
if err != nil {
83
- return err
89
+ return nil , err
84
90
}
85
91
86
92
res := external.PluginResponse {}
87
93
if err := json .Unmarshal (out , & res ); err != nil {
88
- return err
94
+ return nil , err
89
95
}
90
96
91
97
// Error if the plugin failed.
92
98
if res .Error {
93
- return fmt .Errorf (strings .Join (res .ErrorMsgs , "\n " ))
99
+ return nil , fmt .Errorf (strings .Join (res .ErrorMsgs , "\n " ))
100
+ }
101
+
102
+ return & res , nil
103
+ }
104
+
105
+ func handlePluginResponse (fs machinery.Filesystem , req external.PluginRequest , path string ) error {
106
+ req .Universe = map [string ]string {}
107
+
108
+ res , err := makePluginRequest (req , path )
109
+ if err != nil {
110
+ return fmt .Errorf ("error making request to external plugin: %w" , err )
94
111
}
95
112
96
113
currentDir , err := currentDirGetter .GetCurrentDir ()
@@ -123,23 +140,9 @@ func handlePluginResponse(fs machinery.Filesystem, req external.PluginRequest, p
123
140
func getExternalPluginFlags (req external.PluginRequest , path string ) ([]external.Flag , error ) {
124
141
req .Universe = map [string ]string {}
125
142
126
- reqBytes , err := json . Marshal (req )
143
+ res , err := makePluginRequest (req , path )
127
144
if err != nil {
128
- return nil , err
129
- }
130
-
131
- out , err := outputGetter .GetExecOutput (reqBytes , path )
132
- if err != nil {
133
- return nil , err
134
- }
135
-
136
- res := external.PluginResponse {}
137
- if err := json .Unmarshal (out , & res ); err != nil {
138
- return nil , err
139
- }
140
-
141
- if res .Error {
142
- return nil , fmt .Errorf (strings .Join (res .ErrorMsgs , "\n " ))
145
+ return nil , fmt .Errorf ("error making request to external plugin: %w" , err )
143
146
}
144
147
145
148
return res .Flags , nil
@@ -211,3 +214,43 @@ func bindExternalPluginFlags(fs *pflag.FlagSet, subcommand string, path string,
211
214
bindSpecificFlags (fs , flags )
212
215
}
213
216
}
217
+
218
+ // setExternalPluginMetadata is a helper function that sets the subcommand
219
+ // metadata that is used when the help text is shown for a subcommand.
220
+ // It will attempt to get the Metadata from the external plugin. If the
221
+ // external plugin returns no Metadata or an error, a default will be used.
222
+ func setExternalPluginMetadata (subcommand , path string , subcmdMeta * plugin.SubcommandMetadata ) {
223
+ fileName := filepath .Base (path )
224
+ subcmdMeta .Description = fmt .Sprintf (defaultMetadataTemplate , fileName [:len (fileName )- len (filepath .Ext (fileName ))])
225
+
226
+ res , _ := getExternalPluginMetadata (subcommand , path )
227
+
228
+ if res != nil {
229
+ if res .Description != "" {
230
+ subcmdMeta .Description = res .Description
231
+ }
232
+
233
+ if res .Examples != "" {
234
+ subcmdMeta .Examples = res .Examples
235
+ }
236
+ }
237
+ }
238
+
239
+ // fetchExternalPluginMetadata performs the actual request to the
240
+ // external plugin to get the metadata. It returns the metadata
241
+ // or an error if an error occurs during the fetch process.
242
+ func getExternalPluginMetadata (subcommand , path string ) (* plugin.SubcommandMetadata , error ) {
243
+ req := external.PluginRequest {
244
+ APIVersion : defaultAPIVersion ,
245
+ Command : "metadata" ,
246
+ Args : []string {"--" + subcommand },
247
+ Universe : map [string ]string {},
248
+ }
249
+
250
+ res , err := makePluginRequest (req , path )
251
+ if err != nil {
252
+ return nil , fmt .Errorf ("error making request to external plugin: %w" , err )
253
+ }
254
+
255
+ return & res .Metadata , nil
256
+ }
0 commit comments