cmdr 03 - 用流式接口定义命令行参数处理选项

栏目: Go · 发布时间: 5年前

内容简介:基于 v0.2.17转眼已经来到了

基于 v0.2.17

转眼已经来到了 cmdr v0.2.17 了,为了解决此前版本中关于子命令和选项定义语句的太多嵌套的问题,我们实现了流式调用接口(Fluent APIs)。

cmdr 是我发布的一个开源的 golang 命令行参数处理器。它是 golang flags 的替代品。之所以发布它,是因为已有的 command line UI 三方包无法满足我的日常要求,迫不得己自己造一个。如果尚未有了解 cmdr 怎么使用的,不妨抽空浏览我的早前文章,以求获得一些基本概念:

稍后我会继续针对 cmdr 的用法做介绍文章。

至于本文呢 ,只是简单讲述一下如何使用 cmdr 的流式接口(Fluent API)来完成定义。

定义 RootCommand

root := cmdr.Root("aa", "1.0.1").Header("aa - test for cmdr - no version")
rootCmd = root.RootCommand()

第二句是拿到一个 *cmdr.Command 指针,稍后可以做一下相关的其它操作。

此外, rootCmd 作为函数返回值,也便于被用到向 cmdr.Exec() 做传递参数。

func buildCmds() *cmdr.Command {
    root := ...
    rootCmdr = root.RootCommand()
    ...
    return rootCmdr
}

func main() {
    if err := cmdr.Exec(buildCmds()); err != nil {
        logrus.Fatal(err)
    }
}

定义命令 Command

顶级的命令其实就是 RootCommand 的 子命令,所以:

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
}

定义选项 Flag

对于每条命令,你都可以为其附着一系列的选项,这是通过 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 的基础上展开特殊分支来进行测试。

参考


以上所述就是小编给大家介绍的《cmdr 03 - 用流式接口定义命令行参数处理选项》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C++程序设计

C++程序设计

谭浩强 / 清华大学出版社 / 2004-6-1 / 36.00元

《C++程序设计》作者深入调查了我国大学的程序设计课程的现状和发展趋势,参阅了国内外数十种有关C++的教材,认真分析了学习者在学习过程中遇到的困难,研究了初学者的认识规律。在本书中做到准确定位,合理取舍内容,设计了读者易于学习的教材体系,并且以通俗易懂的语言化解了许多复杂的概念,大大减少了初学者学习C++的困难。C++是近年来国内外广泛使用的现代计算机语言,它既支持面向过程的程序设计,也支持基于对......一起来看看 《C++程序设计》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具