Skip to content

Commit

Permalink
Plugin phase 1.5 implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Adrian Orive <[email protected]>
  • Loading branch information
Adirio committed Mar 6, 2021
1 parent 2b46403 commit e5eea91
Show file tree
Hide file tree
Showing 215 changed files with 5,776 additions and 6,090 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ test-unit: ## Run the unit tests
.PHONY: test-coverage
test-coverage: ## Run unit tests creating the output to report coverage
- rm -rf *.out # Remove all coverage files if exists
go test -race -failfast -tags=integration -coverprofile=coverage-all.out -coverpkg="./pkg/cli/...,./pkg/config/...,./pkg/internal/...,./pkg/model/...,./pkg/plugin/...,./pkg/plugins/golang,./pkg/plugins/internal/..." ./pkg/...
go test -race -failfast -tags=integration -coverprofile=coverage-all.out -coverpkg="./pkg/cli/...,./pkg/config/...,./pkg/internal/...,./pkg/machinery/...,./pkg/model/...,./pkg/plugin/...,./pkg/plugins/golang" ./pkg/...

.PHONY: test-integration
test-integration: ## Run the integration tests
Expand Down
8 changes: 4 additions & 4 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import (
"log"

"sigs.k8s.io/kubebuilder/v3/pkg/cli"
cfgv2 "sigs.k8s.io/kubebuilder/v3/pkg/config/v2"
cfgv3 "sigs.k8s.io/kubebuilder/v3/pkg/config/v3"
declarativev1 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/declarative/v1"
pluginv2 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2"
pluginv3 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3"
)
Expand All @@ -30,13 +30,13 @@ func main() {
c, err := cli.New(
cli.WithCommandName("kubebuilder"),
cli.WithVersion(versionString()),
cli.WithDefaultProjectVersion(cfgv3.Version),
cli.WithPlugins(
&pluginv2.Plugin{},
&pluginv3.Plugin{},
&declarativev1.Plugin{},
),
cli.WithDefaultPlugins(cfgv2.Version, &pluginv2.Plugin{}),
cli.WithDefaultPlugins(cfgv3.Version, &pluginv3.Plugin{}),
cli.WithDefaultPlugins(&pluginv3.Plugin{}),
cli.WithDefaultProjectVersion(cfgv3.Version),
cli.WithCompletion(),
)
if err != nil {
Expand Down
84 changes: 31 additions & 53 deletions pkg/cli/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,80 +14,58 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package cli // nolint:dupl
package cli //nolint:dupl

import (
"fmt"

"github.com/spf13/cobra"

"sigs.k8s.io/kubebuilder/v3/pkg/cli/internal/config"
"sigs.k8s.io/kubebuilder/v3/pkg/plugin"
)

const apiErrorMsg = "failed to create API"

func (c cli) newCreateAPICmd() *cobra.Command {
ctx := c.newAPIContext()
cmd := &cobra.Command{
Use: "api",
Short: "Scaffold a Kubernetes API",
Long: ctx.Description,
Example: ctx.Examples,
Use: "api",
Short: "Scaffold a Kubernetes API",
Long: `Scaffold a Kubernetes API.
`,
RunE: errCmdFunc(
fmt.Errorf("api subcommand requires an existing project"),
),
}

// Lookup the plugin for projectVersion and bind it to the command.
c.bindCreateAPI(ctx, cmd)
return cmd
}

func (c cli) newAPIContext() plugin.Context {
return plugin.Context{
CommandName: c.commandName,
Description: `Scaffold a Kubernetes API.
`,
}
}

// nolint:dupl
func (c cli) bindCreateAPI(ctx plugin.Context, cmd *cobra.Command) {
// In case no plugin was resolved, instead of failing the construction of the CLI, fail the execution of
// this subcommand. This allows the use of subcommands that do not require resolved plugins like help.
if len(c.resolvedPlugins) == 0 {
cmdErr(cmd, fmt.Errorf(noPluginError))
return
cmdErr(cmd, noResolvedPluginError{})
return cmd
}

var createAPIPlugin plugin.CreateAPI
for _, p := range c.resolvedPlugins {
tmpPlugin, isValid := p.(plugin.CreateAPI)
if isValid {
if createAPIPlugin != nil {
err := fmt.Errorf("duplicate API creation plugins (%s, %s), use a more specific plugin key",
plugin.KeyFor(createAPIPlugin), plugin.KeyFor(p))
cmdErr(cmd, err)
return
}
createAPIPlugin = tmpPlugin
}
}
// Obtain the plugin keys and subcommands from the plugins that implement plugin.CreateAPI.
pluginKeys, subcommands := c.filterSubcommands(
func(p plugin.Plugin) bool {
_, isValid := p.(plugin.CreateAPI)
return isValid
},
func(p plugin.Plugin) plugin.Subcommand {
return p.(plugin.CreateAPI).GetCreateAPISubcommand()
},
)

if createAPIPlugin == nil {
cmdErr(cmd, fmt.Errorf("resolved plugins do not provide an API creation plugin: %v", c.pluginKeys))
return
// Verify that there is at least one remaining plugin.
if len(*subcommands) == 0 {
cmdErr(cmd, noAvailablePluginError{"API creation"})
return cmd
}

cfg, err := config.LoadInitialized()
if err != nil {
cmdErr(cmd, err)
return
}
// Initialization methods.
options := c.initializationMethods(cmd, subcommands)

// Execution methods.
cmd.PreRunE, cmd.RunE, cmd.PostRunE = c.executionMethodsFuncs(pluginKeys, subcommands, options, apiErrorMsg)

subcommand := createAPIPlugin.GetCreateAPISubcommand()
subcommand.InjectConfig(cfg.Config)
subcommand.BindFlags(cmd.Flags())
subcommand.UpdateContext(&ctx)
cmd.Long = ctx.Description
cmd.Example = ctx.Examples
cmd.RunE = runECmdFunc(cfg, subcommand,
fmt.Sprintf("failed to create API with %q", plugin.KeyFor(createAPIPlugin)))
return cmd
}
Loading

0 comments on commit e5eea91

Please sign in to comment.