登录
首页 >  Golang >  Go问答

如何为子命令提供上下文而不使用包全局变量?

来源:stackoverflow

时间:2024-02-28 19:57:25 382浏览 收藏

学习知识要善于思考,思考,再思考!今天golang学习网小编就给大家带来《如何为子命令提供上下文而不使用包全局变量?》,以下内容主要包含等知识点,如果你正在学习或准备学习Golang,就都不要错过本文啦~让我们一起来看看吧,能帮助到你就更好了!

问题内容

我使用 cobra 和 viper 编写了一个简单的 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 配置对象,但我不清楚该放在哪里 它。


正确答案


cobra 团队最近做到了这一点,请参阅 https://github.com/spf13/cobra/pull/1551

func TestFoo(t *testing.T){
    root := &Command{
        Use: "root",
        PreRun: func(cmd *Command, args []string) {
            ctx := context.WithValue(cmd.Context(), key{}, val)
            cmd.SetContext(ctx)
        },
        Run: func(cmd *Command, args []string) {
            fmt.Println(cmd.Context().Value(key{}))
        },
    }
    ctx := context.WithValue(cmd.Context(), "key", "default")
    root.ExecuteContext(ctx)
}

终于介绍完啦!小伙伴们,这篇关于《如何为子命令提供上下文而不使用包全局变量?》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布Golang相关知识,快来关注吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>