如何使用golang cobra构造子子命令?

问题描述 投票:0回答:1

我是 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

我看过有关堆栈溢出的其他帖子,但没有看到任何清晰的结构或帮助未显示子子命令

go go-cobra
1个回答
0
投票

我注意到,如果您没有为子命令定义 run 函数,它不会显示在帮助中。

我也是眼镜蛇新手,也许有人会有更好的答案,或者更好的例子

这是使一切正常工作的示例代码。

如果您愿意,请查看此repo

/main.go

package main

import "github.com/dev-vinicius-andrade/go-cobra-example/cmd/foo"

func main() {
    foo.CreateCommand().Execute()

}

/cmd/foo/foo.go

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")
}

/cmd/foo/bar/bar.go

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
}


/类型/types.go

package types

type CliContext struct {
    // ...
    GlobalMessage string
    // ...
}

/helpers/cobra.go

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{}

© www.soinside.com 2019 - 2024. All rights reserved.