golang开源框架:命令行框架cobra
命令行参数与命令行选项
命令行的命令包括
command:命令
args:事务
flags:标志或选项
推荐的结构
标志类型:
持久标志:当前命令以及子命令与其继承命令 — PersistentFlags()
全局标志:由持久标志衍生
本地标志:当前命令可用
创建root.go文件
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
var rootCmd = &cobra.Command{
Use: "mycobra",
Short: "简短的描述",
Long: "详细的描述",
}
func Execute() {
rootCmd.Execute()
}
var userLicense string
func init() {
rootCmd.PersistentFlags().Bool("viper", true, "是否采用viper作为配置文件读取")
rootCmd.PersistentFlags().StringP("auther", "a", "YOUR NAME", "作者名称")
rootCmd.PersistentFlags().StringVarP(&userLicense, "licence", "l", "", "授权信息")
rootCmd.Flags().StringP("source", "s", "", "来源")
}
使用
go run .\main.go --help
查看定义的命令参数
创建init.go文件
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
var initCmd = &cobra.Command{
Use: "init",
Short: "init short",
Long: "init long",
Aliases: []string{"createss"}, //别名
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("执行init子命令 start")
author, _ := cmd.Root().PersistentFlags().GetString("author")
viper, _ := cmd.Root().PersistentFlags().GetBool("viper")
license, _ := cmd.Root().PersistentFlags().GetString("licence")
fmt.Printf("author is :%s; viper is %v; license is %s\n", author, viper, license)
fmt.Println("执行init子命令 end")
},
}
func init() {
rootCmd.AddCommand(initCmd)
}
执行
参数验证与内置参数验证器
创建args.go
package cmd
import (
"errors"
"fmt"
"github.com/spf13/cobra"
)
// 自定义验证
var curArgsCheckCmd = &cobra.Command{
Use: "cus",
Long: "",
Short: "",
Args: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return errors.New("至少输入一个参数")
}
if len(args) > 2 {
return errors.New("最多输入两个参数")
}
return nil
},
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("自定义参数验证 start")
fmt.Println(args)
fmt.Println("自定义参数验证 end")
},
}
// 无参数验证
var noArgsCmd = &cobra.Command{
Use: "noArgs",
}
// 可以接受任何参数
var arbitrayArgsCmd = &cobra.Command{}
var onlyArgsCmd = &cobra.Command{}
// 恰好多少个参数
var exactArgsCmd = &cobra.Command{}
// 最大
var maxArgsCmd = &cobra.Command{}
//最小
func init() {
rootCmd.AddCommand(curArgsCheckCmd)
}
检查自定义验证
接下来同理测试其他的参数格式
package cmd
import (
"errors"
"fmt"
"github.com/spf13/cobra"
)
// 自定义验证
var curArgsCheckCmd = &cobra.Command{
Use: "cus",
Long: "",
Short: "",
Args: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return errors.New("至少输入一个参数")
}
if len(args) > 2 {
return errors.New("最多输入两个参数")
}
return nil
},
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("自定义参数验证 start")
fmt.Println(args)
fmt.Println("自定义参数验证 end")
},
}
// 无参数验证
var noArgsCmd = &cobra.Command{
Use: "noArgs",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("无参数验证")
return nil
},
}
// 可以接受任何参数
var arbitrayArgsCmd = &cobra.Command{
Use: "ab",
Args: cobra.ArbitraryArgs,
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("接收任何参数")
fmt.Println(args)
return nil
},
}
var onlyArgsCmd = &cobra.Command{
Use: "only",
Args: cobra.OnlyValidArgs,
ValidArgs: []string{"123", "456", "789"},
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("only参数验证 start")
fmt.Println(args)
fmt.Println("only参数验证 end")
return nil
},
}
// 恰好多少个参数
var exactArgsCmd = &cobra.Command{
Use: "exact",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("恰好两个参数验证 start")
fmt.Println(args)
fmt.Println("恰好两个参数验证 end")
return nil
},
}
func init() {
rootCmd.AddCommand(curArgsCheckCmd)
rootCmd.AddCommand(noArgsCmd)
rootCmd.AddCommand(arbitrayArgsCmd)
rootCmd.AddCommand(onlyArgsCmd)
rootCmd.AddCommand(exactArgsCmd)
}
无参数验证:
可接受任意参数:
只能输入指定参数:
ValidArgs: []string{"123", "456", "789"},
恰好两个参数:
钩子函数定义与使用
四个钩子函数执行顺序:
PersistentPreRun --》
PreRun --》
Run --》
PostRun --》
PersistentPostRun --》
接下来,我们来看继承
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
var hookRootCmd = &cobra.Command{
Use: "hookroot",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("钩子案例,run函数")
},
PersistentPreRun: func(cmd *cobra.Command, args []string) {
//run函数之前执行
fmt.Println("PersistentPreRun")
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
//run函数之后执行
fmt.Println("PersistentPostRun")
},
PreRun: func(cmd *cobra.Command, args []string) {
// run之前
fmt.Println("PreRun")
},
PostRun: func(cmd *cobra.Command, args []string) {
//run之后
fmt.Println("PostRun")
},
}
var hookSubCmd = &cobra.Command{
Use: "hooksub",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("钩子案例,run函数")
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
//run函数之后执行
fmt.Println("PersistentPostRun")
},
PreRun: func(cmd *cobra.Command, args []string) {
//run之后
fmt.Println("PreRun")
},
}
func init() {
rootCmd.AddCommand(hookRootCmd)
hookRootCmd.AddCommand(hookSubCmd)
}
可以看到,我们没有写PersistentPreRun()和PostRun
但是Persistent是可以继承的,所以我们仍然可以继承父亲的PersistentPreRun()
而PostRun()就没有了