关于 go:使用 Cobra/Viper 遇到问题

Trouble using Cobra/Viper

我无法同时使用 Cobra 和 Viper。这就是我正在做的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var options util.Config = util.Config{}
var rootCmd = &cobra.Command{
    Use:  "test [command] [subcommands]",
    Run: func(cmd *cobra.Command, args []string) {
        if err := server.Run(); err != nil {
            l.Fatal(err)
        }
    },
}

// initConfig helps initialise configuration with a stated path
func initConfig() {
    if options.Path !="" {
        viper.SetConfigFile(options.Path)
    }
    viper.AutomaticEnv()
    if err := viper.ReadInConfig(); err != nil {
        fmt.Println("Could not use config file:", viper.ConfigFileUsed())
    }
}

func init() {
    cobra.OnInitialize(initConfig)
    rootCmd.PersistentFlags().StringVarP(&options.Path,"config","n","","Path of a configuration file")
    rootCmd.PersistentFlags().StringVarP(&options.Password,"password","d","","Password to access the server")
    viper.BindPFlag("password", rootCmd.PersistentFlags().Lookup("password"))
    rootCmd.AddCommand(log.Cmd(&options))
}

func main() {
    rootCmd.Execute()
}

我正在尝试在我的子命令(log.Cmd(&options) 中添加的命令)中检索值 options.Password,但是该字段没有被填充。我很确定我正确地关注 Cobra 文档:https://github.com/spf13/cobra#create-rootcmd


将 cobra 标志绑定到 viper 选项只会将 cobra 标志绑定到 viper 选项,反之亦然。所以你可以通过

访问密码

1
pass := viper.GetString("password")

如果密码是通过 viper 或 cobra 设置的,但不是通过标志定义中定义的变量。

基本上,你有两个选择:要么使用 cobra 而不将标志指向变量,然后通过对 viper.Get* 的各种调用来设置全局变量(你甚至可以在处理它们时对其进行清理),或者使用 viper作为一种 aa€?参数注册表a€?并在需要的地方调用 viper.Get*。我倾向于使用前一种解决方案。