文章目录
Go语言命令行库-urfave/cli
官网:https://github.com/urfave/cli
很多用Go写的命令行程序都用了urfave/cli这个库。urfave/cli是一个命令行的框架。
用C写过命令行程序的人应该都不陌生,我们需要根据argc/argv一个个地解析命令行参数,调用不同的函数,最后还要写一个usage()函数用于打印帮助信息。urfave/cli把这个过程做了一下封装,抽象出flag/command/subcommand这些模块,用户只需要提供一些模块的配置,参数的解析和关联在库内部完成,帮助信息也可以自动生成。
总体来说,urfave/cli这个库还是很好用的,完成了很多routine的工作,程序员只需要专注于具体业务逻辑的实现。
怎么使用urfave/cli
go如何编写命令行(cli)程序
参考URL: https://www.jianshu.com/p/790dc1171bbf
首先下载类库包
go get github.com/urfave/cli
main.go
package main
import (
"os"
"github.com/urfave/cli/v2"
"fmt"
)
func main() {
app := &cli.App{
Name: "greet",
Usage: "say a greeting",
Action: func(c *cli.Context) error {
fmt.Println("Greetings")
return nil
},
}
// 接受os.Args启动程序
app.Run(os.Args)
}
- Flags 用于设置参数。
- Action 对应的函数就是你具体对各个参数具体的处理逻辑。
开源实战举例
开源代码举例(来自 filecoin lotus代码):
func main() {
lotuslog.SetupLogLevels()
local := []*cli.Command{
runCmd,
}
app := &cli.App{
Name: "lotus-wallet",
Usage: "Basic external wallet",
Version: build.UserVersion(),
Flags: []cli.Flag{
&cli.StringFlag{
Name: FlagWalletRepo,
EnvVars: []string{"WALLET_PATH"},
Value: "~/.lotuswallet", // TODO: Consider XDG_DATA_HOME
},
&cli.StringFlag{
Name: "repo",
EnvVars: []string{"LOTUS_PATH"},
Hidden: true,
Value: "~/.lotus",
},
},
Commands: local,
}
app.Setup()
if err := app.Run(os.Args); err != nil {
log.Warnf("%+v", err)
return
}
}
“gopkg.in/urfave/cli.v2” 和 “github.com/urfave/cli”
官网:https://github.com/urfave/cli
gopkg:一种方便的go pakcage管理方式
参考URL: https://studygolang.com/articles/2725
根据官网 readme描述,现在2个版本,主版本使用的是 v2 分支。
导入包为: “github.com/urfave/cli/v2”
有些 go 的代码库地址是gopkg.in开头的,比如gopkg.in/urfave/cli.v2。
v2 表明版本号为 v2,而代码则为 github 上面相应的 v2 branch。
这个也是 Go 的包管理解决方案之一,就是 gopkg.in 做了一个转发过程,实际上是使用了 github 里面的相应的 tag 的代码
子命令 Subcommands
如下 demo所示,我们再Action:同层添加 我们定义指针 &cli.Command 变量即可。
demo:
var daemonStopCmd = &cli.Command{
Name: "stop",
Usage: "Stop a running lotus daemon",
Flags: []cli.Flag{},
Action: func(cctx *cli.Context) error {
panic("wombat attack")
},
}
func main() {
app := &cli.App{
Name: "greet",
Usage: "say a greeting",
Action: func(c *cli.Context) error {
fmt.Println("Greetings")
return nil
},
Subcommands: []*cli.Command{
daemonStopCmd,
},
}
// 接受os.Args启动程序
app.Run(os.Args)
}