Skip to content

Commit de84b80

Browse files
authored
Merge pull request #2079 from Adirio/cli-external-api
🌱 Remove CLI interface and expose cli instead
2 parents f0ab179 + 4e6c400 commit de84b80

File tree

14 files changed

+142
-113
lines changed

14 files changed

+142
-113
lines changed

pkg/cli/api.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import (
2525
"sigs.k8s.io/kubebuilder/v3/pkg/plugin"
2626
)
2727

28-
func (c cli) newCreateAPICmd() *cobra.Command {
28+
func (c CLI) newCreateAPICmd() *cobra.Command {
2929
ctx := c.newAPIContext()
3030
cmd := &cobra.Command{
3131
Use: "api",
@@ -42,7 +42,7 @@ func (c cli) newCreateAPICmd() *cobra.Command {
4242
return cmd
4343
}
4444

45-
func (c cli) newAPIContext() plugin.Context {
45+
func (c CLI) newAPIContext() plugin.Context {
4646
return plugin.Context{
4747
CommandName: c.commandName,
4848
Description: `Scaffold a Kubernetes API.
@@ -51,7 +51,7 @@ func (c cli) newAPIContext() plugin.Context {
5151
}
5252

5353
// nolint:dupl
54-
func (c cli) bindCreateAPI(ctx plugin.Context, cmd *cobra.Command) {
54+
func (c CLI) bindCreateAPI(ctx plugin.Context, cmd *cobra.Command) {
5555
if len(c.resolvedPlugins) == 0 {
5656
cmdErr(cmd, fmt.Errorf(noPluginError))
5757
return

pkg/cli/cli.go

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,8 @@ func equalStringSlice(a, b []string) bool {
5757
return true
5858
}
5959

60-
// CLI interacts with a command line interface.
61-
type CLI interface {
62-
// Run runs the CLI, usually returning an error if command line configuration
63-
// is incorrect.
64-
Run() error
65-
}
66-
67-
// cli defines the command line structure and interfaces that are used to
68-
// scaffold kubebuilder project files.
69-
type cli struct { //nolint:maligned
60+
// CLI is the command line utility that is used to scaffold kubebuilder project files.
61+
type CLI struct { //nolint:maligned
7062
/* Fields set by Option */
7163

7264
// Root command name. It is injected downstream to provide correct help, usage, examples and errors.
@@ -77,11 +69,11 @@ type cli struct { //nolint:maligned
7769
defaultProjectVersion config.Version
7870
// Default plugins in case none is provided and a config file can't be found.
7971
defaultPlugins map[config.Version][]string
80-
// Plugins registered in the cli.
72+
// Plugins registered in the CLI.
8173
plugins map[string]plugin.Plugin
8274
// Commands injected by options.
8375
extraCommands []*cobra.Command
84-
// Whether to add a completion command to the cli.
76+
// Whether to add a completion command to the CLI.
8577
completionCommand bool
8678

8779
/* Internal fields */
@@ -98,12 +90,17 @@ type cli struct { //nolint:maligned
9890
cmd *cobra.Command
9991
}
10092

101-
// New creates a new cli instance.
102-
// Developer errors (e.g. not registering any plugins, extra commands with conflicting names) return an error
103-
// while user errors (e.g. errors while parsing flags, unresolvable plugins) create a command which return the error.
104-
func New(opts ...Option) (CLI, error) {
93+
// New creates a new CLI instance.
94+
//
95+
// It follows the functional options pattern in order to customize the resulting CLI.
96+
//
97+
// It returns an error if any of the provided options fails. As some processing needs
98+
// to be done, execution errors may be found here. Instead of returning an error, this
99+
// function will return a valid CLI that errors in Run so that help is provided to the
100+
// user.
101+
func New(options ...Option) (*CLI, error) {
105102
// Create the CLI.
106-
c, err := newCLI(opts...)
103+
c, err := newCLI(options...)
107104
if err != nil {
108105
return nil, err
109106
}
@@ -125,20 +122,20 @@ func New(opts ...Option) (CLI, error) {
125122
return c, nil
126123
}
127124

128-
// newCLI creates a default cli instance and applies the provided options.
125+
// newCLI creates a default CLI instance and applies the provided options.
129126
// It is as a separate function for test purposes.
130-
func newCLI(opts ...Option) (*cli, error) {
131-
// Default cli options.
132-
c := &cli{
127+
func newCLI(options ...Option) (*CLI, error) {
128+
// Default CLI options.
129+
c := &CLI{
133130
commandName: "kubebuilder",
134131
defaultProjectVersion: cfgv3.Version,
135132
defaultPlugins: make(map[config.Version][]string),
136133
plugins: make(map[string]plugin.Plugin),
137134
}
138135

139136
// Apply provided options.
140-
for _, opt := range opts {
141-
if err := opt(c); err != nil {
137+
for _, option := range options {
138+
if err := option(c); err != nil {
142139
return nil, err
143140
}
144141
}
@@ -147,7 +144,7 @@ func newCLI(opts ...Option) (*cli, error) {
147144
}
148145

149146
// getInfoFromFlags obtains the project version and plugin keys from flags.
150-
func (c *cli) getInfoFromFlags() (string, []string, error) {
147+
func (c *CLI) getInfoFromFlags() (string, []string, error) {
151148
// Partially parse the command line arguments
152149
fs := pflag.NewFlagSet("base", pflag.ContinueOnError)
153150

@@ -221,7 +218,7 @@ func getInfoFromConfig(projectConfig config.Config) (config.Version, []string, e
221218

222219
// resolveFlagsAndConfigFileConflicts checks if the provided combined input from flags and
223220
// the config file is valid and uses default values in case some info was not provided.
224-
func (c cli) resolveFlagsAndConfigFileConflicts(
221+
func (c CLI) resolveFlagsAndConfigFileConflicts(
225222
flagProjectVersionString string,
226223
cfgProjectVersion config.Version,
227224
flagPlugins, cfgPlugins []string,
@@ -290,7 +287,7 @@ func (c cli) resolveFlagsAndConfigFileConflicts(
290287
}
291288

292289
// getInfo obtains the project version and plugin keys resolving conflicts among flags and the project config file.
293-
func (c *cli) getInfo() error {
290+
func (c *CLI) getInfo() error {
294291
// Get project version and plugin info from flags
295292
flagProjectVersion, flagPlugins, err := c.getInfoFromFlags()
296293
if err != nil {
@@ -312,7 +309,7 @@ const unstablePluginMsg = " (plugin version is unstable, there may be an upgrade
312309
"https://kubebuilder.io/migration/plugin/plugins.html)"
313310

314311
// resolve selects from the available plugins those that match the project version and plugin keys provided.
315-
func (c *cli) resolve() error {
312+
func (c *CLI) resolve() error {
316313
var plugins []plugin.Plugin
317314
for _, pluginKey := range c.pluginKeys {
318315
name, version := plugin.SplitKey(pluginKey)
@@ -402,7 +399,7 @@ func (c *cli) resolve() error {
402399

403400
// addSubcommands returns a root command with a subcommand tree reflecting the
404401
// current project's state.
405-
func (c *cli) addSubcommands() {
402+
func (c *CLI) addSubcommands() {
406403
// kubebuilder completion
407404
// Only add completion if requested
408405
if c.completionCommand {
@@ -432,7 +429,7 @@ func (c *cli) addSubcommands() {
432429
}
433430

434431
// buildCmd creates the underlying cobra command and stores it internally.
435-
func (c *cli) buildCmd() error {
432+
func (c *CLI) buildCmd() error {
436433
c.cmd = c.newRootCmd()
437434

438435
// Get project version and plugin keys.
@@ -452,7 +449,7 @@ func (c *cli) buildCmd() error {
452449
}
453450

454451
// addExtraCommands adds the additional commands.
455-
func (c *cli) addExtraCommands() error {
452+
func (c *CLI) addExtraCommands() error {
456453
for _, cmd := range c.extraCommands {
457454
for _, subCmd := range c.cmd.Commands() {
458455
if cmd.Name() == subCmd.Name() {
@@ -465,15 +462,17 @@ func (c *cli) addExtraCommands() error {
465462
}
466463

467464
// printDeprecationWarnings prints the deprecation warnings of the resolved plugins.
468-
func (c cli) printDeprecationWarnings() {
465+
func (c CLI) printDeprecationWarnings() {
469466
for _, p := range c.resolvedPlugins {
470467
if d, isDeprecated := p.(plugin.Deprecated); isDeprecated {
471468
fmt.Printf(noticeColor, fmt.Sprintf(deprecationFmt, d.DeprecationWarning()))
472469
}
473470
}
474471
}
475472

476-
// Run implements CLI.Run.
477-
func (c cli) Run() error {
473+
// Run executes the CLI utility.
474+
//
475+
// If an error is found, command help and examples will be printed.
476+
func (c CLI) Run() error {
478477
return c.cmd.Execute()
479478
}

0 commit comments

Comments
 (0)