close
close
how to add a subcommand options in cobra

how to add a subcommand options in cobra

3 min read 23-01-2025
how to add a subcommand options in cobra

Cobra is a powerful Go library for creating elegant and intuitive command-line interfaces (CLIs). One of its key features is the ability to create subcommands, allowing you to organize your CLI into logical groups of related functionalities. But often, you'll need to add options to those subcommands. This article will guide you through the process, demonstrating how to add options to your Cobra subcommands, along with best practices for clear and user-friendly CLI design.

Understanding Cobra's Structure

Before diving into adding options, let's quickly review Cobra's basic structure. A Cobra application typically consists of a root command and one or more subcommands. Each command can have its own flags (options) and arguments.

package main

import (
	"fmt"
	"github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
	Use:   "mycli",
	Short: "My Awesome CLI",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("Root command executed")
	},
}

func main() {
	if err := rootCmd.Execute(); err != nil {
		fmt.Println(err)
	}
}

Adding Subcommands and Options

Let's extend this example by adding a user subcommand with options for adding and listing users.

package main

import (
	"fmt"
	"github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
	Use:   "mycli",
	Short: "My Awesome CLI",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("Root command executed")
	},
}

var userCmd = &cobra.Command{
	Use:   "user",
	Short: "Manage users",
}

var addUserCmd = &cobra.Command{
	Use:   "add",
	Short: "Add a new user",
	Run: func(cmd *cobra.Command, args []string) {
		username, _ := cmd.Flags().GetString("username")
		email, _ := cmd.Flags().GetString("email")
		fmt.Printf("Adding user: %s (%s)\n", username, email)
	},
}

func init() {
	addUserCmd.Flags().StringP("username", "u", "", "Username")
	addUserCmd.Flags().StringP("email", "e", "", "Email address")
	userCmd.AddCommand(addUserCmd)
	rootCmd.AddCommand(userCmd)
}

func main() {
	if err := rootCmd.Execute(); err != nil {
		fmt.Println(err)
	}
}

In this enhanced example:

  • We define a userCmd subcommand.
  • An addUserCmd subcommand is created within userCmd.
  • addUserCmd uses cmd.Flags().StringP() to define two flags: --username (short -u) and --email (short -e). The second argument is the default value (empty string here).
  • The init() function registers the subcommands and their flags. This is crucial for Cobra to correctly parse the commands and options.
  • The Run function for addUserCmd retrieves the flag values using cmd.Flags().GetString(). Note the error handling (we're ignoring errors for brevity here, but in a real application, you should handle them appropriately).

More Advanced Options

Cobra offers a wide variety of flag types beyond strings:

  • BoolP: For boolean flags (true/false).
  • IntP: For integer flags.
  • Float64P: For floating-point number flags.
  • StringSliceP: For a slice of strings.
  • StringArray: For a string array (similar to StringSliceP)
  • Duration: for time.Duration values.

You can choose the appropriate type based on your subcommand's requirements.

Best Practices

  • Clear and Concise Names: Use descriptive names for your commands and options.
  • Short Flags: Utilize short flags (-u, -e) for common options to make the CLI more concise.
  • Help Text: Provide helpful descriptions for all your commands and flags using the Short and Long fields in the cobra.Command struct. Cobra automatically generates help messages based on this information. This is critical for usability.
  • Validation: Add validation to your flag values within the Run function to ensure data integrity.
  • Error Handling: Always handle potential errors, especially when retrieving flag values.

Example with Multiple Subcommands and Options

Let's expand the example to include a list subcommand under user :

package main

import (
	"fmt"
	"github.com/spf13/cobra"
)

// ... (rootCmd remains the same) ...

var userCmd = &cobra.Command{
	Use:   "user",
	Short: "Manage users",
}

var addUserCmd = &cobra.Command{ // ... (addUserCmd remains the same) ... }

var listUserCmd = &cobra.Command{
	Use:   "list",
	Short: "List all users",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("Listing users...") // Add your user listing logic here.
	},
}

func init() {
	addUserCmd.Flags().StringP("username", "u", "", "Username")
	addUserCmd.Flags().StringP("email", "e", "", "Email address")
	userCmd.AddCommand(addUserCmd, listUserCmd)
	rootCmd.AddCommand(userCmd)
}

func main() {
	if err := rootCmd.Execute(); err != nil {
		fmt.Println(err)
	}
}

This illustrates how to add multiple subcommands under a parent command, each with its own set of options. Remember to replace "Listing users..." with your actual user listing logic.

By following these guidelines, you can create powerful and user-friendly CLIs using Cobra's subcommand and option capabilities. Remember to consult the official Cobra documentation for the most up-to-date information and advanced features.

Related Posts