簡體   English   中英

如何使用 Cobra 和 Viper 將值綁定為配置中數組中的第一項?

[英]How can I use Cobra and Viper to bind a value as the first item in an array in the configuration?

我有以下配置模型:

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

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

我希望能夠使用配置文件以及命令行上的選項進行配置。 我知道如何通過以正確的格式傳遞配置文件然后對其進行解組來執行配置文件。

但是,我無法弄清楚如何使用 Cobra 在命令行上設置項目的名稱,然后讓 Viper 將該值綁定為項目數組中的第一項。

以下是我放在一起的一個簡單程序,用於顯示我遇到的問題:

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 來讀入另一個對象然后添加到主配置中還是有其他方法?

在玩弄這個之后,我有了答案。

即使我已經設置了配置,以便它有一部分項目Project []Project ,但 Viper 足夠聰明來解決這個問題。

所以要將項目名稱綁定到切片的第一個元素,就像使用一樣簡單:

viper.BindPFlag("project.name", runCmd.Flags().Lookup("name"))

不需要索引。 但是我可以打印值:

fmt.Println(Config.Project[0].Name)

在此處輸入圖片說明

我想太多了

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM