Cobra简介

Cobra简介

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")
上一篇:KVM虚拟机网卡配置管理


下一篇:iOS VIPER 框架的应用实践