cmdr 03 - 用流式接口定义命令行参数处理选项git
基于 v0.2.17github
转眼已经来到了 cmdr
v0.2.17 了,为了解决此前版本中关于子命令和选项定义语句的太多嵌套的问题,咱们实现了流式调用接口(Fluent APIs)。golang
cmdr
是我发布的一个开源的 golang 命令行参数处理器。它是 golang flags
的替代品。之因此发布它,是由于已有的 command line UI 三方包没法知足个人平常要求,迫不得己本身造一个。若是还没有有了解 cmdr
怎么使用的,不妨抽空浏览个人早前文章,以求得到一些基本概念:api
稍后我会继续针对 cmdr
的用法作介绍文章。函数
至于本文呢 ,只是简单讲述一下如何使用 cmdr
的流式接口(Fluent API)来完成定义。post
root := cmdr.Root("aa", "1.0.1").Header("aa - test for cmdr - no version")
rootCmd = root.RootCommand()
复制代码
第二句是拿到一个 *cmdr.Command
指针,稍后能够作一下相关的其它操做。测试
此外,rootCmd
做为函数返回值,也便于被用到向 cmdr.Exec()
作传递参数。ui
func buildCmds() *cmdr.Command {
root := ...
rootCmdr = root.RootCommand()
...
return rootCmdr
}
func main() {
if err := cmdr.Exec(buildCmds()); err != nil {
logrus.Fatal(err)
}
}
复制代码
顶级的命令其实就是 RootCommand 的 子命令,因此:spa
co := root.NewSubCommand().
Titles("ms", "micro-service").
Description("", "").
Group("")
复制代码
在这里,你能够作的定义基本上和 cmdr.Command
结构定义是相匹配的,因此你可使用 OptCmd
接口所支持的方法来完成一条命令的定义:命令行
// OptCmd to support fluent api of cmdr.
// see also: cmdr.Root().NewSubCommand()/.NewFlag()
OptCmd interface {
Titles(short, long string, aliases ...string) (opt OptCmd)
Short(short string) (opt OptCmd)
Long(long string) (opt OptCmd)
Aliases(ss ...string) (opt OptCmd)
Description(oneLine, long string) (opt OptCmd)
Examples(examples string) (opt OptCmd)
Group(group string) (opt OptCmd)
Hidden(hidden bool) (opt OptCmd)
Deprecated(deprecation string) (opt OptCmd)
Action(action func(cmd *Command, args []string) (err error)) (opt OptCmd) // FlagAdd(flg *Flag) (opt OptCmd) // SubCommand(cmd *Command) (opt OptCmd) PreAction(pre func(cmd *Command, args []string) (err error)) (opt OptCmd) PostAction(post func(cmd *Command, args []string)) (opt OptCmd) TailPlaceholder(placeholder string) (opt OptCmd) NewFlag(typ OptFlagType) (opt OptFlag) NewSubCommand() (opt OptCmd) OwnerCommand() (opt OptCmd) SetOwner(opt OptCmd) RootCommand() *RootCommand } 复制代码
对于每条命令,你均可觉得其附着一系列的选项,这是经过 NewFlag
来完成的:
co.NewFlag(cmdr.OptFlagTypeUint).
Titles("t", "retry").
Description("", "").
Group("").
DefaultValue(3, "RETRY")
复制代码
相似的,全部 OptFlag
接口支持的方法均可以用在这里:
// OptFlag to support fluent api of cmdr.
// see also: cmdr.Root().NewSubCommand()/.NewFlag()
OptFlag interface {
Titles(short, long string, aliases ...string) (opt OptFlag)
Short(short string) (opt OptFlag)
Long(long string) (opt OptFlag)
Aliases(ss ...string) (opt OptFlag)
Description(oneLine, long string) (opt OptFlag)
Examples(examples string) (opt OptFlag)
Group(group string) (opt OptFlag)
Hidden(hidden bool) (opt OptFlag)
Deprecated(deprecation string) (opt OptFlag)
Action(action func(cmd *Command, args []string) (err error)) (opt OptFlag) ToggleGroup(group string) (opt OptFlag) DefaultValue(val interface{}, placeholder string) (opt OptFlag) ExternalTool(envKeyName string) (opt OptFlag) OwnerCommand() (opt OptCmd) SetOwner(opt OptCmd) RootCommand() *RootCommand } 复制代码
按照递归的定义方案,反复重复,你就能够获得一套完整的命令行界面定义了。
我得认可,这个方式避免了传统方式的结构嵌套问题,可读性上是要好不少的了。但它的问题也很明显,你须要在程序启动时额外消耗一点点 CPU 来完成上述定义指令的执行,相比而言,这比传统方式略微费事了 a little bit。但我还要认可,这个消耗,人是感觉不出来的。
流式接口并未带来任何新鲜东西。它只是改善了定义 Command Line UI 的友善性。
cmdr
同时支持两种方式以支持你的命令行参数定义。
v0.2.17:在这个版本中,咱们计划作一系列 gocov 自测工做,以便扫荡此前功能性推动过程当中的潜在隐患。在某些临界条件知足的场景下,cmdr
也许会工做的不使人满意,所以是时候自检一下下了。
新的版本很快就会发布以覆盖 v0.2.17 的一系列子版本。
总的来讲,如无心外,咱们遵循古老的传统,奇数版本号代码着 stable 发布。若是有,偶数版本属于临时性的、又或是试验性的发布。
更多状况下,咱们会在奇数版本号上加之后缀以完成线上测试,例如 v0.2.17-rel01。它们每每是为了配合开源 CI/CD 而产生的。
若是咱们有实验性的想法,那么一般会在 devel
的基础上展开特殊分支来进行测试。