Taught you develop as a docker command line

Foreword

Cobra is a powerful command line program used to build a library of many popular Go project are using it to build, such as Kubernetes, Docker, etcd, Istio, Github CLI and so on.

Next, develop a demo of our own command-line program chenqionghe, imitate what docker command line, is expected to function as follows

# 查看帮助
chenqiong -h 
# 查看版本,类似docker version
chenqionghe version 
# 查看hello命令帮助,类似docker ps -h
chenqionghe hello -h 
# 使用hello命令,类似docker run --name app --volume /app/data
chenqionghe hello --name light-weight-baby --author gym 

Cobra is based on three basic concepts

  • commands (behavior)
  • arguments (position parameter)
  • flags (command line option)

The basic pattern is used APPNAME VERB NOUN --ADJECTIVE or APPNAME COMMAND ARG --FLAG, e.g.

# server是一个command,--port=1313是一个命令行选项
hugo server --port=1313
#  clone 是 commands,URL 是 arguments,brae是命令行选项
git clone URL --bare

First, install

go get -u github.com/spf13/cobra/cobra
go install github.com/spf13/cobra/cobra

Second, the application initialization

gomod initialization

Here my application called chenqionghe

go mod init chenqionghe

Creating entry file cmd / root.go

Create a basic file folders cmd, and creates the file cmd / root.go, which is used to put all the commands

package cmd
import (
	"fmt"
	"github.com/spf13/cobra"
	"os"
)
var rootCmd = &cobra.Command{
	Use:   "chenqionghe",
	Short: "getting muscle is not easy",
	Long: `let's do it, yeah buddy light weight baby!`,
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("hello chenqionghe")
	},
}
func Execute() {
	if err := rootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

Creating the main program main.go

package main

import "chenqionghe/cmd"

func main() {
	cmd.Execute()
}

Running about main.go can see into force

Third, generate Command

Creating hello subcommand

cobra add hello

Will generate a hello.cmd command under cmd, generated command is so long below, the core is called AddCommand method

We get rid of useless information, the streamlined as follows

package cmd

import (
	"fmt"
	"github.com/spf13/cobra"
)
var helloCmd = &cobra.Command{
	Use:   "hello",
	Short: "hello命令简介",
	Long:  `hello命令详细介绍`,
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("hello called")
	},
	TraverseChildren: true,
}

func init() {
	rootCmd.AddCommand(helloCmd)
}

Run directly look

go run main.go hello

Create a version subcommand

Similarly, we create another version command

cobra add version

Modify the Run method

Run: func(cmd *cobra.Command, args []string) {
   fmt.Println("chenqionghe version v0.0.1")
},

Run the following

Fourth, how to set the flag option

flag options are grouped into two categories according to persistent and local scope

Global Options

Global options are persistent, the corresponding method is PersistentFlags, may be assigned to all the sub-command in the command and the command, and the above rootCmd can call flag is helloCmd
e.g., adding a -v option

func init() {
	var Verbose bool
	rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "全局版本")
}

Running, you can see into force

Local Options

local local option, the corresponding method Flags, only take effect for the specified Command, init inside we went hello command to add a local flag

func init() {
	rootCmd.AddCommand(helloCmd)
	//本地flag
	var Source string
	helloCmd.Flags().StringVarP(&Source, "source", "s", "", "读取文件路径")
}

Run the following

Setting Required

We add the following code in the init function

rootCmd.Flags().StringVarP(&Name, "name", "n", "", "你的名字")
rootCmd.MarkFlagRequired("name")

Run the following must fill in the name parameter before you can run

Binding configuration

Add a method initConfig

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)
	}
}

Call the init

cobra.OnInitialize(initConfig) //这会运行每个子命令之前运行
rootCmd.PersistentFlags().StringVar(&Author, "author", "defaultAuthor", "作者名")
viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))

This will find viper configuration and flag bind if the user does not set -author option, from the configuration

5, how to set arguments

cobra default provides some authentication methods

  • NoArgs: If you include any location parameter, the command error
  • ArbitraryArgs: command accepts no parameters
  • OnlyValidArgs: If you have not ValidArgs location parameter, the command error
  • MinimumArgs (init): If the number of parameters less than N, given the command line
  • MaximumArgs (init): If the number of arguments excess of N, being given a command line
  • ExactArgs (init): if the number of words instead of N parameters given command line
  • RangeArgs (min, max): if the number of parameters is not in the range (min, max), the command being given

Examples of Use

Add parameters to the Command Args, we specified parameters can not be less than five, as follows

var rootCmd = &cobra.Command{
   Use:   "chenqionghe",
   Short: "getting muscle is not easy",
   Long:  `let's do it, yeah buddy light weight baby!`,
   Run: func(cmd *cobra.Command, args []string) {
      fmt.Println("hello chenqionghe")
   },
   Args: cobra.MinimumNArgs(5),
}

Run output

6, how to use parameters

We can see that the core of the method, in fact, Run cobra.Command parameter that specifies the func (cmd * cobra.Command, args [ ] string) type of callback
mean we can directly use cmd and args to write our program

Gets flag parameters

We can directly use cmd method of obtaining the delivery of the flag flag

var helloCmd = &cobra.Command{
	Use:   "hello",
	Short: "hello命令简介",
	Long:  `hello命令详细介绍`,
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println(cmd.Flag("author").Value)
		fmt.Println(cmd.Flag("name").Value)
	},
}

Run the following

Get args parameter

var helloCmd = &cobra.Command{
	Use:   "hello",
	Short: "hello命令简介",
	Long:  `hello命令详细介绍`,
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println(args)
	},
	TraverseChildren: true,
}

Call the following, we can see already removed all the args parameter

Seven, how to set the hook

cobra provides many hook method, the following order can be run

  • PersistentPreRun
  • PreRun
  • Run
  • PostRun
  • PersistentPostRun
    use examples
var helloCmd = &cobra.Command{
	Use:   "hello",
	Short: "hello命令简介",
	Long:  `hello命令详细介绍`,
	//Args: cobra.MinimumNArgs(1),
	PersistentPreRun: func(cmd *cobra.Command, args []string) {
		fmt.Printf("Inside rootCmd PersistentPreRun with args: %v\n", args)
	},
	PreRun: func(cmd *cobra.Command, args []string) {
		fmt.Printf("Inside rootCmd PreRun with args: %v\n", args)
	},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Printf("Run with args: %v\n", args)
	},
	PostRun: func(cmd *cobra.Command, args []string) {
		fmt.Printf("Inside rootCmd PostRun with args: %v\n", args)
	},
	PersistentPostRun: func(cmd *cobra.Command, args []string) {
		fmt.Printf("Inside rootCmd PersistentPostRun with args: %v\n", args)
	},
}

Run the following

to sum up

Here, we have learned that if the set subcommand, flag parameters, arguments parameters and the preparation methods of using these parameters,
as well as the final step is to compile our binary program, to test our previous demand

  • Compile
go build -o chenqionghe

Below, we have generated a binary filechenqionghe

  • Run command
./chenqionghe -h # 查看帮助
./chenqionghe version # 查看版本,类似docker version
./chenqionghe hello -h # 查看hello命令帮助,类似docker ps -h
./chenqionghe hello --name light-weight-baby --author gym # 使用hello命令,类似docker run --name app --volume /app/data

You can see, the perfect realization of the expected demand, is that simple, light weight baby!

Guess you like

Origin www.cnblogs.com/chenqionghe/p/12661871.html