Skip to content

Commit

Permalink
Merge pull request #4 from Peefy/feat-plugin-framework
Browse files Browse the repository at this point in the history
feat: add plugin framework and mod and registry subcommands
  • Loading branch information
Peefy authored Oct 24, 2023
2 parents f5a4902 + 76bd812 commit a4da757
Show file tree
Hide file tree
Showing 6 changed files with 416 additions and 3 deletions.
77 changes: 77 additions & 0 deletions cmd/mod.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package cmd

import (
"github.com/spf13/cobra"
cli "github.com/urfave/cli/v2"
"kcl-lang.io/cli/pkg/version"
"kcl-lang.io/kpm/pkg/client"
kpmcmd "kcl-lang.io/kpm/pkg/cmd"
"kcl-lang.io/kpm/pkg/reporter"
)

const (
modDesc = `
This command manages the kcl module
`
modExample = ` # Init one kcl module
kcl mod init
# Push the module
kcl mod push
`
)

// NewModCmd returns the mod command.
func NewModCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "mod",
Short: "KCL module management",
Long: modDesc,
Example: modExample,
RunE: func(_ *cobra.Command, args []string) error {
return RunWithKpmMod("mod", args)
},
SilenceUsage: true,
}

return cmd
}

func RunWithKpmMod(cmd string, args []string) error {
reporter.InitReporter()
kpmcli, err := client.NewKpmClient()
if err != nil {
return err
}
app := cli.NewApp()
app.Usage = "module related functions"
app.Name = "kcl mod"
app.Version = version.GetVersionString()
app.UsageText = "kcl mod <command> [arguments]..."
app.Commands = []*cli.Command{
kpmcmd.NewInitCmd(kpmcli),
kpmcmd.NewAddCmd(kpmcli),
kpmcmd.NewPkgCmd(kpmcli),
kpmcmd.NewMetadataCmd(kpmcli),
kpmcmd.NewRunCmd(kpmcli),
kpmcmd.NewLoginCmd(kpmcli),
kpmcmd.NewLogoutCmd(kpmcli),
kpmcmd.NewPushCmd(kpmcli),
kpmcmd.NewPullCmd(kpmcli),
}
app.Flags = []cli.Flag{
&cli.BoolFlag{
Name: kpmcmd.FLAG_QUIET,
Usage: "push in vendor mode",
},
}
app.Before = func(c *cli.Context) error {
if c.Bool(kpmcmd.FLAG_QUIET) {
kpmcli.SetLogWriter(nil)
}
return nil
}
argsWithCmd := []string{cmd}
argsWithCmd = append(argsWithCmd, args...)
return app.Run(argsWithCmd)
}
70 changes: 70 additions & 0 deletions cmd/registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package cmd

import (
"github.com/spf13/cobra"
cli "github.com/urfave/cli/v2"
"kcl-lang.io/cli/pkg/version"
"kcl-lang.io/kpm/pkg/client"
kpmcmd "kcl-lang.io/kpm/pkg/cmd"
"kcl-lang.io/kpm/pkg/reporter"
)

const (
registryDesc = `
This command manages the kcl registry
`
registryExample = ` # Login the registry
kcl registry login docker.io
# Logout the registry
kcl registry logout
`
)

// NewModCmd returns the mod command.
func NewRegistryCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "registry",
Short: "KCL registry management",
Long: registryDesc,
Example: registryExample,
RunE: func(_ *cobra.Command, args []string) error {
return RunWithKpmRegistry("registry", args)
},
SilenceUsage: true,
}

return cmd
}

func RunWithKpmRegistry(cmd string, args []string) error {
reporter.InitReporter()
kpmcli, err := client.NewKpmClient()
if err != nil {
return err
}
app := cli.NewApp()
app.Usage = "registry related functions"
app.Name = "kcl registry"
app.Version = version.GetVersionString()
app.UsageText = "kcl registry <command> [arguments]..."
app.Commands = []*cli.Command{
kpmcmd.NewLoginCmd(kpmcli),
kpmcmd.NewLogoutCmd(kpmcli),
}
app.Flags = []cli.Flag{
&cli.BoolFlag{
Name: kpmcmd.FLAG_QUIET,
Usage: "push in vendor mode",
},
}
app.Before = func(c *cli.Context) error {
if c.Bool(kpmcmd.FLAG_QUIET) {
kpmcli.SetLogWriter(nil)
}
return nil
}
argsWithCmd := []string{cmd}
argsWithCmd = append(argsWithCmd, args...)
return app.Run(argsWithCmd)
}
74 changes: 71 additions & 3 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,31 +67,99 @@
// version Shows the command version
//
// ```
// #### Alias
//
// ```
// alias kcl="kcl run"
// alias kpm="kcl mod"
// ```
package cmd

import (
"fmt"
"os"
"strings"

"github.com/spf13/cobra"
"kcl-lang.io/cli/pkg/plugin"
"kcl-lang.io/cli/pkg/version"
)

const rootDesc = `The KCL Command Line Interface (CLI).
const (
cmdName = "kcl"
rootDesc = `The KCL Command Line Interface (CLI).
KCL is an open-source, constraint-based record and functional language that
enhances the writing of complex configurations, including those for cloud-native
scenarios. The KCL website: https://kcl-lang.io
`
)

// New creates a new cobra client
func New() *cobra.Command {
cmd := &cobra.Command{
Use: "kcl",
Use: cmdName,
Short: "The KCL Command Line Interface (CLI).",
Long: rootDesc,
SilenceUsage: true,
Version: version.GetVersionString(),
}
cmd.AddCommand(NewVersionCmd())
cmd.AddCommand(NewRunCmd())
cmd.SetHelpCommand(&cobra.Command{}) // Disable the help command
cmd.AddCommand(NewModCmd())
cmd.AddCommand(NewRegistryCmd())

bootstrapCmdPlugin(cmd, plugin.NewDefaultPluginHandler([]string{cmdName}))

return cmd
}

func bootstrapCmdPlugin(cmd *cobra.Command, pluginHandler plugin.PluginHandler) {
if pluginHandler == nil {
return
}
if len(os.Args) > 1 {
cmdPathPieces := os.Args[1:]

// only look for suitable extension executables if
// the specified command does not already exist
if foundCmd, _, err := cmd.Find(cmdPathPieces); err != nil {
// Also check the commands that will be added by Cobra.
// These commands are only added once rootCmd.Execute() is called, so we
// need to check them explicitly here.
var cmdName string // first "non-flag" arguments
for _, arg := range cmdPathPieces {
if !strings.HasPrefix(arg, "-") {
cmdName = arg
break
}
}

builtinSubcmdExist := false
for _, subcmd := range foundCmd.Commands() {
if subcmd.Name() == cmdName {
builtinSubcmdExist = true
break
}
}
switch cmdName {
// Don't search for a plugin
case "help", cobra.ShellCompRequestCmd, cobra.ShellCompNoDescRequestCmd:
default:
if !builtinSubcmdExist {
if err := plugin.HandlePluginCommand(pluginHandler, cmdPathPieces, false); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
// Run the run command for the root command. alias kcl="kcl run"
cmd := NewRunCmd()
cmd.SetArgs(cmdPathPieces)
if err := cmd.Execute(); err != nil {
os.Exit(1)
}
os.Exit(0)
}
}
}
}
}
14 changes: 14 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.19
require (
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/spf13/cobra v1.7.0
github.com/urfave/cli/v2 v2.25.0
kcl-lang.io/kcl-go v0.6.1-0.20231023065115-16ee99bd07f7
kcl-lang.io/kcl-openapi v0.5.1
kcl-lang.io/kpm v0.3.7
Expand Down Expand Up @@ -90,28 +91,41 @@ require (
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect
github.com/acomagu/bufpipe v1.0.4 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/cloudflare/circl v1.1.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/fatih/color v1.10.0 // indirect
github.com/go-git/gcfg v1.5.0 // indirect
github.com/go-git/go-billy/v5 v5.4.1 // indirect
github.com/go-git/go-git/v5 v5.6.1 // indirect
github.com/goccy/go-yaml v1.11.0 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/iancoleman/strcase v0.3.0 // indirect
github.com/imdario/mergo v0.3.13 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
github.com/otiai10/copy v1.9.0 // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/qri-io/jsonpointer v0.1.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/skeema/knownhosts v1.1.0 // indirect
github.com/thoas/go-funk v0.9.3 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/tools v0.8.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
oras.land/oras-go v1.2.3 // indirect
oras.land/oras-go/v2 v2.3.0 // indirect
Expand Down
Loading

0 comments on commit a4da757

Please sign in to comment.