Go 应用构建:pflag、viper、cobra
date
May 19, 2023
slug
pflag&viper&cobra
status
Published
tags
Code
Go
summary
pflag、viper、cobra 的使用场景和使用方式
type
Post
Created Time
Oct 28, 2023 01:45 PM
Updated Time
Oct 28, 2023 01:45 PM
AI summary
介绍了 Go 语言中使用 pflag、viper、cobra 库进行应用构建的方法。其中,pflag 用于处理命令行参数,viper 用于处理配置文件,cobra 用于构建命令行工具。详细介绍了这些库的使用方法,包括读取配置、添加命令、添加嵌套子命令、添加非选项参数验证、添加钩子函数等。
Status
在介绍这三个库之前,首先说一下这三个库的作者—— Steve Francia,他在个人主页是这样介绍自己的:“我的名字是史蒂夫-弗朗西亚。27 年的时间里,我是一名软件开发者,是一名产品经理,同时也是一个宣传领导者,在开源社区的这些年里,期冀能够有效“提升”开发者的用户体验。”如果你还不了解他,强烈建议去他的 GitHub 主页看一眼,一定会印象深刻。Steve Francia 在 2016 年加入 Google,2022 年离开谷歌,在加入 Google 时,他就公开表示,自己会在 6 年后离开 Google。在 Google 的 6 年时间里,他领导的 Go 团队,大大改善了 Go 的开发体验,为 Go 语言的蓬勃发展做出了巨大的贡献。
pflag
一个命令行解析工具。与 flag 包的工作原理甚至是代码实现都是类似的,在一些地方做了优化:
- 支持的参数类型更多,如增加了 IP、IP Mask、IP Net、Count、各种类型的 Slice 类型等。
- 支持更丰富的功能,如 shorthand、deprecated、hidden 等高级功能。
除此之外,pflag 还兼容了 flag 库的 Flag 和 FlagSet,有点儿像是对 flag 的扩展,让你可以更方便的解析命令行。
使用
pflag 的使用非常简单,如下:
其结果可能有三种:
- 什么都不做,则 ip 最终为 1234;
- 设置了 —flagname 但是没有设置值,则 ip 最终为 4321;
- 设置 —flagname=9999,则 ip 最终为 9999;
更多使用方式,查阅官方文档。
viper
一个配置管理工具。主要有三大特性:
- 支持多种格式的配置文件;
- 支持多种方式读入配置;
- 支持多种方式读取配置;
多种格式
阅读 viper 的源码可以看到,viper 支持如下几种格式的配置文件:
- YAML
- JSON
- HCL
- Java Properties
- TOML
- ENV
- Initialization File
多种方式读入配置
viper 可以从不同的位置读取配置,不同位置的配置具有不同的优先级,高优先级的配置会覆盖低优先级相同的配置,按优先级从高到低排列如下:通过 viper.Set 函数显示设置的配置→命令行参数→环境变量→Key/Value 存储→默认值。需要注意,viper 配置键不区分大小写。
通过 viper.Set 函数显示设置的配置
命令行参数
环境变量
Key/Value 存储(通过配置文件进行设置)
默认值
多种方式读取配置
Get(key string) interface{}
假设 JSON 文件中的值如下:
访问 JSON 文件中的值:
Get<Type>(key string) <Type>
其中,<Type> 是 viper 支持的类型,首字母大写:Bool、Float64、Int、IntSlice、String、StringMap、StringMapString、StringSlice、Time、Duration,如 GetInt()。
AllSettings() map[string]interface{}
用于将配置序列化成字符串,如将 Viper 中保存的所有设置序列化到一个字符串中:
IsSet(key string) : bool
检查给定的键是否存在。
反序列化
提供了两种方法
- Unmarshal(rawVal interface{}) error
- UnmarshalKey(key string, rawVal interface{}) error
使用方式如下:
更多使用方式,参考官方文档。
cobra
一个命令行工具。主要有以下特性:
- 自定义命令,添加、修改,重定义等;
- 智能提示和自动补全,比如,当我们输入的命令有误时,Cobra 会根据注册的命令,推算出可能的命令;
- 嵌套子命令;
- 提供了对应的脚手架,轻松生成程序框架;
cobra 的命令行结构由三部分组成:
- 命令(Command):就是需要执行的操作;
- 参数(Arg):命令的参数,即要操作的对象;
- 选项(Flag):命令选项可以调整命令的行为。
cobra 认为,一个好的命令要如同一个句子一样符合语法以及直观。
下载
执行如下命令进行下载
cobra-cli
命令行工具下载完成后执行
cobra-cli -h
进行验证。初始化
cobra 的使用非常简单,需要使用如下命令进行初始化:
初始化完毕后,项目会自动生成如下结构:
这个结构符合 cobra 的标准结构规范。
添加命令
就会在 cmd 文件夹下生成一个 version.go 文件,我们可以根据需要,修改 root.go 文件中的内容。
添加嵌套子命令
嵌套子命令需要先添加命令,如通过
cobra-cli add test
命令增加 test.go 文件,再修改 test.go 文件中的 init 函数:测试嵌套子命令:
添加非选项参数验证
在命令的过程中,经常会传入非选项参数,并且需要对这些非选项参数进行验证,cobra 提供了机制来对非选项参数进行验证。可以使用 command 的 args 字段来验证非选项参数。cobra 也内置了一些验证函数:
- NoArgs:如果存在任何非选项参数,该命令将报错。
- ArbitraryArgs:该命令将接受任何非选项参数。
- OnlyValidArgs:如果有任何非选项参数不在 Command 的 ValidArgs 字段中,该命令将报错。
- MinimumNArgs(int):如果没有至少 N 个非选项参数,该命令将报错。
- MaximumNArgs(int):如果有多于 N 个非选项参数,该命令将报错。
- ExactArgs(int):如果非选项参数个数不为 N,该命令将报错。
- ExactValidArgs(int):如果非选项参数的个数不为 N,或者非选项参数不在 Command 的 ValidArgs 字段中,该命令将报错。
- RangeArgs(min, max):如果非选项参数的个数不在 min 和 max 之间,该命令将报错。
使用预定义验证函数,示例如下:
自定义验证函数,示例如下:
添加钩子函数
在运行 Run 函数时,我们可以运行一些钩子函数,在 Run 函数之前执行(或执行之后)执行。这些函数的执行顺序如下:
- PersistentPreRun;
- PreRun
- Run
- PostRun
- PersistentPostRun
其中,父级的 PreRun 只会在父级命令运行时调用,子命令是不会调用。
示例如下:
输出:
更多使用方式,查看官方文档。