Cobra CLI Framework
Cobra is a powerful library for creating modern CLI applications in Go. Used by kubectl, Hugo, GitHub CLI, and many other popular tools. Provides commands, subcommands, flags, and automatic help generation.
Use Case
Use Cobra when you need to:
- Build complex CLI tools with subcommands
- Provide consistent flag handling
- Generate automatic help and documentation
- Create professional command-line interfaces
Installation
1go get -u github.com/spf13/cobra@latest
Code
Basic Structure
1package main
2
3import (
4 "fmt"
5 "os"
6
7 "github.com/spf13/cobra"
8)
9
10var rootCmd = &cobra.Command{
11 Use: "myapp",
12 Short: "A brief description of your application",
13 Long: `A longer description that spans multiple lines and likely contains
14examples and usage of using your application.`,
15}
16
17func main() {
18 if err := rootCmd.Execute(); err != nil {
19 fmt.Fprintln(os.Stderr, err)
20 os.Exit(1)
21 }
22}
Examples
Example 1: Simple Command with Flags
1package main
2
3import (
4 "fmt"
5 "github.com/spf13/cobra"
6)
7
8var (
9 verbose bool
10 output string
11)
12
13var rootCmd = &cobra.Command{
14 Use: "greet [name]",
15 Short: "Greet someone",
16 Args: cobra.ExactArgs(1),
17 Run: func(cmd *cobra.Command, args []string) {
18 name := args[0]
19 greeting := fmt.Sprintf("Hello, %s!", name)
20
21 if verbose {
22 greeting = fmt.Sprintf("Hello there, %s! Nice to meet you!", name)
23 }
24
25 if output == "json" {
26 fmt.Printf(`{"greeting": "%s"}`, greeting)
27 } else {
28 fmt.Println(greeting)
29 }
30 },
31}
32
33func init() {
34 rootCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Verbose output")
35 rootCmd.Flags().StringVarP(&output, "output", "o", "text", "Output format (text|json)")
36}
37
38func main() {
39 rootCmd.Execute()
40}
Usage:
1$ myapp greet John
2Hello, John!
3
4$ myapp greet John --verbose
5Hello there, John! Nice to meet you!
6
7$ myapp greet John -o json
8{"greeting": "Hello, John!"}
Example 2: Subcommands
1package main
2
3import (
4 "fmt"
5 "github.com/spf13/cobra"
6)
7
8var rootCmd = &cobra.Command{
9 Use: "app",
10 Short: "My application",
11}
12
13var initCmd = &cobra.Command{
14 Use: "init",
15 Short: "Initialize the application",
16 Run: func(cmd *cobra.Command, args []string) {
17 fmt.Println("Initializing...")
18 },
19}
20
21var runCmd = &cobra.Command{
22 Use: "run",
23 Short: "Run the application",
24 Run: func(cmd *cobra.Command, args []string) {
25 fmt.Println("Running...")
26 },
27}
28
29var configCmd = &cobra.Command{
30 Use: "config",
31 Short: "Manage configuration",
32}
33
34var configGetCmd = &cobra.Command{
35 Use: "get [key]",
36 Short: "Get configuration value",
37 Args: cobra.ExactArgs(1),
38 Run: func(cmd *cobra.Command, args []string) {
39 fmt.Printf("Getting config: %s\n", args[0])
40 },
41}
42
43var configSetCmd = &cobra.Command{
44 Use: "set [key] [value]",
45 Short: "Set configuration value",
46 Args: cobra.ExactArgs(2),
47 Run: func(cmd *cobra.Command, args []string) {
48 fmt.Printf("Setting %s = %s\n", args[0], args[1])
49 },
50}
51
52func init() {
53 // Add commands to root
54 rootCmd.AddCommand(initCmd)
55 rootCmd.AddCommand(runCmd)
56 rootCmd.AddCommand(configCmd)
57
58 // Add subcommands to config
59 configCmd.AddCommand(configGetCmd)
60 configCmd.AddCommand(configSetCmd)
61}
62
63func main() {
64 rootCmd.Execute()
65}
Usage:
1$ app init
2Initializing...
3
4$ app config get database.host
5Getting config: database.host
6
7$ app config set database.host localhost
8Setting database.host = localhost
Example 3: Persistent Flags and PreRun
1package main
2
3import (
4 "fmt"
5 "github.com/spf13/cobra"
6)
7
8var (
9 cfgFile string
10 debug bool
11)
12
13var rootCmd = &cobra.Command{
14 Use: "app",
15 Short: "My application",
16 PersistentPreRun: func(cmd *cobra.Command, args []string) {
17 // Runs before any command
18 if debug {
19 fmt.Println("Debug mode enabled")
20 }
21 if cfgFile != "" {
22 fmt.Printf("Using config file: %s\n", cfgFile)
23 }
24 },
25}
26
27var serveCmd = &cobra.Command{
28 Use: "serve",
29 Short: "Start the server",
30 PreRun: func(cmd *cobra.Command, args []string) {
31 // Runs before this specific command
32 fmt.Println("Preparing to serve...")
33 },
34 Run: func(cmd *cobra.Command, args []string) {
35 fmt.Println("Server started!")
36 },
37 PostRun: func(cmd *cobra.Command, args []string) {
38 // Runs after this specific command
39 fmt.Println("Server stopped")
40 },
41}
42
43func init() {
44 // Persistent flags available to all commands
45 rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file")
46 rootCmd.PersistentFlags().BoolVar(&debug, "debug", false, "debug mode")
47
48 rootCmd.AddCommand(serveCmd)
49}
50
51func main() {
52 rootCmd.Execute()
53}
Example 4: Required Flags and Validation
1package main
2
3import (
4 "fmt"
5 "github.com/spf13/cobra"
6)
7
8var (
9 username string
10 password string
11 port int
12)
13
14var loginCmd = &cobra.Command{
15 Use: "login",
16 Short: "Login to the service",
17 PreRunE: func(cmd *cobra.Command, args []string) error {
18 // Validation before running
19 if port < 1 || port > 65535 {
20 return fmt.Errorf("invalid port: %d", port)
21 }
22 return nil
23 },
24 RunE: func(cmd *cobra.Command, args []string) error {
25 // Use RunE to return errors
26 fmt.Printf("Logging in as %s on port %d\n", username, port)
27 return nil
28 },
29}
30
31func init() {
32 loginCmd.Flags().StringVarP(&username, "username", "u", "", "Username (required)")
33 loginCmd.Flags().StringVarP(&password, "password", "p", "", "Password (required)")
34 loginCmd.Flags().IntVar(&port, "port", 8080, "Port number")
35
36 // Mark flags as required
37 loginCmd.MarkFlagRequired("username")
38 loginCmd.MarkFlagRequired("password")
39}
40
41func main() {
42 rootCmd := &cobra.Command{Use: "app"}
43 rootCmd.AddCommand(loginCmd)
44 rootCmd.Execute()
45}
Example 5: Cobra Generator (Quick Start)
1# Install cobra-cli
2go install github.com/spf13/cobra-cli@latest
3
4# Initialize new CLI app
5cobra-cli init
6
7# Add commands
8cobra-cli add serve
9cobra-cli add config
10cobra-cli add create
11
12# Project structure created:
13# βββ cmd/
14# β βββ root.go
15# β βββ serve.go
16# β βββ config.go
17# β βββ create.go
18# βββ main.go
19# βββ go.mod
Common Patterns
Argument Validation
1var cmd = &cobra.Command{
2 Use: "example",
3 Args: cobra.MinimumNArgs(1), // At least 1 arg
4 // Args: cobra.ExactArgs(2), // Exactly 2 args
5 // Args: cobra.RangeArgs(1, 3), // Between 1 and 3 args
6 // Args: cobra.NoArgs, // No args allowed
7 Run: func(cmd *cobra.Command, args []string) {
8 // ...
9 },
10}
Custom Validation
1var cmd = &cobra.Command{
2 Use: "example",
3 Args: func(cmd *cobra.Command, args []string) error {
4 if len(args) < 1 {
5 return fmt.Errorf("requires at least 1 arg")
6 }
7 if args[0] != "valid" {
8 return fmt.Errorf("invalid argument: %s", args[0])
9 }
10 return nil
11 },
12 Run: func(cmd *cobra.Command, args []string) {
13 // ...
14 },
15}
Version Command
1var version = "1.0.0"
2
3var versionCmd = &cobra.Command{
4 Use: "version",
5 Short: "Print the version number",
6 Run: func(cmd *cobra.Command, args []string) {
7 fmt.Printf("Version: %s\n", version)
8 },
9}
10
11func init() {
12 rootCmd.AddCommand(versionCmd)
13}
Notes
- Use
PersistentFlagsfor flags available to all subcommands - Use
Flagsfor command-specific flags PreRun,Run,PostRunprovide lifecycle hooks- Use
RunEinstead ofRunto return errors - Cobra automatically generates help and usage
Gotchas/Warnings
- β οΈ Flag parsing: Flags must come after the command name
- β οΈ Required flags: Use
MarkFlagRequired()for validation - β οΈ Persistent flags: Defined on parent, available to children
- β οΈ Args validation: Use built-in validators or custom functions
comments powered by Disqus