CLI 应用程序框架 —— Go Cobra 入门

本文通过丰富的代码示例演示了 Cobra 的基本功能,读者可以跟随这些示例,学习如何使用 Cobra

Cobra

Cobra 由以下两部分组成:

  • 用于创建 CLI 应用程序的库(cobra 库)
  • 用于生成 Cobra 应用程序的工具(cobra-cli)

概念

Cobra 建立在命令(command)、参数(arguments)和标志(flags)的结构之上,这三个组件共同定义了命令行应用程序的行为。

  • 命令(Commands)代表着命令行应用程序可以执行的特定操作
  • 参数(Args)是这些操作所针对的实体或项
  • 标志(Flags)是可以修改命令或参数行为的修饰符。

设计良好的命令行应用程序在使用时读起来像句子,其遵循的模式如下:

  • APPNAME VERB NOUN --ADJECTIVE,如:git clone URL --bare
  • APPNAME COMMAND ARG --FLAG,如:hugo server --port=1313

cobra-cli

cobra-cli 是一个命令行工具,用于生成 Cobra 应用程序。我们可以使用命令 go install github.com/spf13/cobra-cli@latest 来安装它。

初始化应用程序

安装完 cobra-cli 后,我们可以在项目根目录下执行命令 cobra-cli init 以初始化我们的 Cobra 应用程序。初始化完成后,我们的项目目录结构如下:

│  go.mod
│  go.sum
│  LICENSE	# cobra-cli 生成的许可证文件
│  main.go	# cobra-cli 生成的程序入口文件
│
└─cmd
        root.go	# cobra-cli 生成的根命令文件

cobra-cli 生成的代码文件具有详细的注释,这里我们就不作讲解。

使用 cobro-cli init 时,我们还可以附加 flag :

cobra-cli init --author="Sue211213@163.com" --license=mit --viper
 
#D:\workspace\golang\src\cobra-demo
  • --author 指定作者,作者信息会显示在文件的版权头信息和 LICENSE 文件中
  • --license 指定许可证,许可证信息会显示在 LICENSE 文件中
  • --viper 使用 viper

添加命令

初始化 Cobra 应用程序后,我们还可以使用 cobra-cli add 命令为我们的应用程序添加其他命令,如:

cobra-cli add serve
cobra-cli add config
cobra-cli add create -p 'configCmd'
  • -p 指定该命令的父级,默认情况下父级命令为 rootCmd

指定 command ,运行程序:

go run main.go serve
#serve called

go run main.go config
#config called

go run main.go config create
#create called

配置文件

我们可以将 flag 写入到配置文件中,然后以读取配置文件的形式使用 flag。

创建配置文件 .cobra.yaml

author: Sue211213 <sue211213@163.com>	# 作者信息
license: MIT							# 许可证信息,可以为 none,也可以自定义
useViper: true							# 启用 viper

使用配置文件进行初始化:

cobra-cli init --config=.cobra.yaml
#Using config file: .cobra.yaml
#Your Cobra application is ready at
#D:\workspace\golang\src\cobra-demo

cobra

使用标志

持久标志

我们可以为某个命令分配持久标志,持久标志能够被该命令及其所有子命令使用。

在下面这个示例中,我们为根命令分配了一个名为 verbose 的持久标志,由于是根命令上的持久标志,所以该标志是一个全局标志,可用于所有命令:

var rootCmd = &cobra.Command{
   
	Use:   "app",
}

var cmdFoo = &cobra.Command{
   
	Use:   "foo",

	Run: func(cmd *cobra.Command, args []string) {
   
		fmt.Println("foo executed")
		if verbose {
   
			fmt.Println("verbose output enabled")
		}
	},
}

var verbose bool

func init() {
   
	rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "enable verbose output")
}

func main() {
   
	rootCmd.AddCommand(cmdFoo)
	
	_ = rootCmd.Execute()
}
go run main.go foo
#foo executed

go run main.go foo -v
#foo executed
#verbose output enabled
本地标志

我们可以为某个命令分配本地标志,本地标志只有该命令能够使用。

在下面这个示例中,我们为子命令 foo 分配了一个本地标志 name,该标志只能由子命令 foo 使用:

var rootCmd = &cobra.Command{
   
	Use:   "app",
}

var cmdFoo = &cobra.Command{
   
	Use:   "foo",

	Run: func(cmd *cobra.Command, args []string) {
   
		name, _ := cmd.Flags().GetString("name")
		fmt.Printf("Hello %s\n", name)
	},
}

func init() {
   
	cmdFoo.Flags().StringP("name", "n", "world", "The name to greet")
}

func main() {
   
	rootCmd.AddCommand(cmdFoo)
    
	_ = rootCmd.Execute()
}
go run main.go -n=sue211213@163.com
#Error: unknown shorthand flag: 'n' in -n=sue211213@163.com
#...

go run main.go foo -n=sue211213@163.com
#Hello sue211213@163.com
将标志与配置绑定

我们可以使用 viper 将我们的标志和配置信息进行绑定。

在下面的这个示例中,我们将 name 标志与环境变量 APP_NAME 进行绑定:

var rootCmd = &cobra.Command{
   
	Use:   "app",

	Run: func(cmd *cobra.Command, args []string) {
   
		name := viper.GetString("name")
		fmt.Printf("Hello, %s\n", name)
	},
}

func init() {
   
	rootCmd.Flags().StringP("name", "n", "world", "the name to greet")
	_ = viper.BindPFlag("name", rootCmd.Flags().Lookup("name"))
	viper.SetEnvPrefix("app")
	viper.AutomaticEnv()
}

func main() {
   
	_ = rootCmd.Execute()
}
APP_NAME=Bob go run main.go
#Hello, Bob
必填标志

我们可以为某个命令设置必填标志。

在下面这个示例中,我们为 app 命令设置了必填标志 name:

var rootCmd = &cobra.Command{
   
	Use:   "app",

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

func init() {
   
	rootCmd.Flags().StringP("name", "n", "World", "The name to greet")
	_ = rootCmd.MarkFlagRequired("name")
}

func main() {
   
	_ = rootCmd.Execute()
}
go run main.go
#Error: required flag(s) "name" not set
#...
标志组

我们可以使用 MarkFlagsRequiredTogether 函数限制某些标志必须一起执行,如:

var rootCmd = &cobra.Command{
   
	Use:   "myapp",
	Short: "A simple command line application",

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

func 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值