Cobra既是一个创建强大的现代CLI应用程序的库,也是一个生成应用程序和命令文件的程序。
Cobra被用于许多Go项目,如Kubernetes、Hugo和Github CLI等等。这个列表包含了一个更广泛的使用Cobra的项目列表。
目录
- 概述
- 概念
- 指令
- 旗帜
- 安装
- 入门
- 使用Cobra生成器
- 使用Cobra库
- 使用Flags
- 位置和自定义参数
- 例子
- 帮助命令
- 使用说明
- 运行前和运行后挂钩
- 发生 "未知命令 "时的建议
- 为您的命令生成文档
- 生成外壳完成
- 贡献
- 许可证
使用Cobra库
要手动实现Cobra,你需要创建一个空的main.go文件和一个rootCmd文件。你还可以根据自己的需要提供其他命令。
创建rootCmd
Cobra不需要任何特殊的构造函数。只需创建你的命令。
理想情况下,你可以把它放在app/cmd/root.go
中。
var rootCmd = &cobra.Command{
Use: "hugo",
Short: "Hugo is a very fast static site generator",
Long: `A Fast and Flexible Static Site Generator built with
love by spf13 and friends in Go.
Complete documentation is available at http://hugo.spf13.com`,
Run: func(cmd *cobra.Command, args []string) {
// Do Stuff Here
},
}
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
你将在 init()函数中额外定义标志和处理配置。
例如 cmd/root.go:
package cmd
import (
"fmt"
"os"
homedir "github.com/mitchellh/go-homedir"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var (
// Used for flags.
cfgFile string
userLicense string
rootCmd = &cobra.Command{
Use: "cobra",
Short: "A generator for Cobra based Applications",
Long: `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.`,
}
)
// Execute executes the root command.
func Execute() error {
return rootCmd.Execute()
}
func init() {
cobra.OnInitialize(initConfig)
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "author name for copyright attribution")
rootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "name of license for the project")
rootCmd.PersistentFlags().Bool("viper", true, "use Viper for configuration")
viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper"))
viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
viper.SetDefault("license", "apache")
rootCmd.AddCommand(addCmd)
rootCmd.AddCommand(initCmd)
}
func er(msg interface{}) {
fmt.Println("Error:", msg)
os.Exit(1)
}
func initConfig() {
if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
} else {
// Find home directory.
home, err := homedir.Dir()
if err != nil {
er(err)
}
// Search config in home directory with name ".cobra" (without extension).
viper.AddConfigPath(home)
viper.SetConfigName(".cobra")
}
viper.AutomaticEnv()
if err := viper.ReadInConfig(); err == nil {
fmt.Println("Using config file:", viper.ConfigFileUsed())
}
}
创建你的main.go
有了root命令,你需要让你的main函数来执行它。为了清楚起见,执行应该在根节点上运行,尽管它可以在任何命令上被调用。
在Cobra应用中,通常main.go文件是非常简单的。它的作用只有一个:初始化Cobra:
package main
import (
"{pathToYourApp}/cmd"
)
func main() {
cmd.Execute()
}
创建其他命令
其他的命令可以被定义,通常每个命令都在 cmd/目录下有自己的文件。
如果你想创建一个版本命令,你可以创建cmd/version.go
,并在其中加入以下内容:
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 Hugo",
Long: `All software has versions. This is Hugo's`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Hugo Static Site Generator v0.9 -- HEAD")
},
}
返回和处理错误
如果你想向命令的调用者返回一个错误,可以使用RunE。
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
func init() {
rootCmd.AddCommand(tryCmd)
}
var tryCmd = &cobra.Command{
Use: "try",
Short: "Try and possibly fail at something",
RunE: func(cmd *cobra.Command, args []string) error {
if err := someFunc(); err != nil {
return err
}
return nil
},
}
然后可以在执行函数调用时捕捉到错误。
使用Flags
Flags提供了修饰符来控制动作命令的操作方式。
将Flags分配给命令
由于Flags的定义和使用位置不同,所以我们需要在外面定义一个具有正确范围(类型)的变量来分配给Flags。
var Verbose bool
var Source string
有两种不同的方法来分配Flags。
持久性的 Flags
一个Flags可以是 "持久化 "的,这意味着这个Flags将对它所分配的命令以及该命令下的每一个命令有效。对于全局Flags,在根目录下将Flags分配为持久性Flags。
rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")
本地标志
也可以在本地分配一个标志,这个标志只适用于该特定的命令。
localCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")