Skip to content

Instantly share code, notes, and snippets.

@akkuman
Created December 11, 2023 09:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akkuman/7383580f6df4c3f340da616fe1721ad0 to your computer and use it in GitHub Desktop.
Save akkuman/7383580f6df4c3f340da616fe1721ad0 to your computer and use it in GitHub Desktop.
cobra 根据所给得某个参数动态添加参数
package cmd
import (
"context"
"expgo/pkg/errs"
"expgo/plugins"
"expgo/plugins/api/types"
"expgo/processor"
"fmt"
"os"
"github.com/spf13/cast"
"github.com/spf13/cobra"
)
func printHelpAndExit(cmd *cobra.Command, err error) {
if err != nil {
fmt.Println(err)
}
cmd.Help()
fmt.Println()
os.Exit(0)
}
var execCmd = &cobra.Command{
Use: "exec",
Short: "运行插件",
Long: `使用所给的参数运行插件`,
DisableFlagParsing: true,
Run: func(cmd *cobra.Command, args []string) {
// 让用户指定插件
pluginPath := cmd.Flags().StringP("plugin", "p", "", "使用的插件路径")
// set flag back
cmd.DisableFlagParsing = false
cmd.ParseFlags(args)
if *pluginPath == "" {
printHelpAndExit(cmd, nil)
}
// 解析插件获取参数
pluginData, err := os.ReadFile(*pluginPath)
if err != nil {
printHelpAndExit(cmd, err)
}
pluginSrc := string(pluginData)
info, err := processor.GetEXPInfo(pluginSrc)
if err != nil {
printHelpAndExit(cmd, err)
}
for _, argDetail := range info.Opts {
if argDetail.Type == types.IntOptType || argDetail.Type == types.IntChoicesOptType {
cmd.Flags().Int(argDetail.Name, argDetail.Default.(int), argDetail.Desc)
} else if argDetail.Type == types.StringOptType || argDetail.Type == types.StringChoicesOptType {
cmd.Flags().String(argDetail.Name, argDetail.Default.(string), argDetail.Desc)
} else if argDetail.Type == types.BoolOptType {
cmd.Flags().Bool(argDetail.Name, argDetail.Default.(bool), argDetail.Desc)
}
cmd.MarkFlagRequired(argDetail.Name)
}
err = cmd.ParseFlags(args)
if err != nil {
printHelpAndExit(cmd, err)
}
if cmd.Flag("help").Value.String() == "true" ||
len(args) == 0 ||
(len(args) == 2 && cmd.Flag("plugin").Value.String() != "") {
printHelpAndExit(cmd, nil)
}
expOptValues := make(map[string]interface{})
for _, argDetail := range info.Opts {
v := cmd.Flag(argDetail.Name).Value.String()
if argDetail.Type == types.IntOptType || argDetail.Type == types.IntChoicesOptType {
expOptValues[argDetail.Name] = cast.ToInt(v)
} else if argDetail.Type == types.StringOptType || argDetail.Type == types.StringChoicesOptType {
expOptValues[argDetail.Name] = v
} else if argDetail.Type == types.BoolOptType {
expOptValues[argDetail.Name] = cast.ToBool(v)
}
}
node, err := plugins.CompileSrcToAST(pluginSrc)
if err != nil {
fmt.Printf("%s: %v\n", errs.CodeErrParseAST.String(), err)
os.Exit(1)
}
pExcutor, err := plugins.NewPluginExecutor(node)
if err != nil {
fmt.Printf("%s: %v\n", errs.CodeErrNewPluginExecutor.String(), err)
os.Exit(1)
}
_, err = pExcutor.Run(context.Background(), expOptValues)
if err != nil {
fmt.Printf("%s: %v\n", errs.CodeErrPluginExec.String(), err)
os.Exit(1)
}
},
}
func init() {
rootCmd.AddCommand(execCmd)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment