## 底层库的选择
Go 的命令行底层库有两个非常知名的选项:
* [github.com/urfave/cli](https://github.com/urfave/cli)一万多 star
* [github.com/spf13/cobra](https://github.com/spf13/cobra)两万多 star
Gohub 项目里,我们将选择 star 数更高的 cobra 项目。cobra 功能比较强大,设计优良,最重要的**它支持全局选项**。
cli 库做不到`--env`参数后加子命令,例如说:
~~~php
# 指定加载 .env.testing 设定的环境变量来运行 migrate 子命令
$ gohub --env=testing migrate
~~~
主要还是跟其实现方式有关,cli 依赖于官方的 flag 包。而 flag 包的逻辑是会把`--env`参数后面的所有内容都当做选项的值,详细的讨论请见[github.com/urfave/cli/issues/427](https://github.com/urfave/cli/issues/427)。
Cobra 使用的是自己实现的选项解析器 ——[github.com/spf13/pflag](https://github.com/spf13/pflag),故不存在此问题。
另外一个 cli 的不足之处是不支持全局选项,无法满足我们全局选项`--env`的需求。
## cobra.Command struct
在 Cobra 里,所有命令都是一个 cobra.Command 的实现。一个简单示例:
~~~php
var CmdMakeSeeder = &cobra.Command{
Use: "seeder",
Short: "Create seeder file, example: make seeder user",
Run: runMakeSeeder,
Args: cobra.ExactArgs(1), // 只允许且必须传 1 个参数
}
~~~
下面是一个 cobra.Command 的注释,基本上涵盖 Cobra 的大部分功能点:
~~~php
// Command代表执行命令的结构
type Command struct {
// 代表当前命令的,如何执行,root 最好和生成的命令工具名称一致
Use string
// 代表这个工具的别名,在 subCommand 中有用,比如 root cmd1 和 root cmd_1 想要都执行一个 subCommand 就需要这样
Aliases []string
// 由于不强制设置,用于输入错误的时候建议字段
SuggestFor []string
// 这个就是在 help 的时候一句话描述这个命令的功能
Short string
// 详细描述这个命令的功能
Long string
// 例子,调用示例
Example string
// 参数白名单(非 flag),只允许传这里定制的参数
// 此处的参数被被自动补全
ValidArgs []string
// 参数验证器(可设置不接受参数,或者最多、最少参数)
Args PositionalArgs
// 参数别名
ArgAliases []string
// 自动补全的命令设置,只能在 root 命令设置
BashCompletionFunction string
// 如果这个命令已经废弃了,那么就这里写上废弃信息
Deprecated string
// 如果这个命令要被隐藏,设置这个字段
Hidden bool
// 设置命令分组注释
Annotations map[string]string
// 设置命令的版本
Version string
// The *Run 函数运行顺序:
// * PersistentPreRun()
// * PreRun()
// * Run()
// * PostRun()
// * PersistentPostRun()
// 会被子命令继承的前置 Run
PersistentPreRun func(cmd *Command, args []string)
// 会被子命令继承的前置 Run, 带 error
PersistentPreRunE func(cmd *Command, args []string) error
// 当前这个命令的前置 Run
PreRun func(cmd *Command, args []string)
// 当前这个命令的前置 Run,带 Error
PreRunE func(cmd *Command, args []string) error
// zh: 实际跑的时候运行的函数
Run func(cmd *Command, args []string)
// zh: Run 执行错误了之后
RunE func(cmd *Command, args []string) error
// 后置运行
PostRun func(cmd *Command, args []string)
// 后置运行,带 error
PostRunE func(cmd *Command, args []string) error
// 会被子命令继承的后置运行
PersistentPostRun func(cmd *Command, args []string)
// 会被子命令继承的后置运行,带 error
PersistentPostRunE func(cmd *Command, args []string) error
// 是否要打印错误信息
SilenceErrors bool
// 是否关闭使用建议(当命令不存在,或参数有误时)
SilenceUsage bool
// 是否有 flag,如果这个命令没有 flag,设置为 true,那么所有的命令后面的参数都会是 arguments
DisableFlagParsing bool
// 生成文档时,是否打印自动生成字样: ("Auto generated by spf13/cobra...")
DisableAutoGenTag bool
// 是否显示[flags]字样
DisableFlagsInUseLine bool
// 是否打印建议,当命令行出错时,匹配字数,然后给出建议的命令,提高用户体验
DisableSuggestions bool
// 多少个字才会触发 suggest,必须大于 0
SuggestionsMinimumDistance int
// 是否使用 Traverse 的方式来解析参数
TraverseChildren bool
// 解析错误白名单, 比如像未知参数
FParseErrWhitelist FParseErrWhitelist
}
~~~
## 命令钩子
重点关注下 cobra 命令的钩子:
~~~php
// The *Run 函数运行顺序:
// * PersistentPreRun()
// * PreRun()
// * Run()
// * PostRun()
// * PersistentPostRun()
// 会被子命令继承的前置 Run
PersistentPreRun func(cmd *Command, args []string)
// 会被子命令继承的前置 Run, 带 error
PersistentPreRunE func(cmd *Command, args []string) error
// 当前这个命令的前置 Run
PreRun func(cmd *Command, args []string)
// 当前这个命令的前置 Run,带 Error
PreRunE func(cmd *Command, args []string) error
// zh: 实际跑的时候运行的函数
Run func(cmd *Command, args []string)
// zh: Run 执行错误了之后
RunE func(cmd *Command, args []string) error
// 后置运行
PostRun func(cmd *Command, args []string)
// 后置运行,带 error
PostRunE func(cmd *Command, args []string) error
// 会被子命令继承的后置运行
PersistentPostRun func(cmd *Command, args []string)
// 会被子命令继承的后置运行,带 error
PersistentPostRunE func(cmd *Command, args []string) error
~~~
- 序言
- 基础
- 安装GoHub
- 目录结构
- 开发规范
- 部署项目
- 架构
- 架构总览
- 生命周期
- 配置
- 配置介绍
- 配置目录
- 配置格式
- 配置加载
- 读取配置
- 动态配置
- 环境变量配置
- 路由
- 路由模式
- 路由定义
- 路由参数
- 路由分组
- 路由限流
- 路由拆分
- 控制器
- 控制定义
- 控制器初始化
- 中间件
- Make创建控制器
- 请求
- 请求信息
- 数据库
- 连接数据库
- 基本使用
- Make创建模型
- 日志
- 介绍
- 日志驱动
- 日志写入
- HTTP日志
- 数据库请求日志
- 错误和调试
- Debuger调试器
- 验证
- 验证器
- 验证规则
- Make创建验证器
- 杂项
- 缓存
- 分页
- 验证码
- CURL请求
- 命令行
- 基础知识
- console 包
- Cobra 基础
- 命令行模式
- 附录
- 配置参考
- 第三方依赖库