golang cobra简要使用介绍

        cobra几乎是每个学习golang的码农必备的技能,简要来说,他是个编写命令行的工具,在大型项目中经常使用cobra来启动服务,接下来直接上代码

root.go

package cmd

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var Verbose bool
var Author string
var Author2 string
var Author3 string
var Test bool

var rootCmd = &cobra.Command{
	Use:   "hugo",
	Short: "Hugo is a very fast static site generator",
	Args:  cobra.NoArgs,

	// NoArgs - the command will report an error if there are any positional args.
	// ArbitraryArgs - the command will accept any args.
	// OnlyValidArgs - the command will report an error if there are any positional args that are not in the ValidArgs field of Command.
	// MinimumNArgs(int) - the command will report an error if there are not at least N positional args.
	// MaximumNArgs(int) - the command will report an error if there are more than N positional args.
	// ExactArgs(int) - the command will report an error if there are not exactly N positional args.
	// ExactValidArgs(int) = the command will report and error if there are not exactly N positional args OR if there are any positional args that are not in the ValidArgs field of Command
	// RangeArgs(min, max) - the command will report an error if the number of args is not between the minimum and maximum number of expected args.
	// Args match a function ,so you can difine your own function
	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) {
		fmt.Println("main root")
		fmt.Println(cmd.Flags().GetString("author"))
		fmt.Println(viper.Get("author"))
		fmt.Println(cmd.Flags().GetBool("test"))
		// Do Stuff Here

	},

	// PersistentPreRun
	// PreRun
	// Run
	// PostRun
	// PersistentPostRun
	/**
		以上key按顺序执行对应的函数,而Persistent代表始终执行,并且对于子命令也一样,如果子命令没有定义Persistent
		的key的话,则执行父命令的Persistent*Run函数。
	**/

}

func Execute() {
	if err := rootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func init() {

	cobra.OnInitialize(initConfig) //这会在运行每个子命令之前运行,后面无法更新viper中初始config的数据
	rootCmd.PersistentFlags().StringVarP(&Author, "author", "a", "defaultAuthor", "作者名")
	rootCmd.PersistentFlags().StringVar(&Author2, "author2", "defaultAuthor2", "作者名2")
	rootCmd.PersistentFlags().String("author3", "defaultAuthor3", "作者名3")
	/**
		方法名带P的则代表可在参数中添加短声明,带有Var的则代表可以将值绑定到变量中
	**/
	viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
	// 将用户输入的author信息绑定到viper缓存中,优先级低于viper本身从配置信息中读取的绑定
	rootCmd.Flags().BoolVarP(&Test, "test", "t", false, "test")
	// PersistentFlags为全局Flag,不带Persistent的为本地Flag
	viper.BindPFlag("author", rootCmd.Flags().Lookup("test"))
	// 绑定局部Flag

	rootCmd.MarkPersistentFlagRequired("author")
	rootCmd.MarkFlagRequired("author2")
	rootCmd.MarkPersistentFlagRequired("author3") // 仅对于全局Flag生效,标记其为必须输入的Flag

	rootCmd.MarkFlagRequired("test") // 仅对于局部Flag生效,标记其为必须输入的Flag
}

func initConfig() {
	viper.AddConfigPath("./")
	viper.AddConfigPath("./conf")
	viper.SetConfigName("config")
	viper.SetConfigType("yaml")
	viper.AutomaticEnv()
	if err := viper.ReadInConfig(); err != nil {
		fmt.Println("Error:", err)
		os.Exit(1)
	}
}

version.go

package cmd

import (
	"fmt"

	"github.com/spf13/cobra"
)

var versionCmd = &cobra.Command{
	Use:              "version",
	Short:            "Print the version number of Hugo",
	TraverseChildren: true,
	// 用途不明
	Long: `All software has versions. This is Hugo's`,
	Args: cobra.MaximumNArgs(5),
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("Hugo Static Site Generator v0.9 -- HEAD")
		fmt.Println(cmd.Flags().GetString("name"))
		fmt.Println(cmd.Flags().GetString("author"))
		fmt.Println(args)
	},
}

func init() {
	rootCmd.AddCommand(versionCmd)
	var Source string
	versionCmd.Flags().StringVarP(&Source, "source", "s", "", "读取文件路径")

	var Name string
	versionCmd.Flags().StringVarP(&Name, "name", "n", "default name", "你的名字")
	// rootCmd.SetArgs([]string{"version", "second-arg", "third-arg"})
	/**
		此命令可以设置全局初始参数,大概用于测试?例如此参数设置后可以直接进入version的子命令并添加两个参数
	**/
}

最后在main.go中执行root.go的Execute函数即可,注意init函数将会在程序执行之前执行来进行初始化,具体请参考另一篇博客关于init函数的介绍,关于viper的使用请参考viper的使用介绍

你可能感兴趣的:(我的golang学习之旅,golang,开发语言,后端)