Skip to content

Commit 91afef6

Browse files
PuneetPunamiyasoltysh
authored andcommitted
Refactors explain command to split flags from options
Signed-off-by: Puneet Punamiya [email protected] Signed-off-by: Maciej Szulik <[email protected]>
1 parent 0798325 commit 91afef6

File tree

2 files changed

+85
-52
lines changed

2 files changed

+85
-52
lines changed

staging/src/k8s.io/kubectl/pkg/cmd/explain/explain.go

Lines changed: 78 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -56,44 +56,78 @@ var (
5656
5757
# Get the documentation of a specific field of a resource
5858
kubectl explain pods.spec.containers
59-
59+
6060
# Get the documentation of resources in different format
6161
kubectl explain deployment --output=plaintext-openapiv2`))
6262

6363
plaintextTemplateName = "plaintext"
6464
plaintextOpenAPIV2TemplateName = "plaintext-openapiv2"
6565
)
6666

67-
type ExplainOptions struct {
68-
genericiooptions.IOStreams
69-
70-
CmdParent string
67+
type ExplainFlags struct {
7168
APIVersion string
72-
Recursive bool
73-
74-
args []string
75-
76-
Mapper meta.RESTMapper
77-
openAPIGetter openapi.OpenAPIResourcesGetter
78-
79-
// Name of the template to use with the openapiv3 template renderer.
69+
// Name of the template to use with the openapiv3 template renderer. If
70+
// `EnableOpenAPIV3` is disabled, this does nothing
8071
OutputFormat string
72+
Recursive bool
73+
genericclioptions.IOStreams
74+
}
8175

82-
// Client capable of fetching openapi documents from the user's cluster
83-
OpenAPIV3Client openapiclient.Client
76+
// AddFlags registers flags for a cli
77+
func (flags *ExplainFlags) AddFlags(cmd *cobra.Command) {
78+
cmd.Flags().BoolVar(&flags.Recursive, "recursive", flags.Recursive, "Print the fields of fields (Currently only 1 level deep)")
79+
cmd.Flags().StringVar(&flags.APIVersion, "api-version", flags.APIVersion, "Get different explanations for particular API version (API group/version)")
80+
81+
// Only enable --output as a valid flag if the feature is enabled
82+
cmd.Flags().StringVar(&flags.OutputFormat, "output", plaintextTemplateName, "Format in which to render the schema (plaintext, plaintext-openapiv2)")
8483
}
8584

86-
func NewExplainOptions(parent string, streams genericiooptions.IOStreams) *ExplainOptions {
87-
return &ExplainOptions{
88-
IOStreams: streams,
89-
CmdParent: parent,
85+
// NewExplainFlags returns a default ExplainFlags
86+
func NewExplainFlags(streams genericclioptions.IOStreams) *ExplainFlags {
87+
return &ExplainFlags{
9088
OutputFormat: plaintextTemplateName,
89+
IOStreams: streams,
90+
}
91+
}
92+
93+
// ToOptions converts from CLI inputs to runtime input
94+
func (flags *ExplainFlags) ToOptions(f cmdutil.Factory, parent string, args []string) (*ExplainOptions, error) {
95+
mapper, err := f.ToRESTMapper()
96+
if err != nil {
97+
return nil, err
98+
}
99+
100+
schema, err := f.OpenAPISchema()
101+
if err != nil {
102+
return nil, err
91103
}
104+
105+
// Only openapi v3 needs the discovery client.
106+
openAPIV3Client, err := f.OpenAPIV3Client()
107+
if err != nil {
108+
return nil, err
109+
}
110+
111+
o := &ExplainOptions{
112+
CmdParent: parent,
113+
Mapper: mapper,
114+
Schema: schema,
115+
args: args,
116+
IOStreams: flags.IOStreams,
117+
Recursive: flags.Recursive,
118+
APIVersion: flags.APIVersion,
119+
OutputFormat: plaintextTemplateName,
120+
OpenAPIV3Client: openAPIV3Client,
121+
}
122+
123+
return o, nil
92124
}
93125

94126
// NewCmdExplain returns a cobra command for swagger docs
95-
func NewCmdExplain(parent string, f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command {
96-
o := NewExplainOptions(parent, streams)
127+
func NewCmdExplain(parent string, f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
128+
// o := NewExplainOptions(parent, streams)
129+
130+
flags := NewExplainFlags(streams)
97131

98132
cmd := &cobra.Command{
99133
Use: "explain TYPE [--recursive=FALSE|TRUE] [--api-version=api-version-group] [-o|--output=plaintext|plaintext-openapiv2]",
@@ -102,39 +136,18 @@ func NewCmdExplain(parent string, f cmdutil.Factory, streams genericiooptions.IO
102136
Long: explainLong + "\n\n" + cmdutil.SuggestAPIResources(parent),
103137
Example: explainExamples,
104138
Run: func(cmd *cobra.Command, args []string) {
105-
cmdutil.CheckErr(o.Complete(f, cmd, args))
139+
o, err := flags.ToOptions(f, parent, args)
140+
cmdutil.CheckErr(err)
106141
cmdutil.CheckErr(o.Validate())
107142
cmdutil.CheckErr(o.Run())
108143
},
109144
}
110-
cmd.Flags().BoolVar(&o.Recursive, "recursive", o.Recursive, "When true, print the name of all the fields recursively. Otherwise, print the available fields with their description.")
111-
cmd.Flags().StringVar(&o.APIVersion, "api-version", o.APIVersion, "Use given api-version (group/version) of the resource.")
112145

113-
// Only enable --output as a valid flag if the feature is enabled
114-
cmd.Flags().StringVarP(&o.OutputFormat, "output", "o", plaintextTemplateName, "Format in which to render the schema. Valid values are: (plaintext, plaintext-openapiv2).")
146+
flags.AddFlags(cmd)
115147

116148
return cmd
117149
}
118150

119-
func (o *ExplainOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
120-
var err error
121-
o.Mapper, err = f.ToRESTMapper()
122-
if err != nil {
123-
return err
124-
}
125-
126-
// Only openapi v3 needs the discovery client.
127-
o.OpenAPIV3Client, err = f.OpenAPIV3Client()
128-
if err != nil {
129-
return err
130-
}
131-
132-
// Lazy-load the OpenAPI V2 Resources, so they're not loaded when using OpenAPI V3.
133-
o.openAPIGetter = f
134-
o.args = args
135-
return nil
136-
}
137-
138151
func (o *ExplainOptions) Validate() error {
139152
if len(o.args) == 0 {
140153
return fmt.Errorf("You must specify the type of resource to explain. %s\n", cmdutil.SuggestAPIResources(o.CmdParent))
@@ -232,3 +245,23 @@ func (o *ExplainOptions) renderOpenAPIV2(
232245

233246
return explain.PrintModelDescription(fieldsPath, o.Out, schema, gvk, o.Recursive)
234247
}
248+
249+
type ExplainOptions struct {
250+
genericclioptions.IOStreams
251+
252+
CmdParent string
253+
APIVersion string
254+
Recursive bool
255+
256+
args []string
257+
258+
Mapper meta.RESTMapper
259+
Schema openapi.Resources
260+
261+
// Name of the template to use with the openapiv3 template renderer. If
262+
// `EnableOpenAPIV3` is disabled, this does nothing
263+
OutputFormat string
264+
265+
// Client capable of fetching openapi documents from the user's cluster
266+
OpenAPIV3Client openapiclient.Client
267+
}

staging/src/k8s.io/kubectl/pkg/cmd/explain/explain_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ func TestExplainInvalidArgs(t *testing.T) {
5757
tf := cmdtesting.NewTestFactory()
5858
defer tf.Cleanup()
5959

60-
opts := explain.NewExplainOptions("kubectl", genericiooptions.NewTestIOStreamsDiscard())
61-
cmd := explain.NewCmdExplain("kubectl", tf, genericiooptions.NewTestIOStreamsDiscard())
62-
err := opts.Complete(tf, cmd, []string{})
60+
flags := explain.NewExplainFlags(genericclioptions.NewTestIOStreamsDiscard())
61+
62+
opts, err := flags.ToOptions(tf, "kubectl", []string{})
6363
if err != nil {
6464
t.Fatalf("unexpected error %v", err)
6565
}
@@ -69,7 +69,7 @@ func TestExplainInvalidArgs(t *testing.T) {
6969
t.Error("unexpected non-error")
7070
}
7171

72-
err = opts.Complete(tf, cmd, []string{"resource1", "resource2"})
72+
opts, err = flags.ToOptions(tf, "kubectl", []string{"resource1", "resource2"})
7373
if err != nil {
7474
t.Fatalf("unexpected error %v", err)
7575
}
@@ -84,9 +84,9 @@ func TestExplainNotExistResource(t *testing.T) {
8484
tf := cmdtesting.NewTestFactory()
8585
defer tf.Cleanup()
8686

87-
opts := explain.NewExplainOptions("kubectl", genericiooptions.NewTestIOStreamsDiscard())
88-
cmd := explain.NewCmdExplain("kubectl", tf, genericiooptions.NewTestIOStreamsDiscard())
89-
err := opts.Complete(tf, cmd, []string{"foo"})
87+
flags := explain.NewExplainFlags(genericclioptions.NewTestIOStreamsDiscard())
88+
89+
opts, err := flags.ToOptions(tf, "kubectl", []string{"foo"})
9090
if err != nil {
9191
t.Fatalf("unexpected error %v", err)
9292
}

0 commit comments

Comments
 (0)