登录
首页 >  Golang >  Go问答

在 Cobra CLI 中如何将命令执行结果传递给 Postrun

来源:stackoverflow

时间:2024-03-20 16:48:33 300浏览 收藏

Cobra CLI 支持在命令执行后调用 PostRun,但如何将命令状态传递给 PostRun 调用呢?一种方法是利用 Cobra 命令中提供的注释。在 run 函数中设置注释,并在 PostRun 函数中检索这些注释。另一种方法是使用高阶函数包装 run 和 PostRun 函数,以捕获错误或恐慌,然后将它们传递到 PostRun 中。

问题内容

Cobra CLI 支持在执行命令后调用 PostRun。

https://github.com/spf13/cobra#prerun-and-postrun-hooks

如何将命令状态传递给 PostRun 调用? 我需要在执行后将命令状态发布到服务器


正确答案


更简洁的方法是利用 cobra 命令中提供的注释

package main

import (
    "fmt"

    "github.com/spf13/cobra"
)


func main() {
    var rootcmd = &cobra.command{
        use:   "root [sub]",
        short: "my root command",
        run: func(cmd *cobra.command, args []string) {
            // do your processing here
            // set the command annotations
            cmd.annotations = make(map[string]string)
            cmd.annotations["status"] = "status_goes_here"
            cmd.annotations["error"] = "error_goes_here"
        },
        postrun: func(cmd *cobra.command, args []string) {
            // retrieve the annotations
            fmt.println(cmd.annotations["status"])
            fmt.println(cmd.annotations["error"])
        },
    }

    rootcmd.setargs([]string{"sub", "arg1", "arg2"})
    rootcmd.execute()
}

真的很喜欢@bracken在这里采取的方法,尽管有一些调整可以使其发挥作用

package main

import (
    "fmt"
    "errors"

    "github.com/spf13/cobra"
)

type wrapper struct {
    err error
}

// rune fails to proceed further in case of error resulting in not executing postrun actions
func (w *wrapper) run(f func(cmd *cobra.command, args []string) error) func(cmd *cobra.command, args []string) {
    return func(cmd *cobra.command, args []string) {
        err := f(cmd, args)
        w.err = err
    }
}

func (w *wrapper) postrun(f func(cmd *cobra.command, args []string, cmderr error)) func(cmd *cobra.command, args []string) {
    return func(cmd *cobra.command, args []string) {
        f(cmd, args, w.err)
    }
}

func main() {
    cmdwrap := wrapper{}
    var rootcmd = &cobra.command{
        use:   "root [sub]",
        short: "my root command",
        run: cmdwrap.run(func(cmd *cobra.command, args []string) error {
            return errors.new("i'm not in the book, you know")
        }),
        postrun: cmdwrap.postrun(func(cmd *cobra.command, args []string, cmderr error) {
            fmt.printf("error was %v\n", cmderr)
        }),
    }

    rootcmd.setargs([]string{"sub", "arg1", "arg2"})
    rootcmd.execute()
}

-----旧答案-----

如果我理解正确的话,有一些状态需要从 cmd.execute 传递到 postrun。

您可以使用 executecontext(ctx context.context) 方法代替 execute() 并设置需要在上下文中设置的任何键值。

ctx := context.withvalue(context.background(), "status", "statusvalue")
rootcmd.executecontext(ctx)

可以使用 cmd.context() 在 postrun 内检索相同的值

postrun: func(cmd *cobra.command, args []string) {
   ctx := cmd.context()
   status := ctx.value("status")
}

我将使用高阶函数包装您的 run (或 rune)函数和 postrun 函数来捕获错误或恐慌,然后将它们传递到您的 postrun 中:

package main

import (
    "fmt"

    "github.com/spf13/cobra"
)

type wrapper struct {
    err error
}

func (w *wrapper) RunE(f func(cmd *cobra.Command, args []string) error) func(cmd *cobra.Command, args []string) error {
    return func(cmd *cobra.Command, args []string) (err error) {
        defer func() {
            if r := recover(); r != nil {
                err = fmt.Errorf("panic: %v", r)
                w.err = err
            }
        }()
        err = f(cmd, args)
        w.err = err
        return
    }
}

func (w *wrapper) PostRun(f func(cmd *cobra.Command, args []string, cmdErr error)) func(cmd *cobra.Command, args []string) {
    return func(cmd *cobra.Command, args []string) {
        f(cmd, args, w.err)
    }
}

func main() {
    cmdWrap := wrapper{}
    var cmdFail = &cobra.Command{
        Use:   "fail",
        Short: "Doesn't work",
        RunE: cmdWrap.RunE(func(cmd *cobra.Command, args []string) error {
            panic("i'm not in the book, you know")
        }),
        PostRun: cmdWrap.PostRun(func(cmd *cobra.Command, args []string, cmdErr error) {
            fmt.Printf("error was %v\n", cmdErr)
        }),
    }

    var rootCmd = &cobra.Command{}
    rootCmd.AddCommand(cmdFail)
    rootCmd.Execute()
}

到这里,我们也就讲完了《在 Cobra CLI 中如何将命令执行结果传递给 Postrun》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!

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