我在 Go 中创建了一个 CLI,我决定同时使用 Cobra 和 Viper 来解析 cli 参数和配置文件。
我到处寻找一种同时使用cobra
并viper
合并配置文件和给定 CLI 参数的方法。
我偶然发现了毒蛇毒刺*cobra.Command
作为使用标志的一种方式,并使用cobra
.
这个实现的问题是它强制配置键与命令参数具有相同的名称。它也不允许我在配置文件中有更多的配置选项。
我也发现了这个 Github 问题。除了 CLI 标志之外,这似乎也不允许我进行自定义配置。
没有找到合适的解决方案,我选择了“肮脏”的路线,并决定使用 cmd 标志创建一个配置实例,viper
然后使用github.com/imdario/mergo
.
一个简化的例子:
func loadConfigFile(path string) (*Configuration, error) {
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
return nil, fmt.Errorf("failed to read config file - %s", err.Error())
}
}
var config *Configuration
if err := viper.Unmarshal(&config); err != nil {
return nil, fmt.Errorf("failed to unmarshal config file - %s", err.Error())
}
}
func loadCmdConfig() *Configuration {
return &Configuration{...}
}
func loadConfiguration() (*Configuration, error) {
fileConfig, err := loadConfigFile()
if err != nil {
return nil, err
}
cmdConfig := loadCmdConfig()
if fileConfig != nil {
if err := mergo.Merge(cmdConfig, fileConfig); err != nil {
return nil, err
}
}
return cmdConfig, nil
}
显然,这种实现存在问题,所以我想知道是否有人知道使用cobra
and的更好方法viper
。