Cobra, an advanced CLI library

Like cli, cobra is a package for writing client binaries but takes a different approach. In cobra, we have to create separate commands and use them in our main app. We can install cobra using dep. Let's create our cobra project repository:

mkdir -p $GOPATH/src/github.com/git-user/chapter8/cobraCLI

Now, let's create another directory called cmd in the project for defining commands. In cobra apps, there will be a root command. This can have multiple subcommands. We can implement the same example we used for the flag package. Input the name and age from the command line using cobra.

Let's define a root command:

var rootCmd = &cobra.Command{
Use: "details",
Short: "This project takes student information",
Long: `A long string about description`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
name := cmd.PersistentFlags().Lookup("name").Value
age := cmd.PersistentFlags().Lookup("age").Value
log.Printf("Hello %s (%s years), Welcome to the command line
world", name, age)
},
}

This creates a command with "details" as a command. It has few properties, such as Use, Short, Long, Args and, Run. See the following table to find their exact meaning:

Parameter Meaning
Use Name of the command
Short Short description
Long Long description
Args Number of arguments expected
Run Process inputs after collection

 

In the Run command, we are expecting two arguments: name and age. However, in order to collect them, we have to define them. Where can we define them? Cobra asks the developer to define them in a special function called Execute:

// Execute is Cobra logic start point
func Execute() {
rootCmd.PersistentFlags().StringP("name", "n", "stranger", "Name of
the student")
rootCmd.PersistentFlags().IntP("age", "a", 25, "Age of the student")

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

We need to use the previously defined root command to attach the flags. PersistentFlags has various types that can be used to collect flags. Now, create the main program and import this command:

touch $GOPATH/src/github.com/git-user/chapter8/cobraCLI/main.go

Now, in this file, you can import the command and call the Execute function:

package main

import "github.com/git-user/chapter8/cobraExample/cmd"

func main() {
cmd.Execute()
}

That's it. We have a client application that can be used to collect the name and age of the student. When we build this, it generates a binary:

go build $GOPATH/src/github.com/git-user/chapter8/cobraCLI

Now, we can run that binary as a client tool:

./cobraExample details -n Albert -a 23

It prints a log to the console:

Hello Albert (23 years), Welcome to the command line world

We can also pass flags in a different order:

./cobraExample details --age=23 --name=Albert

We can also create many subcommands on top of this command and do a lot more. This is just a basic example. We will look at an advanced example in the next section, where you will implement the same with cobra.

Later in this chapter, we'll discuss creating REST clients in Go. Before that, you should know how to make HTTP requests from a Go program. Although this is possible with Go's built-in net/http package, we need a more intuitive package. In the next section, we'll look at grequests, a similar package to Python's Requests for making HTTP requests.