细细观看cockroachDB
的初始化流程,绕不过去的就是cockroachDB
中使用的一个叫做cobra
的模块。本文就是要简单梳理一下cobra
模块,若是使用golang
进行开发,很可能会用上这个模块作为命令的处理模块。
cobra
是什么
cobra
是基于golang
的客户端接口工具。为实现客户端准备的。
cobra
被使用之后是什么样的
以 cockroachDB
为例,命令最终的效果就是:
./cockroach start --insecure --host=localhost
./cockroach sql --insecure
cockroach
是这个客户端的名称.
start
/ sql
是这个客户端需要执行的命令
--option[=value]
这些都是给start
命令传递的参数
cobra
的好处
现代客户端命令的很好的框架,现代的客户命令端框架一般就是这种形式的,比如git, go。
git clone url
go get url
appname command --option[=value]
安装方法
go get -u github.com/spf13/cobra/cobra
使用方法
- 在你的代码中引入这个模块
import "github.com/spf13/cobra"
- 以下下内容有部分翻译自官网。
文件的组织形式官方推荐是:
▾ appName/
▾ cmd/
add.go
your.go
commands.go
here.go
main.go
在main.go中, 使用如下代码
package main
import (
"fmt"
"os"
"{pathToYourApp}/cmd"
)
func main() {
cmd.Execute()
}
创建一个root的命令,可以将它放到app/cmd/root.go, 命令的格式是:
yourapp Hugo
代码如下:
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
},
}
下面代码就是剩余部分的app/cmd/root.go, 可以添加一些选项以及配置文件的初始化读取操作。
import (
"fmt"
"os"
homedir "github.com/mitchellh/go-homedir"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
func init() {
cobra.OnInitialize(initConfig)
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
rootCmd.PersistentFlags().StringVarP(&projectBase, "projectbase", "b", "", "base project directory eg. github.com/spf13/")
rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "Author name for copyright attribution")
rootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "Name of license for the project (can provide `licensetext` in config)")
rootCmd.PersistentFlags().Bool("viper", true, "Use Viper for configuration")
viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
viper.BindPFlag("projectbase", rootCmd.PersistentFlags().Lookup("projectbase"))
viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper"))
viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
viper.SetDefault("license", "apache")
}
func initConfig() {
// Don't forget to read config either from cfgFile or from home directory!
if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
} else {
// Find home directory.
home, err := homedir.Dir()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// Search config in home directory with name ".cobra" (without extension).
viper.AddConfigPath(home)
viper.SetConfigName(".cobra")
}
if err := viper.ReadInConfig(); err != nil {
fmt.Println("Can't read config:", err)
os.Exit(1)
}
}
最后的简单例子
package main
import (
"fmt"
"strings"
"github.com/spf13/cobra"
)
func main() {
var echoTimes int
var cmdPrint = &cobra.Command{
Use: "print [string to print]",
Short: "Print anything to the screen",
Long: `print is for printing anything back to the screen.
For many years people have printed back to the screen.`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Print: " + strings.Join(args, " "))
},
}
var cmdEcho = &cobra.Command{
Use: "echo [string to echo]",
Short: "Echo anything to the screen",
Long: `echo is for echoing anything back.
Echo works a lot like print, except it has a child command.`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Print: " + strings.Join(args, " "))
},
}
var cmdTimes = &cobra.Command{
Use: "times [# 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 a string.`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
for i := 0; i < echoTimes; i++ {
fmt.Println("Echo: " + strings.Join(args, " "))
}
},
}
cmdTimes.Flags().IntVarP(&echoTimes, "times", "t", 1, "times to echo the input")
var rootCmd = &cobra.Command{Use: "app"}
rootCmd.AddCommand(cmdPrint, cmdEcho)
cmdEcho.AddCommand(cmdTimes)
rootCmd.Execute()
}
这个例子有助于理解cobra。
看官方文档,是一个好习惯。
更多更加详细的说明请参考:
https://github.com/spf13/cobra/blob/master/README.md