I have a, rootCmd, with two chidren, serveCmd and dbCmd. I'd like rootCmd.Run to be an alias of serveCmd, including flags. But I don't wan't flags shown when rootCmd --help is executed. So far I could make the root execute the subcommand with:
Run: func(cmd *cobra.Command, args []string) {
serveCmd.Run(cmd, args)
},
However, when a flag defined in serveCmd is passed to rootCmd, it complains before reaching rootCmd.Run.
I can't think of a good way to do this....
In main() before you call rootCmd.Execute() you might be able to mess with os.Args to magically insert your subcommand into the argument list if it wasn't there?
I'll keep trying to think of something...
It works great! As you said, I added a check. If os.Args[1] is not any of the subcommands in a list, it adds one. This is my main now:
func main() {
checkRootAlias(os.Args[1], NonRootSubCommands)
cmd.Execute()
}
var NonRootSubCommands = []string{"db"}
func checkRootAlias(a string, b []string) {
for _, v := range b {
if a == v {
return
}
}
os.Args = append([]string{os.Args[0], "serve"}, os.Args[1:]...)
}
Would it be feasible to enhance cobra in order to generate NonRootSubCommands automatically? It should be a []string containing the names and commands of all the subcommands of root, except the selected one.
You should be able to iterate over rootCmd.Commands() to get the Name() of each and use that.
Indeed, I was going to post that :). I removed everything from main, then added a Aliases field to rootCmd (with a single string), and this is my Execute() now:
func checkRootAlias(a string, b []string) {
for _, v := range b {
if a == v {
return
}
}
os.Args = append([]string{os.Args[0], rootCmd.Aliases[0]}, os.Args[1:]...)
}
func nonRootSubCmds() (l []string) {
for _, c := range rootCmd.Commands() {
isAlias := false
for _, a := range append(c.Aliases, c.Name()) {
if a == rootCmd.Aliases[0] {
isAlias = true
break
}
}
if !isAlias {
l = append(l, c.Name())
l = append(l, c.Aliases...)
}
}
return
}
func Execute() {
checkRootAlias(os.Args[1], nonRootSubCmds())
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
Thanks @eparis!
Thanks @1138-4EB, I'm waiting for https://github.com/spf13/cobra/issues/823 too.
Most helpful comment
I can't think of a good way to do this....
In main() before you call rootCmd.Execute() you might be able to mess with os.Args to magically insert your subcommand into the argument list if it wasn't there?
I'll keep trying to think of something...