Cobra:在不使用包全局变量的情况下为子命令提供上下文?

问题描述

我使用 cobraviper 编写了一个简单的 CLI 工具。我最近一直在重构它以避免包全局变量,主要是因为使用例如建议的布局很难测试cobra init

代替...

var rootCmd = &cobra.Command{
  ...
}

func main() {
  rootCmd.Execute()
}

我有更多类似的东西:

func NewCmdRoot() *cobra.Command {
  cmd := &cobra.Command{
    ...
  }

  return cmd
}

func main() {
  rootCmd := NewCmdRoot()
  rootCmd.Execute()
}

这实际上效果很好,并且使测试更容易 从一组干净的 cli 选项开始。我遇到了一些 难以将 Viper 整合到新计划中。如果我只在乎 关于 root 命令,我可以在 PersistentPreRun 命令,像这样:

func initConfig(cmd *cobra.Command) {
  config := viper.New()
  rootCmd := cmd.Root()

  config.BindPFlag("my-nifty-option",rootCmd.Flag("my-nifty-option")); err != nil {

  // ...stuff happens here...

  config.ReadInConfig()

  // What happens next?
}

func NewCmdRoot() *cobra.Command {
  cmd := &cobra.Command{
    PersistentPreRun: func(cmd *cobra.Command,args []string) {
      initConfig(cmd)
    },}

这种工作:只要我只对配置选项感兴趣 对应于 Cobra 命令行选项,事情就像 预期的。但是如果我想访问 config 变量本身怎么办?

我不确定如何将 config 变量暴露在 initConfig 方法而不将其转换为全局包。我想要 实例化多个命令树的可能性,每个命令树都有 它是自己独立的 Viper 配置对象,但我不清楚该放在哪里

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)