gogo-cobra

cobra PersistentPreRun stack overflow


why does the following CLI program using the cobra package throw a stack overflow error when ran with go run /tmp/test.go branch leaf, but does not error when when leaf subcommand is directly connected to root(as commented in the main function)?

This suggests that I'm not using the cobra PersistenRun* functions properly. My understanding of the PersistenRun* functions is that they only apply to command's children. The issue seems that a command's parent has been somehow set to the command itself.

package main

import (
        "fmt"
        "os"
        "path"

        "github.com/spf13/cobra"
)

var programName = path.Base(os.Args[0])

var rootCmd = &cobra.Command{
        Use: programName,
        PersistentPreRun: func(cmd *cobra.Command, args []string) {
                fmt.Println("in root pre run")
        },
}

var branchCmd = &cobra.Command{
        Use: "branch",
        PersistentPreRun: func(cmd *cobra.Command, args []string) {
                cmd.Parent().PersistentPreRun(cmd, args)
                fmt.Println("in branch pre run")
        },
}

var leafCmd = &cobra.Command{
        Use: "leaf",
        PersistentPreRun: func(cmd *cobra.Command, args []string) {
                cmd.Parent().PersistentPreRun(cmd, args)
                fmt.Println("in leaf pre run")
        },
        Run: func(cmd *cobra.Command, args []string) {
                fmt.Println("in leaf run")
        },
}

func main() {
        branchCmd.AddCommand(leafCmd)
        rootCmd.AddCommand(branchCmd)
        rootCmd.Execute()

        // If I connect the root to the leaf directly, like the following, then
        // the program no longer stack overflow
        // rootCmd.AddCommand(leafCmd)
        // rootCmd.Execute()
}

Solution

  • NVM, I figured it out.

    Intead of

           PersistentPreRun: func(cmd *cobra.Command, args []string) {
                    cmd.Parent().PersistentPreRun(cmd, args)
                    fmt.Println("in * pre run")
           },
    

    It should be:

           PersistentPreRun: func(cmd *cobra.Command, args []string) {
                    cmd.Parent().PersistentPreRun(cmd.Parent(), args)
                    fmt.Println("in * pre run")
           },