cobra mysql_Go学习笔记 : cobra 包简介

本文介绍如何使用Go语言的Cobra库构建命令行工具。Cobra简化了子命令、参数及选项的管理,并提供了帮助信息、智能建议等功能。

cobra 是 go 语言的一个库,可以用于编写命令行工具。通常我们可以看到git pull 、docker container start 、apt install 等等这样命令,都可以很容易用corba来实现,另外,go 语言是很容易编译成一个二进制文件,本文将实现一个简单的命令行工具。

主要功能

cobra 的主要功能如下,可以说每一项都很实用:

简易的子命令行模式,如 app server, app fetch 等等

完全兼容 posix 命令行模式

嵌套子命令 subcommand

支持全局,局部,串联 flags

使用 cobra 很容易的生成应用程序和命令,使用 cobra create appname 和 cobra add cmdname

如果命令输入错误,将提供智能建议,如 app srver,将提示 srver 没有,是不是 app server

自动生成 commands 和 flags 的帮助信息

自动生成详细的 help 信息,如 app help

自动识别帮助 flag -h,--help

自动生成应用程序在 bash 下命令自动完成功能

自动生成应用程序的 man 手册

命令行别名

自定义 help 和 usage 信息

可选的与 viper apps 的紧密集成

cobra 中的主要概念

cobra 中有个重要的概念,分别是 commands、arguments 和 flags。其中 commands 代表行为,arguments 就是命令行参数(或者称为位置参数),flags 代表对行为的改变(也就是我们常说的命令行选项)。执行命令行程序时的一般格式为:

APPNAME COMMAND ARG --FLAG

比如下面的例子:

# server是 commands,port 是 flag

hugo server--port=1313# clone 是 commands,URL 是 arguments,brae 是 flag

git clone URL--bare

如果是一个简单的程序(功能单一的程序),使用 commands 的方式可能会很啰嗦,但是像 git、docker 等应用,把这些本就很复杂的功能划分为子命令的形式,会方便使用(对程序的设计者来说又何尝不是如此)。

创建 cobra 应用

在创建 cobra 应用前需要先安装 cobra 包:    go get -u github.com/spf13/cobra/cobra

然后就可以用 cobra 程序生成应用程序框架了:   cobra init --pkg-name cobrademo  [在cobrademo目录下执行]

af1fe485bbb854fd61215a69b253e150.png

使用 cobra 程序生成命令代码

除了生成应用程序框架,还可以通过 cobra add 命令生成子命令的代码文件,比如下面的命令会添加两个子命令 image 和 container 相关的代码文件:  cobra add image 和 cobra add container

60ba64f62c25e0da027b785376c4f1f6.png

这两条命令分别生成了 cobrademo 程序中 image 和 container 子命令的代码,当然了,具体的功能还得靠我们自己实现。

为命令添加具体的功能

到目前为止,我们一共为 cobrademo 程序添加了三个 Command,分别是 rootCmd(cobra init 命令默认生成)、imageCmd 和 containerCmd。

打开文件 root.go ,找到变量 rootCmd 的初始化过程并为之设置 Run 方法:

Run: func(cmd *cobra.Command, args []string) {

fmt.Println("cobra demo program")

},

重新编译 cobrademo 程序并不带参数运行【初次要执行 go mod init】,这次就不再输出帮助信息了,而是执行了 rootCmd 的 Run 方法:

D:\Project\GoProject\src\cobrademo>go build -o .

D:\Project\GoProject\src\cobrademo>cobrademo.exe

cobra demo program

再创建一个 version Command 用来输出当前的软件版本。先在 cmd 目录下添加 version.go 文件[ cobra add version],编辑文件的内容如下:

package cmd

import ("fmt"

"github.com/spf13/cobra")

func init() {

rootCmd.AddCommand(versionCmd)

}var versionCmd = &cobra.Command{

Use:"version",

Short:"Print the version number of cobrademo",

Long: `All software has versions. Thisis cobrademo's`,

Run: func(cmd *cobra.Command, args []string) {

fmt.Println("cobrademo version is v1.0")

},

}

D:\Project\GoProject\src\cobrademo>go run main.go version

cobrademo versionis v1.0

为 Command 添加选项(flags)

选项(flags)用来控制 Command 的具体行为。根据选项的作用范围,可以把选项分为两类:

persistent

local

对于 persistent 类型的选项,既可以设置给该 Command,又可以设置给该 Command 的子 Command。对于一些全局性的选项,比较适合设置为 persistent 类型,比如控制输出的 verbose 选项:

var Verbose boolrootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")

local 类型的选项只能设置给指定的 Command,比如下面定义的 source 选项:

var Source stringrootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")

该选项不能指定给 rootCmd 之外的其它 Command。

默认情况下的选项都是可选的,但一些用例要求用户必须设置某些选项,这种情况 cobra 也是支持的,通过 Command 的 MarkFlagRequired 方法标记该选项即可:

var Name stringrootCmd.Flags().StringVarP(&Name, "name", "n", "", "user name (required)")

rootCmd.MarkFlagRequired("name")

命令行参数(arguments)

首先我们来搞清楚命令行参数(arguments)与命令行选项的区别(flags/options)。以常见的 ls 命令来说,其命令行的格式为:

ls [OPTION]... [FILE]…

其中的 OPTION 对应本文中介绍的 flags,以 - 或 -- 开头;而 FILE 则被称为参数(arguments)或位置参数。一般的规则是参数在所有选项的后面,上面的 … 表示可以指定多个选项和多个参数。

cobra 默认提供了一些验证方法:

NoArgs - 如果存在任何位置参数,该命令将报错

ArbitraryArgs - 该命令会接受任何位置参数

OnlyValidArgs - 如果有任何位置参数不在命令的 ValidArgs 字段中,该命令将报错

MinimumNArgs(int) - 至少要有 N 个位置参数,否则报错

MaximumNArgs(int) - 如果位置参数超过 N 个将报错

ExactArgs(int) - 必须有 N 个位置参数,否则报错

ExactValidArgs(int) 必须有 N 个位置参数,且都在命令的 ValidArgs 字段中,否则报错

RangeArgs(min, max) - 如果位置参数的个数不在区间 min 和 max 之中,报错

一个完整的 demo

我们在前面创建的代码的基础上,为 image 命令添加行为(打印信息到控制台),并为它添加一个子命令 cmdTimes,下面是更新后的 image.go 文件的内容:

package cmd

import ("fmt"

"strings"

"github.com/spf13/cobra")//imageCmd represents the image command

var imageCmd = &cobra.Command{

Use:"image",

Short:"Print images information",

Long:"Print all images information",

Run: func(cmd*cobra.Command, args []string) {

fmt.Println("image one is win7")

fmt.Println("image two is win10")

fmt.Println("image args are :" + strings.Join(args, " "))

},

}var echoTimes int

var cmdTimes = &cobra.Command{

Use:"times [string to echo]",

Short:"Echo anything to the screen more times",

Long: `echo things multiple times back to the user by providing a count and astring.`,

Args: cobra.MinimumNArgs(1),

Run: func(cmd*cobra.Command, args []string) {for i := 0; i < echoTimes; i++{

fmt.Println("Echo:" + strings.Join(args, " "))

}

},

}

func init() {

rootCmd.AddCommand(imageCmd)

cmdTimes.Flags().IntVarP(&echoTimes, "times", "t", 1, "times to echo the input")

imageCmd.AddCommand(cmdTimes)

}

编译后执行命令:

D:\Project\GoProject\src\cobrademo>go run main.go image hello

image oneiswin7

image twoiswin10

image args are : hello

D:\Project\GoProject\src\cobrademo>go run main.go image times -t=3world

Echo: world

Echo: world

Echo: world

D:\Project\GoProject\src\cobrademo>go run main.go image times -t=3Error: requires at least1 arg(s), only received 0Usage:

cobrademo image times [stringto echo] [flags]

Flags:-h, --help help fortimes-t, --times int times to echo the input (default 1)

Global Flags:--config string config file (default is $HOME/.cobrademo.yaml)

requires at least1 arg(s), only received 0exit status1D:\Project\GoProject\src\cobrademo>

因为我们为 cmdTimes 命令设置了 Args: cobra.MinimumNArgs(1),所以必须为 times 子命令传入一个参数,不然 times 子命令会报错:

帮助信息(help command)

cobra 会自动添加 --help(-h)选项,所以我们可以不必添加该选项而直接使用:

D:\Project\GoProject\src\cobrademo>go run main.go -h

A longer description that spans multiple lines and likely contains

examples and usage ofusingyour application. For example:

Cobrais a CLI library forGo that empowers applications.

This applicationisa tool to generate the needed files

to quickly create a Cobra application.

Usage:

cobrademo [flags]

cobrademo [command]

Available Commands:

container A brief description of your command

help Help about any command

image Print images information

version Print the version number of cobrademo

Flags:--config string config file (default is $HOME/.cobrademo.yaml)-h, --help help forcobrademo-t, --toggle Help message fortoggle

Use"cobrademo [command] --help" for more information about a command.

cobra 同时还自动添加了 help 子命,默认效果和使用 --help 选项相同。如果为 help 命令传递其它命令作为参数,则会显示对应命令的帮助信息,下面的命令输出 image 子命令的帮助信息:

D:\Project\GoProject\src\cobrademo>go run main.go help image

Print all images information

Usage:

cobrademo image [flags]

cobrademo image [command]

Available Commands:

times Echo anything to the screen more times

Flags:-h, --help help forimage

Global Flags:--config string config file (default is $HOME/.cobrademo.yaml)

Use"cobrademo image [command] --help" for more information about a command.

当然也可以通过这种方式查看子命令的子命令的帮助文档:go run main.go help image times

除了 cobra 默认的帮助命令,我们还可以通过下面的方式进行自定义:

cmd.SetHelpCommand(cmd *Command)

cmd.SetHelpFunc(f func(*Command, []string))

cmd.SetHelpTemplate(sstring)

提示信息(usage message)

提示信息和帮助信息很相似,只不过它是在你输入了非法的参数、选项或命令时才出现的,和帮助信息一样,我们也可以通过下面的方式自定义提示信息:

cmd.SetUsageFunc(f func(*Command) error)

cmd.SetUsageTemplate(sstring)

在 Commnad 执行前后执行额外的操作

Command 执行的操作是通过 Command.Run 方法实现的,为了支持我们在 Run 方法执行的前后执行一些其它的操作,Command 还提供了额外的几个方法,它们的执行顺序如下:

1. PersistentPreRun

2. PreRun

3. Run

4. PostRun

5. PersistentPostRun

修改 rootCmd 的初始化代码如下:

var rootCmd = &cobra.Command{

Use:"cobrademo",

Short:"sparkdev's cobra demo",

Long:"the demo show how to use cobra package",

PersistentPreRun: func(cmd*cobra.Command, args []string) {

fmt.Printf("Inside rootCmd PersistentPreRun with args: %v\n", args)

},

PreRun: func(cmd*cobra.Command, args []string) {

fmt.Printf("Inside rootCmd PreRun with args: %v\n", args)

},

Run: func(cmd*cobra.Command, args []string) {

fmt.Printf("cobra demo program, with args: %v\n", args)

},

PostRun: func(cmd*cobra.Command, args []string) {

fmt.Printf("Inside rootCmd PostRun with args: %v\n", args)

},

PersistentPostRun: func(cmd*cobra.Command, args []string) {

fmt.Printf("Inside rootCmd PersistentPostRun with args: %v\n", args)

},

}

重新编译 cobrademo 程序并执行,输出结果中可以看到这些方法的执行顺序

D:\Project\GoProject\src\cobrademo>go run main.go

Inside rootCmd PersistentPreRun with args: []

Inside rootCmd PreRun with args: []

cobra demo program, with args: []

Inside rootCmd PostRun with args: []

Inside rootCmd PersistentPostRun with args: []

D:\Project\GoProject\src\cobrademo>go run main.go image hello

Inside rootCmd PersistentPreRun with args: [hello]

image oneiswin7

image twoiswin10

image args are : hello

Inside rootCmd PersistentPostRun with args: [hello]

D:\Project\GoProject\src\cobrademo>

其中的 PersistentPreRun 方法和 PersistentPostRun 方法会伴随任何子命令的执行:

对未知命令的提示

如果我们输入了不正确的命令或者是选项,cobra 还会智能的给出提示,对于这样的提示我们也是可以自定义的,或者如果觉着没用就直接关闭掉。

参考:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值