首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Cobra和Viper将值绑定为配置中数组中的第一项?

如何使用Cobra和Viper将值绑定为配置中数组中的第一项?
EN

Stack Overflow用户
提问于 2021-07-30 11:04:51
回答 1查看 416关注 0票数 0

我有以下配置模型:

代码语言:javascript
复制
type Config struct {
  Project []Project `mapstructure:"project"`
}

type Project struct {
  Name string `mapstructure:"name"`
}

我希望能够使用配置文件以及命令行上的选项进行配置。我知道如何通过以正确的格式传递配置文件,然后对其进行解组。

但是,我不知道如何使用Cobra在命令行上设置项目名称,然后让Viper将该值绑定为project数组中的第一项。

下面是我放在一起的一个简单的程序,用来展示我遇到的问题:

代码语言:javascript
复制
package main

import (
    "fmt"
    "log"

    "github.com/spf13/cobra"
    "github.com/spf13/viper"
)

type Config struct {
    Project []Project `mapstructure:"project"`
    Name    string    `mapstructure:"name"`
}

type Project struct {
    Name string `mapstructure:"name"`
}

var (
    config Config

    rootCmd = &cobra.Command{
        Use:              "rjsdummy",
        Short:            "Dummy app to understand Viper BindPFlags",
        Long:             "",
        PersistentPreRun: preRun,
        Run:              executeRun,
    }
)

func init() {

    var name string
    var project_name string

    cobra.OnInitialize()

    // configure the flags on the command line
    rootCmd.Flags().StringVarP(&name, "name", "n", "", "Your name")
    rootCmd.Flags().StringVarP(&project_name, "project", "p", "", "Project name")

    // bind the flags to the configuration
    viper.BindPFlag("name", rootCmd.Flags().Lookup(("name")))
    viper.BindPFlag("project.0.name", rootCmd.Flags().Lookup(("project")))
}

func preRun(ccmd *cobra.Command, args []string) {
    err := viper.Unmarshal(&config)
    if err != nil {
        log.Fatalf("Unable to read Viper options into configuration: %v", err)
    }
}

func executeRun(ccmd *cobra.Command, args []string) {
    fmt.Printf("Your name: %s\n", config.Name)
    fmt.Printf("Project name: %s\n", config.Project[0].Name)
}

func main() {
    rootCmd.Execute()
}

当我使用命令go run .\binding.go -n Russell -p Turtle运行这个命令时,我得到了以下输出:

所以我知道线路viper.BindPFlag("project.0.name", rootCmd.Flags().Lookup(("project")))不工作。如果我把它改成project[0].name,我会得到一个堆栈跟踪。问题是如何将这个(和其他属性)添加为复杂对象数组中的第一项?我可以有第二个Viper,它可以读入另一个对象,然后添加到主配置中,或者有其他方法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-30 14:52:55

玩弄了这个之后,我有了答案。

尽管我已经设置了配置,使其具有项目Project []Project的一部分,但Viper足够聪明,可以解决这一问题。

因此,要将项目名称绑定到切片的第一个元素,只需使用:

代码语言:javascript
复制
viper.BindPFlag("project.name", runCmd.Flags().Lookup("name"))

不需要索引。但是,我可以使用以下命令打印值:

代码语言:javascript
复制
fmt.Println(Config.Project[0].Name)

我想得太多了

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68589913

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档