# conftool **Repository Path**: thincats/conftool ## Basic Information - **Project Name**: conftool - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-03-30 - **Last Updated**: 2021-04-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## Intro 配置解析工具,基于[Viper](https://github.com/spf13/viper) ## Feature - 使用 Struct Field Tag 注解元信息 - 支持嵌套结构体 - 支持默认值的设置 (Support By github.com/creasty/defaults) - 支持解析后校验 (Support By github.com/go-playground/validator/v10) - 支持环境变量 - 支持配置文件 - 支持命令行 - 支持 PathFlagMode,预先解析配置文件路径与.env 路径 - 函数式选项配置 ## Provider Priority 优先级从上到下 1. 命令行 2. 环境变量 3. 配置文件 4. 默认值 ## Usage see `example/` and `conftool_test.go` ### 1 Declare Config Struct ```go type Output struct { Path string `cli:"usage=output path"` } type Extra struct { Output Output Timeout time.Dudation `default:"2s" validate:"gte=100ms" cli:"usage=timeout"` } type RootConfig struct { Verbose bool `cli:"usage=enable verbose mode."` LoaderType string `validate:"required,oneof=mysql clickhouse" cli:"usage=loader type (mysql|clickhouse)"` Extra Extra `cli:"usage=extra config"` } ``` 注意: Viper 与 Struct2StringMap 均依赖于 mapstructure,所以要控制 nested struct 的行为,需要指定 mapstructure tag,如匿名结构体字段 ```go type BaseConfig struct { Name string } type DBConfig struct { BaseConfig `mapstructure:",squash"` // 指定squash 展平 BaseConfig } ``` ### 2 New conftool.Tool ```go ctool := conftool.New() // or path flag mode ctool := conftool.New( conftool.WithPathFlagMode(os.Args[1:]), ) ``` ### 3 Parse Config Tool ```go conf := RootConfig{} ctool.MustParse(&conf, ctool.WithDefaultValueSupport(), ctool.WithCommandLineSupport(os.Args[1:]), ctool.WithEnvSupport("DS"), ctool.WithConfigFileSupport(".", "app"), ctool.WithValidateSupport(), ) // or path flag mode ctool.MustParse(&conf, ctool.WithDefaultValueSupport(), ctool.WithCommandLineSupportPathFlag(), ctool.WithEnvSupportPathFlag("DS"), ctool.WithConfigFileSupportPathFlag(), ctool.WithValidateSupport(), ) // or use not panic version err := ctool.Parse(...) // then should check -h error if ctool.IsHelpError(err) { ... } ``` ### 4 [Optional] Print Config To Yaml (For Debug) ```go b, err := conftool.ConfigToYaml(conf) if err != nil { ... } fmt.Printf("Use Config\n%s\n", string(b)) ``` ### 5 Run ```sh go run main.go -h # or path flag mode go run main.go -- -h ``` output: ``` Usage of : --extra.timeout int timeout --loaderType string loader type (mysql|clickhouse) --verbose enable verbose mode. exit status 1 ``` ### Path Flag Mode PathFlag 启用后,程序将支持解析两个部分的命令行,第一个部分负责解析配置文件路径以及环境变量 dotenv 文件路径,解析后,该信息将会被传递给配置文件/环境变量解析器。第二部分是常规的命令行解析,两部分使用--分隔 例如 ```sh # 解析app.yml作为配置文件路径,设置extra.timeout=1s go run main.go --conf app.yml --env .env -- --extra.timeout 1s # 查看path flag help go run main.go -h # 查看命令行配置help go run main.go -- -h ``` 需要在代码中启用 PathFlagMode ```go // 前两个参数为flag名称 ctool := conftool.New( conftool.WithPathFlagMode(os.Args[1:]), ) // 对应选项也要启用PathFlag ctool.MustParse(&conf, ctool.WithDefaultValueSupport(), ctool.WithCommandLineSupportPathFlag(), ctool.WithEnvSupportPathFlag("DS", "env"), ctool.WithConfigFileSupportPathFlag("conf"), ctool.WithValidateSupport(), ) ```