Cobra CLI Framework
Cobra is a library for creating powerful modern CLI applications in Go, used by Kubernetes, Hugo, GitHub CLI, and many more.
Core Concepts
Commands represent actions, Args are things, Flags are modifiers. Follow the pattern: APPNAME COMMAND ARG --FLAG.
Project Structure
appName/
cmd/
root.go
subcommand.go
main.go
Creating Commands
Root Command
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
)
var rootCmd = &cobra.Command{
Use: "myapp",
Short: "Brief description",
Long: `Detailed description...`,
Run: func(cmd *cobra.Command, args []string) {
// Action here
},
}
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
Subcommands
var versionCmd = &cobra.Command{
Use: "version",
Short: "Print version",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("v1.0.0")
},
}
func init() {
rootCmd.AddCommand(versionCmd)
}
Error Handling with RunE
var cmd = &cobra.Command{
Use: "delete [name]",
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return fmt.Errorf("name required")
}
return deleteResource(args[0])
},
}
Flags
Persistent Flags (cascade to children)
var verbose bool
func init() {
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
}
Local Flags (command-specific)
var source string
func init() {
cmd.Flags().StringVarP(&source, "source", "s", "", "source directory")
}
Required Flags
func init() {
rootCmd.Flags().StringVarP(®ion, "region", "r", "", "AWS region")
rootCmd.MarkFlagRequired("region")
}
Flag Groups
func init() {
rootCmd.Flags().StringVarP(&user, "username", "u", "", "Username")
rootCmd.Flags().StringVarP(&pass, "password", "p", "", "Password")
rootCmd.MarkFlagsRequiredTogether("username", "password")
rootCmd.MarkFlagsMutuallyExclusive("json", "yaml")
}
Count/Array Flags
var verbose int
var files []string
func init() {
rootCmd.PersistentFlags().CountVarP(&verbose, "verbose", "v", "verbosity (-v, -vv, -vvv)")
rootCmd.Flags().StringArrayVarP(&files, "file", "f", []string{}, "input files")
}
Argument Validation
var cmd = &cobra.Command{
Use: "create [name]",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) { ... },
}
Built-in validators:
NoArgs- no positional args allowedArbitraryArgs- any number (default)MinimumNArgs(int)- at least N argsMaximumNArgs(int)- at most N argsExactArgs(int)- exactly N argsRangeArgs(min, max)- between min and maxOnlyValidArgs- only values in ValidArgs
Combined validation:
Args: cobra.MatchAll(cobra.ExactArgs(2), cobra.OnlyValidArgs),
PreRun/PostRun Hooks
Execution order: PersistentPreRun -> PreRun -> Run -> PostRun -> PersistentPostRun
var rootCmd = &cobra.Command{
Use: "myapp",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
// Runs before any child command
},
PreRun: func(cmd *cobra.Command, args []string) {
// Runs before this command's Run
},
Run: func(cmd *cobra.Command, args []string) {
// Main logic
},
PostRun: func(cmd *cobra.Command, args []string) {
// Runs after Run
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
// Runs after any child command
},
}
Shell Completions
Static Completions
var cmd = &cobra.Command{
Use: "get [resource]",
ValidArgs: []string{"pod", "service", "deployment"},
Run: func(cmd *cobra.Command, args []string) { ... },
}
Dynamic Completions
var cmd = &cobra.Command{
Use: "status [release]",
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]cobra.Completion, cobra.ShellCompDirective) {
return getReleases(toComplete), cobra.ShellCompDirectiveNoFileComp
},
Run: func(cmd *cobra.Command, args []string) { ... },
}
Flag Completions
cmd.RegisterFlagCompletionFunc("output", func(cmd *cobra.Command, args []string, toComplete string) ([]cobra.Completion, cobra.ShellCompDirective) {
return []cobra.Completion{"json", "yaml", "table"}, cobra.ShellCompDirectiveNoFileComp
})
ShellCompDirective Values
ShellCompDirectiveDefault- default behaviorShellCompDirectiveNoSpace- no space after completionShellCompDirectiveNoFileComp- no file completionShellCompDirectiveFilterFileExt- filter by file extensionShellCompDirectiveFilterDirs- directory names only
Help Customization
cmd.SetHelpCommand(customHelpCmd)
cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) { ... })
cmd.SetHelpTemplate(customTemplate)
cmd.SetUsageFunc(func(cmd *cobra.Command) error { ... })
cmd.SetUsageTemplate(customTemplate)
Version Flag
var rootCmd = &cobra.Command{
Use: "myapp",
Version: "1.0.0",
}
Command Groups
func init() {
rootCmd.AddGroup(
&cobra.Group{ID: "management", Title: "Management Commands:"},
&cobra.Group{ID: "query", Title: "Query Commands:"},
)
listCmd.GroupID = "query"
createCmd.GroupID = "management"
rootCmd.AddCommand(listCmd, createCmd)
}
Plugin Support (kubectl-style)
rootCmd := &cobra.Command{
Use: "kubectl-myplugin",
Annotations: map[string]string{
cobra.CommandDisplayNameAnnotation: "kubectl myplugin",
},
}
Common Patterns
Traverse Children Flags
rootCmd := &cobra.Command{
Use: "myapp",
TraverseChildren: true, // Parse parent flags before child command
}
Silence Errors/Usage
cmd.SilenceErrors = true // Don't print error prefix
cmd.SilenceUsage = true // Don't print usage on error
Hidden Commands
cmd.Hidden = true
Deprecated Commands
cmd.Deprecated = "use 'newcmd' instead"
Examples Index
| File | Description |
|---|---|
| references/_examples/basic_app.go | Minimal CLI application |
| references/_examples/subcommands.go | Nested subcommands |
| references/_examples/flags.go | Flag patterns |
| references/_examples/hooks.go | PreRun/PostRun hooks |
| references/_examples/completions.go | Shell completions |
Integration with Viper
import "github.com/spf13/viper"
func init() {
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file")
rootCmd.PersistentFlags().StringP("author", "a", "", "author name")
viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
}
Further Reading
- User Guide - Complete user guide documentation
- Shell Completions - Detailed completion documentation
- Active Help - Context-sensitive help messages
Converted and distributed by TomeVault — claim your Tome and manage your conversions.