Go语言命令行库urfave-cli简介
很多用Go写的命令行程序都用了urfave/cli这个库,包括geth,有必要简单了解一下。
用C写过命令行程序的人应该都不陌生,我们需要根据argc/argv一个个地解析命令行参数,调用不同的函数,最后还要写一个usage()函数用于打印帮助信息。urfave/cli把这个过程做了一下封装,抽象出flag/command/subcommand这些模块,用户只需要提供一些模块的配置,参数的解析和关联在库内部完成,帮助信息也可以自动生成。
举个例子,我们想要实现下面这个命令行程序:
1 | NAME: GoTest - hello world |
- 基本结构
导入包以后,通过cli.NewApp()创建一个实例,然后调用Run()方法就实现了一个最基本的命令行程序了。
当然,为了让我们的程序干点事情,可以指定一下入口函数app.Action,具体写法如下:
1 | import ( |
- 公共配置
就是帮助里需要显示的一些基本信息:
1 | app.Name = "GoTest" |
- Flag配置
具体对应于帮助中的以下信息:
1 | --lang FILE, -l FILE read from FILE (default: "english") |
对应代码:
1 | var language string |
可以看到,每一个flag都对应一个cli.Flag接口的实例。
Name字段中逗号后面的字符表示flag的简写,也就是说”–port”和”-p”是等价的。
Value字段可以指定flag的默认值。
Usage字段是flag的描述信息。
Destination字段可以为该flag指定一个接收者,比如上面的language变量。解析完”–lang”这个flag后会自动存储到这个变量里,后面的代码就可以直接使用这个变量的值了。
另外,如果你想给用户增加一些属性值类型的提示,可以通过占位符(placeholder)来实现,比如上面的”–lang FILE”。占位符通过``符号来标识。
我们可以在app.Action中测试一下打印这些flag的值:
1 | app.Action = func(c *cli.Context) error { |
另外,正常来说帮助信息里的flag是按照代码里的声明顺序排列的,如果你想让它们按照字典序排列的话,可以借助于sort:
1 | import "sort" |
最后,help和version这两个flag有默认实现,也可以自己改:
1 | cli.HelpFlag = cli.BoolFlag { |
- Command配置
命令行程序除了有flag,还有command(比如git log, git commit等等)。
另外每个command可能还有subcommand,也就必须要通过添加两个命令行参数才能完成相应的操作。比如我们的db命令包含2个子命令,如果输入GoTest db -h会显示下面的信息:
1 | NAME: GoTest db - database operations |
每个command都对应于一个cli.Command接口的实例,入口函数通过Action指定。如果你想像在帮助信息里实现分组显示,可以为每个command指定一个Category。具体代码如下:
1 | app.Commands = []cli.Command { |
如果你想在command执行前后执行后完成一些操作,可以指定app.Before/app.After这两个字段:
1 | app.Before = func(c *cli.Context) error { |
具体测试一下:
1 | $ GoTest add |
- 小结
总体来说,urfave/cli这个库还是很好用的,完成了很多routine的工作,程序员只需要专注于具体业务逻辑的实现。
附完整demo代码:
1 | package cli |
Go语言命令行库urfave-cli简介
https://mxts.jiujiuer.xyz/2022/11/22/计算机科学/编程语言/Golang/Go语言命令行库urfave-cli简介/