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

我有以下配置模型:


type Config struct {

  Project []Project `mapstructure:"project"`

}


type Project struct {

  Name string `mapstructure:"name"`

}

我希望能够使用配置文件以及命令行上的选项对此进行配置。我知道如何通过以正确的格式传递它然后取消编组来执行配置文件。


但是,我无法弄清楚该怎么做的是使用Cobra在命令行上设置项目名称,然后让Viper将该值绑定为Project数组中的第一项。


以下是我放在一起的简单程序,以显示我遇到的问题:


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


http://img2.mukewang.com/6327ce890001a71b02300054.jpg

所以我知道这条线不起作用。如果我将其更改为,我将获得堆栈跟踪。问题是我如何添加这个(和其他属性)作为复杂对象数组中的第一项?我可以有第二个Viper来读取另一个对象,然后添加到主配置中,还是有另一种方法?viper.BindPFlag("project.0.name", rootCmd.Flags().Lookup(("project")))project[0].name


qq_花开花谢_0
浏览 49回答 1
1回答

斯蒂芬大帝

在玩了这个问题之后,我有了答案。即使我已经设置了配置,以便它有一个切片项目,Viper也足够聪明地解决了这个问题。Project []Project因此,要将项目名称绑定到切片的第一个元素,就像使用:viper.BindPFlag("project.name", runCmd.Flags().Lookup("name"))不需要索引。但是,我可以打印以下值:fmt.Println(Config.Project[0].Name)我过度思考这个
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go