Getting Started with Cobra

To begin, you'll need to install Cobra. You can do this using Go modules. First, create a new directory for your project and initialize a new Go module:

mkdir mycliapp
cd mycliapp
go mod init mycliapp

Next, install Cobra:

go get github.com/spf13/cobra@latest

Creating Your First Command

Cobra allows you to create commands easily. Let's create a simple command-line application that has a hello command. Create a file named main.go in your project directory:

package main

import (
    "fmt"
    "os"

    "github.com/spf13/cobra"
)

func main() {
    var rootCmd = &cobra.Command{Use: "mycliapp"}

    var helloCmd = &cobra.Command{
        Use:   "hello",
        Short: "Prints 'Hello, World!'",
        Run: func(cmd *cobra.Command, args []string) {
            fmt.Println("Hello, World!")
        },
    }

    rootCmd.AddCommand(helloCmd)
    if err := rootCmd.Execute(); err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
}

Running Your Application

To run your application, execute the following command in your terminal:

go run main.go hello

You should see the output:

Hello, World!

Adding Flags to Your Command

Cobra supports flags, which allow users to customize the behavior of commands. Let's enhance our hello command to accept a name as an argument. Modify the helloCmd definition as follows:

var name string

var helloCmd = &cobra.Command{
    Use:   "hello",
    Short: "Prints a personalized greeting",
    Run: func(cmd *cobra.Command, args []string) {
        if name == "" {
            fmt.Println("Hello, World!")
        } else {
            fmt.Printf("Hello, %s!\n", name)
        }
    },
}

helloCmd.Flags().StringVarP(&name, "name", "n", "", "Name to greet")

Testing the Flag

You can now run the command with the --name flag:

go run main.go hello --name Alice

Output:

Hello, Alice!

Structuring Your Application

As your application grows, it’s a good practice to structure it into multiple files. For example, you can separate commands into their own files. Create a new directory called cmd and move the command definitions there.

  1. Create a new file cmd/hello.go:
package cmd

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

var name string

var helloCmd = &cobra.Command{
    Use:   "hello",
    Short: "Prints a personalized greeting",
    Run: func(cmd *cobra.Command, args []string) {
        if name == "" {
            fmt.Println("Hello, World!")
        } else {
            fmt.Printf("Hello, %s!\n", name)
        }
    },
}

func init() {
    helloCmd.Flags().StringVarP(&name, "name", "n", "", "Name to greet")
}
  1. Update main.go to use the new command:
package main

import (
    "os"
    "mycliapp/cmd"
)

func main() {
    if err := cmd.RootCmd.Execute(); err != nil {
        os.Exit(1)
    }
}
  1. Create a cmd/root.go file to define the root command:
package cmd

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

var RootCmd = &cobra.Command{Use: "mycliapp"}

func init() {
    RootCmd.AddCommand(helloCmd)
}

Running the Structured Application

You can still run your application in the same way:

go run main.go hello --name Bob

Output:

Hello, Bob!

Adding More Commands

You can easily add more commands to your application. For instance, let’s add a goodbye command. Create a new file cmd/goodbye.go:

package cmd

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

var goodbyeCmd = &cobra.Command{
    Use:   "goodbye",
    Short: "Prints a goodbye message",
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("Goodbye, World!")
    },
}

func init() {
    RootCmd.AddCommand(goodbyeCmd)
}

Testing the New Command

Run the goodbye command:

go run main.go goodbye

Output:

Goodbye, World!

Conclusion

Cobra is a versatile library that simplifies the creation of command-line applications in Go. Through this tutorial, you learned how to set up a basic CLI application, add commands and flags, structure your application, and extend it with additional commands.

By following best practices such as modularizing your code and using clear command structures, you can create maintainable and user-friendly command-line tools.

Learn more with useful resources