Customizing Your CLI
In this tutorial, we’ll build upon the basic CLI from the previous tutorial and add customization features like flags, custom descriptions, and configuration options.
Prerequisites
- Completed the My First CLI tutorial
- Your
my-cli
project from the previous tutorial
Steps
-
Customize the Root Command Description
Let’s start by updating the main application description. Open the
cmd/root.go
file and see how we transform a basic command into a professional one:Beforevar rootCmd = &cobra.Command{ Use: "my-cli", Short: "A brief description of your application", Long: `A longer description that spans multiple lines and likely contains examples and usage of using your application. For example: Cobra is a CLI library for Go that empowers applications.`, // Uncomment the following line if your bare application // has an action associated with it: // Run: func(cmd *cobra.Command, args []string) { }, }
Aftervar rootCmd = &cobra.Command{ Use: "my-cli", Short: "A powerful CLI tool built with Cobra", Long: `My CLI is a demonstration application built with Cobra. This application shows how to create professional command-line tools with proper flag handling, subcommands, and configuration.`, // Uncomment the following line if your bare application // has an action associated with it: // Run: func(cmd *cobra.Command, args []string) { }, }
-
Add Global Flags
Let’s see how adding global flags transforms your CLI from basic to feature-rich. Here’s how the
init()
function evolves:Beforefunc init() { rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") }
Aftervar verbose bool func init() { rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output") rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") }
-
Enhance the Serve Command
Watch how a simple serve command evolves into a fully-featured server command with flags and verbose output:
Beforevar serveCmd = &cobra.Command{ Use: "serve", Short: "A brief description of your command", Long: `A longer description that spans multiple lines and likely contains examples and usage of using your command.`, Run: func(cmd *cobra.Command, args []string) { fmt.Println("serve called") }, } func init() { rootCmd.AddCommand(serveCmd) }
Aftervar port int var host string var serveCmd = &cobra.Command{ Use: "serve", Short: "Start the application server", Long: `Start the application server on the specified host and port. The serve command will start a web server that can handle requests and provide API endpoints for your application.`, Run: func(cmd *cobra.Command, args []string) { if verbose { fmt.Printf("Starting server on %s:%d\n", host, port) fmt.Println("Verbose mode enabled") } else { fmt.Printf("Server starting on %s:%d\n", host, port) } }, } func init() { rootCmd.AddCommand(serveCmd) serveCmd.Flags().IntVarP(&port, "port", "p", 8080, "Port to run the server on") serveCmd.Flags().StringVarP(&host, "host", "H", "localhost", "Host to bind the server to") }
-
Test Your Enhanced CLI
Build and test your updated CLI:
go build -o my-cli
./my-cli --help
A powerful CLI tool built with Cobra
My CLI is a demonstration application built with Cobra.
This application shows how to create professional command-line
tools with proper flag handling, subcommands, and configuration.
Usage:
my-cli [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
help Help about any command
serve Start the application server
Flags:
-h, --help help for my-cli
-t, --toggle Help message for toggle
-v, --verbose verbose output
-
Test the Serve Command with Flags
Try out the serve command with different flag combinations:
./my-cli serve --help
Start the application server on the specified host and port.
The serve command will start a web server that can handle requests
and provide API endpoints for your application.
Usage:
my-cli serve [flags]
Flags:
-h, --help help for serve
-H, --host string Host to bind the server to (default "localhost")
-p, --port int Port to run the server on (default 8080)
Global Flags:
-v, --verbose verbose output
Test with custom port and verbose mode:
./my-cli serve --port 3000 --host 0.0.0.0 --verbose
Starting server on 0.0.0.0:3000
Verbose mode enabled
-
Add Input Validation
See how adding validation transforms your command from basic functionality to production-ready code:
BeforeRun: func(cmd *cobra.Command, args []string) { if verbose { fmt.Printf("Starting server on %s:%d\n", host, port) fmt.Println("Verbose mode enabled") } else { fmt.Printf("Server starting on %s:%d\n", host, port) } },
AfterRun: func(cmd *cobra.Command, args []string) { if port < 1 || port > 65535 { fmt.Fprintf(os.Stderr, "Error: port must be between 1 and 65535\n") os.Exit(1) } if verbose { fmt.Printf("Starting server on %s:%d\n", host, port) fmt.Println("Verbose mode enabled") fmt.Println("Configuration validated successfully") } else { fmt.Printf("Server starting on %s:%d\n", host, port) } },
Summary
In this tutorial, you’ve learned how to:
- Customize command descriptions with the
Short
andLong
fields - Add global flags that work across all commands using
PersistentFlags()
- Create command-specific flags with
Flags()
- Use different flag types (
bool
,int
,string
) - Implement flag shortcuts with single letters
- Add basic input validation
- Access global flags from subcommands
Your CLI now has proper help text, configurable options, and professional command-line behavior!
Next Steps
- Try adding more commands with
cobra-cli add [command-name]
- Explore configuration files with Viper integration
- Add persistent configuration and environment variable support