spf13/cobra
一、介绍
cobra是一个命令行程序库,其提供简单的接口来创建强大现代的CLI接口,可以用来编写命令行程序。同时,它也提供了一个脚手架, 用于生成基于 cobra 的应用程序框架。
Softool.CN Notes:
CLI 是 Command Line Interface 的缩写,即命令行界面。
命令行界面要较图形用户界面节约计算机系统的资源。在熟记命令的前提下,可以使用命令行界面往往要较使用图形用户界面的操作速度要快。
二、概念
Cobra基于三个基本概念 commands, arguments 和 flags。
commands 代表行为
arguments 代表数值
flags 代表对行为的改变。
基本模型如下:
#格式一:
APPNAME VERB NOUN --ADJECTIVE
#格式二:(常用)
# COMMAND 可以忽略
# ARG 可以忽略
# FLAG 可以忽略
# VALUE 可以忽略
APPNAME COMMAND ARG --FLAG=VALUE
以 格式二 为例,看看下面2个例子:
# 此处没有 arguments ,说明了其可以忽略
# server是commands,port是flag
hugo server --port=1313
# clone是commands,URL是arguments,brae是flags
git clone URL --bare
Commands
Commands是应用的中心点,同样commands可以有子命令(children commands),其分别包含不同的行为。
Commands的结构体如下:
type Command struct {
Use string //当前命令的名称 name
Short string //当前命令的简短描述
Long string //当前命令的完整描述
Run func(cmd *Command, args []string) // Run属性是一个函数,当前命令执行时会默认调用此函数
}
Arguments
Leagacy arg validation有以下几类:
- NoArgs: 如果包含任何位置参数,命令报错
- ArbitraryArgs: 命令接受任何参数
- OnlyValidArgs: 如果有位置参数不在ValidArgs中,命令报错
- MinimumArgs(init): 如果参数数目少于N个后,命令行报错
- MaximumArgs(init): 如果参数数目多余N个后,命令行报错
- ExactArgs(init): 如果参数数目不是N个话,命令行报错
- RangeArgs(min, max): 如果参数数目不在范围(min, max)中,命令行报错
如: 命令行参数不少于1个
var helloCmd = &cobra.Command {
Use: "hello",
Short: "hello 子命令.",
Long: "这是一个Hello 子命令",
Args: cobra.MinimumNArgs(1),
Run: runHello,
}
自字义Arguments判断
var cmd = &cobra.Command{
Use: "hello",
Short: "hello",
Args: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return errors.New("requires at least one arg")
}
if myapp.IsValidColor(args[0]) {
return nil
}
return fmt.Errorf("invalid color specified: %s", args[0])
},
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Hello, World!")
},
}
Flags
Flags用来改变commands的行为。其完全支持POSIX命令行模式和Go的flag包。这里的flag使用的是spf13/pflag包,具体可以参考Golang之使用Flag和Pflag.
cobra 中选项分为Flags,一种是永久选项,定义它的命令和其子命令都可以使用。通过给根命令添加一个选项定义全局选项。 另一种是本地选项,只能在定义它的命令中使用。
与flag一样,存储选项的变量也需要提前定义好:
var Verbose bool
var Source string
设置永久Flags:
rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")
设置本地Flags:
localCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
三、快速使用
安装
go get github.com/spf13/cobra/cobra
导入
import "github.com/spf13/cobra"
新建 cjapp 目录,文件结构如下:
▾ cjapp/
▾ cmd/
hello.go
root.go
version.go
go.mod
main.go
go.mod
module zngw
go 1.14
require github.com/spf13/cobra v1.2.1
root.go
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
var rootCmd = &cobra.Command {
Use: "zngw",
Short: "这是 cobra 测试程序主入口",
Long: `这是 cobra 测试程序主入口, 无参数启动时进入`,
Run: runRoot,
}
func Execute() {
if err := rootCmd.Execute(); err != nil {
panic(err)
}
}
func runRoot(cmd *cobra.Command, args []string) {
fmt.Printf("execute %s args:%v \n", cmd.Name(), args)
// TODO 这里处理无参数启动时程序处理
}
hello.go
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
var helloCmd = &cobra.Command {
Use: "hello",
Short: "hello 子命令.",
Long: "这是一个Hello 子命令",
Args: cobra.MinimumNArgs(1),
Run: runHello,
}
func init() {
rootCmd.AddCommand(helloCmd)
}
func runHello(cmd *cobra.Command, args []string) {
// TODO 这里处理hello子命令
fmt.Println("Hello ", args[0])
}
version.go
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
var versionCmd = &cobra.Command {
Use: "version",
Short: "version 子命令.",
Long: "这是一个version 子命令",
Run: runVersion,
}
func init() {
rootCmd.AddCommand(versionCmd)
}
func runVersion(cmd *cobra.Command, args []string) {
// TODO 这里处理version子命令
fmt.Println("version is 1.0.0")
}
main.go
package main
import (
"zngw/cmd"
)
func main() {
cmd.Execute()
}
测试
进入工程目录,直接使用go build编译,编译后的可执行程序为zngw.exe
自带-h参数,生成帮助信息
E:\55\cobra>zngw -h
这是 cobra 测试程序主入口, 无参数启动时进入
Usage:
zngw [flags]
zngw [command]
Available Commands:
completion generate the autocompletion script for the specified shell
hello hello 子命令.
help Help about any command
version version 子命令.
Flags:
-h, --help help for zngw
Use "zngw [command] --help" for more information about a command.
测试子命令
E:\55\zngw>zngw
execute zngw args:[]
E:\55\zngw>zngw hello guoke
Hello guoke
E:\55\zngw>zngw version
version is 1.0.0
验证:
因作者没有提供完整的包,所以我根据上面的内容重现了一下,但是完全按照上面的内容遇到了一些小问题,我根据自己的情况修改后测试通过。
我把我测试的包放在附件。
先编译:
go build
测试效果图:
作者:岑吾
链接:https://o-my-chenjian.com/2017/09/20/Using-Cobra-With-Golang/
状态:已整理