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-cliproject from the previous tutorial
Steps
-
Customize the Root Command Description
Let’s start by updating the main application description. Open the
cmd/root.gofile 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 --helpA powerful CLI tool built with CobraMy CLI is a demonstration application built with Cobra.This application shows how to create professional command-linetools with proper flag handling, subcommands, and configuration.Usage:my-cli [command]Available Commands:completion Generate the autocompletion script for the specified shellhelp Help about any commandserve Start the application serverFlags:-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 --helpStart the application server on the specified host and port.The serve command will start a web server that can handle requestsand 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 outputTest with custom port and verbose mode:
./my-cli serve --port 3000 --host 0.0.0.0 --verboseStarting server on 0.0.0.0:3000Verbose 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
ShortandLongfields - 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