【问题标题】:Global parameters to commands using go-flags使用 go-flags 命令的全局参数
【发布时间】:2020-10-17 16:40:10
【问题描述】:

我正在使用这个库https://github.com/jessevdk/go-flags

我的应用程序的命令可能如下:

ex list events

所以我有我的包装器命令

type ExCommand struct {
    List list.ListCommand `command:"list" description:"list events" subcommands-optional:"true"`
}

列表命令

type ListCommand struct {
    ExCommand ExCommand `command:"events" description:"list events"`

    Config string `short:"c" long:"config" description:"config file" optional:"yes"`
}

Ex 命令

type EventsCommand struct {
}


func (c *ListCommand) Execute(args []string) error {
    fmt.Println("execute list")
    for _, val := range args {
        fmt.Println(val)
    }
    fmt.Printf("c: %s\n", c.Config)

    return nil
}

func (c *ExCommand) Execute(args []string) error {
    fmt.Println("list events")
    for _, val := range args {
        fmt.Println(val)
    }

    return nil
}

所以我想做的是有一些选择,比如

verbose
config
terse

是可以在任何命令上运行的全局选项。我似乎无法弄清楚是否有办法使用这个库来做到这一点。有没有人有这方面的经验?我可以将Config 添加到每个单独的低级命令,在这种情况下列出EventsCommand,但似乎我通过在每个低级命令而不是更高级别的ListCommand 或ExCommand 添加来重复自己。

【问题讨论】:

    标签: go


    【解决方案1】:

    您可以使用NewParser 创建一个新的解析器。您会从文档中注意到,第一个参数是一个指向“应用程序选项”结构的指针。我将从解释开始,然后是一个工作示例。假设您有以下包含应用程序范围选项的结构:

    type Defaults struct {
        Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"`
        Terse   bool   `short:"t" long:"terse" description:"Shows terse output"`
    }
    

    您可以像之前提到的那样将它传递给 NewParser 函数,如下所示:

    defaultOptions = Defaults{}
    parser = flags.NewParser(&defaultOptions, flags.Default)
    

    您可以使用 parser.AddCommand 函数添加其他命令。例如:

    list := ListCommand{}
    parser.AddCommand("list", "lists something", "", &list)
    

    通过调用解析器完成。解析并享受!

    parser.Parse()
    fmt.Printf("Verbose: %v\n", defaultOptions.Verbose)
    fmt.Printf("Terse: %v\n", defaultOptions.Terse)
    

    这是一个完整的小例子:

    package main
    
    import (
        "fmt"
        flags "github.com/jessevdk/go-flags"
    )
    
    type Defaults struct {
        Verbose []bool `short:"v" long:"verbose" description:"Show verbose    debug information"`
        Terse   bool   `short:"t" long:"terse" description:"Shows terse output"`
    }
    
    type ListCommand struct {
        Config string `short:"c" long:"config" description:"config file" optional:"yes"`
    }
    
    func main() {
        defaultOptions := Defaults{}
        listCmd := ListCommand{}
    
        parser := flags.NewParser(&defaultOptions, flags.Default)
        parser.AddCommand("list", "lists something", "", &listCmd)
    
        parser.Parse()
    }
    

    您还可以通过将 Defaults 结构作为匿名结构包含在您的 Command 结构中来准确实现您的要求。请注意我如何在 ListCommand 结构中引用 Defaults 类型,但没有为该字段提供名称。这允许我访问 Defaults 的字段,就好像它们是 ListCommand 结构的一部分一样。以下示例代码允许我在使用 <prog> list -h 时提供 Verbose 和 Terse 标志:

    package main
    
    import flags "github.com/jessevdk/go-flags"
    
    type Defaults struct {
        Verbose []bool `short:"v" long:"verbose" description:"Show verbose    debug information"`
        Terse   bool   `short:"t" long:"terse" description:"Shows terse output"`
    }
    
    type ListCommand struct {
        Config string `short:"c" long:"config" description:"config file" optional:"yes"`
        Defaults
    }
    
    func main() {
        listCmd := ListCommand{}
    
        parser := flags.NewParser(nil, flags.Default)
        parser.AddCommand("list", "lists something", "", &listCmd)
    
        parser.Parse()
    }
    

    【讨论】:

    • 这是有道理的。但是如何访问 ListCommand 中的 Verbose 或 Terse 标志? ListCommand 的 Execute 函数运行 func (c *ListCommand) Execute(args []string) error 并且 ListCommand 无法访问 Verbose 或 Terse 对吗?
    • 没错。我的示例中的详细和简洁可以通过上面示例中的defaultOptions 访问。您可以使该全局变量能够在您的程序中访问这些选项。
    • 我将用另一种可能实现您想要实现的目标来编辑我的答案。请稍等。
    猜你喜欢
    • 2016-12-07
    • 1970-01-01
    • 2022-06-27
    • 1970-01-01
    • 1970-01-01
    • 2019-10-09
    • 1970-01-01
    • 2023-01-23
    • 1970-01-01
    相关资源
    最近更新 更多