了解 Cobra包,使用 cobra 命令行生成一个简单的带子命令的命令行程序。模仿 cobra.Command 编写一个 myCobra 库。
了解 Cobra包,使用 cobra 命令行生成一个简单的带子命令的命令行程序。
首先了解一下cobra的作用
Cobra is a library providing a simple interface to create powerful modern CLI interfaces similar to git & go tools.
Cobra is also an application that will generate your application scaffolding to rapidly develop a Cobra-based application.
参考官方文档https://github.com/spf13/cobra/blob/master/cobra/README.md
准备工作
安装cobra执行文件(值得一提,不能直接在apt上面下载。并不能使用,没有--pkg-name 参数)
![]()
由于墙的原因,官网上的cobra 文件不能下载,产生报错

解决:先执行下列代码

参考了https://blog.csdn.net/u013256816/article/details/99619335,表示感谢
再安装cobra

这样还是不能用,所以我执行了
sudo apt install cobra
就可以使用了
但是,注意不可以直接install cobra。不然执行go run main.go时会发生报错。找不到xxx/cmd文件。
步骤1:
先在
创建文件夹cobraPractice
命令 makedir cobraPractice
步骤二
初始化

步骤三
创建命令行 执行文件

步骤四
简单运行程序

接下来实现自己的简单的cobra
package myCobra
import (
"fmt"
"os"
flag "github.com/spf13/pflag"
"strings"
)
var (
)
//command struct have all information about a comand
type Command struct {
Use string
Short string
Long string
Run func(cmd *Command, args []string)
commands []*Command
choose *Command // sub command at run time
parent *Command
args []string
pflags *flag.FlagSet
}
//add new subCommand to rootCommand
func (c *Command) AddCommand(sub *Command) {
for _, v := range c.commands {
if v == sub {
return
}
}
c.commands = append(c.commands, sub)
sub.parent = c
}
//before execute a command
func (c *Command) Execute() error {
if c == nil {
return fmt.Errorf("Called Execute() on a nil Command")
}
if c .parent == nil { // root Command
ParseArgs(c, os.Args[1:])
}
c.execute()
return nil
}
//execute a command or execute its subCommand
func (c *Command) execute() {
if c.choose == nil {
c.Run(c, c.args)
return
}
c.choose.execute()
}
//retrieve and store all the args for every command
func ParseArgs(c *Command, args []string) {
//fmt.Printf("%v", args)
if len(args) < 1 {
return
}
for _, v := range c.commands {
if v.Use == args[0] { //there is any sub command fit
c.args = args[:1]
c.choose = v
ParseArgs(v, args[1:])
return
}
}
c.args = args // there is no sub command, then all args belong to current command
c.PersistentFlags().Parse(c.args)
}
func (c *Command) PersistentFlags() *flag.FlagSet {
if c.pflags == nil {
c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
}
return c.pflags
}
// Name returns the command's name: the first word in the use line.
func (c *Command) Name() string {
name := c.Use
i := strings.Index(name, " ")
if i >= 0 {
name = name[:i]
}
return name
}
代码解析:
此实现比较简单,例如go run main.go printTxt hello中
root是printTxt的父命令、printTxt是hello的父命令,而且此命令只会执行hello.go
如果有参数的话,也是只能由hello(即没有子命令的命令,拥有参数)
func (c *Command) PersistentFlags() *flag.FlagSet {
if c.pflags == nil {
c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
}
return c.pflags
}
// Name returns the command's name: the first word in the use line.
func (c *Command) Name() string {
name := c.Use
i := strings.Index(name, " ")
if i >= 0 {
name = name[:i]
}
return name
}
上面的函数,就是给命令加上pflag解析参数的功能
功能使用:
例如
package cmd
import (
"fmt"
//"github.com/spf13/cobra"
cobra "github.com/wood666/myCobra"
)
var help bool
// printTxtCmd represents the printTxt command
var printTxtCmd = &cobra.Command{
Use: "printTxt",
Short: "A brief description of your command",
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
Run: func(cmd *cobra.Command, args []string) {
if (help) {
fmt.Printf("sorry, We can't give you any help, this is a fake CLI\n")
}
},
}
func init() {
help = true;
rootCmd.AddCommand(printTxtCmd)
printTxtCmd.PersistentFlags().BoolVarP(&help, "h", "h", false, "maybe it can give you some help!!!")
}
在子命令中,调用参数-h

因此运行成功
命令生成API,请参考我的上一篇博客
具体代码请参考我的giteehttps://gitee.com/woodx9/go/tree/master/cobra

浙公网安备 33010602011771号