简体   繁体   English

将资源从命令传递到 urfave/cli/v2 中的子命令

[英]Pass resource from Command To Subcommands in urfave/cli/v2

Is is possible, and if so how, to let a Command initialize a resource and pass it down to its Subcommands .是否可以,如果可以,如何让Command初始化资源并将其传递给它的Subcommands Image an application that takes its arguments like对采用其参数的应用程序进行映像,例如

$ mycmd db --connect <...> create <...>
$ mycmd db --connect <...> update <...>

This may not be a great example but it illustrates the concept.这可能不是一个很好的例子,但它说明了这个概念。 Here db is some resource that all the subcommands depend on.这里db是所有子命令所依赖的一些资源。 I would like a single function to be responsible for the initialization of the db resource and then pass the initialized resource down to the subcommands.我想要一个函数来负责db资源的初始化,然后将初始化的资源传递给子命令。 I can't figure out how to do this with urfave/cli/v2 .我不知道如何使用urfave/cli/v2做到这一点。

You could do it by creating two separate cli.App s, one that parses the db part of the arguments just to create a context.Context with context.WithValue and then use that context to create the second cli.App which would parse the remainder of the arguments.您可以通过创建两个单独做cli.App S,一个解析db的参数的一部分只是为了创造一个context.Contextcontext.WithValue ,然后使用该上下文来创建第二个cli.App这将解析余的论点。 I'm sure there's a better way to do it.我相信有更好的方法来做到这一点。

I'm grateful for any help!我很感激任何帮助!

Maybe you can achieve this with context values.也许您可以使用上下文值来实现这一点。 You set the value in the Before callback.您在Before回调中设置值。 Below code is copied and modified from the subcommands example:下面的代码是从子命令示例中复制和修改的:

package main

import (
  "fmt"
  "log"
  "os"

  "github.com/urfave/cli/v2"
)

func main() {
  app := &cli.App{
    Commands: []*cli.Command{
      {
        Name:   "db",
        Before: func(c *cli.Context) error {
            db := initDB()
            c.Context = context.WithValue(c.Context, "db", db)
            return nil
        }
        Subcommands: []*cli.Command{
          {
            Name:  "connect",
            Action: func(c *cli.Context) error {
                db := c.Context.Value("db").(*MyDB) // remember to assert to original type
                //use db
                return nil
            },
          },
        },
      },
    },
  }

  err := app.Run(os.Args)
  if err != nil {
    log.Fatal(err)
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM