Created
August 26, 2016 13:09
-
-
Save elliotmr/8815e429a91bdc54109eeec9d5a53cbd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package cmd | |
import ( | |
"strings" | |
"github.com/chzyer/readline" | |
"github.com/spf13/cobra" | |
) | |
var shellCmd = &cobra.Command{ | |
Use: "shell", | |
Short: "This is a shell version of this tool", | |
Long: ``, | |
Run: func(cmd *cobra.Command, args []string) { | |
runShell() | |
}, | |
} | |
func init() { | |
RootCmd.AddCommand(shellCmd) | |
} | |
func pcFromCommands(parent readline.PrefixCompleterInterface, c *cobra.Command) { | |
pc := readline.PcItem(c.Use) | |
parent.SetChildren(append(parent.GetChildren(), pc)) | |
for _, child := range c.Commands() { | |
pcFromCommands(pc, child) | |
} | |
} | |
func runShell() { | |
completer := readline.NewPrefixCompleter() | |
for _, child := range RootCmd.Commands() { | |
pcFromCommands(completer, child) | |
} | |
shell, err := readline.NewEx(&readline.Config{ | |
Prompt: "> ", | |
AutoComplete: completer, | |
EOFPrompt: "exit", | |
}) | |
if err != nil { | |
panic(err) | |
} | |
defer shell.Close() | |
shell_loop: | |
for { | |
l, err := shell.Readline() | |
if err != nil { | |
break shell_loop | |
} | |
cmd, flags, err := RootCmd.Find(strings.Fields(l)) | |
if err != nil { | |
shell.Terminal.Write([]byte(err.Error())) | |
} | |
cmd.ParseFlags(flags) | |
cmd.Run(cmd, flags) | |
} | |
} |
Where is RootCmd
supposed to be defined?
I've tried defining it in the shel.go file but I get circular reference errors:
RootCmd refers to
runShell refers to
RootCmd
I think the assumption in the gist above is to leave the RootCmd in root.go and make shell a subcommand of RootCmd(as done in init())
Honestly, I haven't looked at this in 3 years since I wrote it. What Kiran says sounds right to me, I believe that cobra should generate a global RootCmd struct and this registers the shell command. If there problems it could also be that cobra changed how it works in the last 3 years.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Your example is much appreciated. I'm currently looking at a revised version of your primary loop to mirror a standard call a bit more directly. In order to handle the call to cmd.Run directly, I found myself replicating much of the functionality already included in cmd.execute(...).
Haven't run into any issues yet, but I'll post back if I do.