我是 go 和 cobra 的新手,我一直在关注如何构建命令的文件/文件夹的教程/阅读,但是当我在命令中添加子命令时,我遇到了困难,并希望一些提示
我有这个布局
--cmd
|-cli
|--foo
|--foo.go
|--bar
|--bar.go
这工作得很好(也适用于 go build)
go run .\main.go foo bar
作为参考,foo.go 导入了 bar.go,我将其添加为 foo 的命令,但 bar 没有显示在帮助中:即:
go run .\main.go foo --help
或:go run .\main.go --help
我看过有关堆栈溢出的其他帖子,但没有看到任何清晰的结构或帮助未显示子子命令
我注意到,如果您没有为子命令定义 run 函数,它不会显示在帮助中。
我也是眼镜蛇新手,也许有人会有更好的答案,或者更好的例子
这是使一切正常工作的示例代码。
如果您愿意,请查看此repo
package main
import "github.com/dev-vinicius-andrade/go-cobra-example/cmd/foo"
func main() {
foo.CreateCommand().Execute()
}
package foo
import (
"github.com/dev-vinicius-andrade/go-cobra-example/cmd/foo/bar"
"github.com/dev-vinicius-andrade/go-cobra-example/types"
"github.com/spf13/cobra"
)
type commandDefinition struct {
Context *types.CliContext
ParentCommand *cobra.Command
}
var context = types.CliContext{}
func CreateCommand() *cobra.Command {
c := commandDefinition{}
return c.CreateCommandDefinition()
}
func (c *commandDefinition) CreateCommandDefinition() *cobra.Command {
command := cobra.Command{
Use: "foo",
Short: "Foo is the main command of this tool",
Long: `This is a long description of Foo is the main command of this tool`,
Aliases: []string{},
TraverseChildren: true, // This is important to always run the Run function of the parent command, good for global flags, context, etc
}
defineFlags(&command)
defineSubCommands(&command)
setRunCommand(&command)
return &command
}
func defineSubCommands(cmd *cobra.Command) {
bar.CreateCommand(&context, cmd)
}
func runCommand(cmd *cobra.Command, args []string) {
if len(args) == 0 {
cmd.Help()
return
}
}
func setRunCommand(command *cobra.Command) {
command.Run = runCommand
}
func defineFlags(command *cobra.Command) {
command.PersistentFlags().StringVarP(&context.GlobalMessage, "message", "m", "Default Global Message", "Global message to be used in all commands")
}
package bar
import (
"fmt"
"github.com/dev-vinicius-andrade/go-cobra-example/helpers"
"github.com/dev-vinicius-andrade/go-cobra-example/types"
"github.com/spf13/cobra"
)
type commandDefinition struct {
Context *types.CliContext
ParentCommand *cobra.Command
}
func CreateCommand(context *types.CliContext, parentCommand *cobra.Command) (*cobra.Command, error) {
command := commandDefinition{
Context: context,
ParentCommand: parentCommand,
}
return command.createCommandDefinition(context, parentCommand), nil
}
func (c *commandDefinition) createCommandDefinition(context *types.CliContext, parentCommand *cobra.Command) *cobra.Command {
command := cobra.Command{
Use: "bar",
Short: "Bar is subcommand of foo",
Long: `This is a long description of Bar is a subcommand of foo`,
Aliases: []string{},
TraverseChildren: true,
}
defineFlags(&command)
defineSubCommands(&command)
setRunCommand(context, &command)
helpers.CobraHelper.AddCommandToParent(&command, parentCommand)
return &command
}
func defineSubCommands(cmd *cobra.Command) {
//define your subcommands here
}
func runCommand(context *types.CliContext, cmd *cobra.Command, args []string) {
fmt.Printf("%s\n", context.GlobalMessage)
}
func setRunCommand(context *types.CliContext, command *cobra.Command) {
command.Run = func(cmd *cobra.Command, args []string) {
runCommand(context, cmd, args)
}
}
func defineFlags(command *cobra.Command) {
//define your flags of your subcommand here
}
package types
type CliContext struct {
// ...
GlobalMessage string
// ...
}
package helpers
import "github.com/spf13/cobra"
type cobraHelper struct{}
func (c *cobraHelper) AddCommandToParent(command *cobra.Command, parentCommand *cobra.Command) {
if parentCommand == nil {
return
} else {
parentCommand.AddCommand(command)
}
}
var CobraHelper = cobraHelper{}