CLI Applications in Go – fun, effective and very easy to create

In previous blogs about Go we have looked at the Go programming language and how to run go in AWS Lambda. We also saw how to cross compile Go code so that it runs on Linux, Mac and Windows platforms. We also looked at the AWS SDK for Go that makes it easy to integrate Go applications with the full suite of AWS services. This time we are going to create Command Line Interface (CLI) applications in Go. Lets get going!

Command Line Applications

Command Line Interface ‘CLI’ applications are tiny applications with a very specific focus. These applications are often called ‘tools’ and help us with common operations that we often want to automate. When we take a closer look at command line applications we see that these applications are structured around commands, arguments and flags. Commands represent actions/verbs, Args are things/nouns/objects and Flags are modifiers/adjective (property/state) for actions.

For example:

#       action  thing/object   property/state
$ myapp verb    noun           --adjective

#     action   thing/object                                       state
$ git clone    git@github.com:binxio/cfn-certificate-provider.git --bare

#    action   thing/object
$ go get -u   github.com/aws/aws-sdk-go/...      

Cobra

To create CLI applications, we will use Cobra, a library for creating powerful modern CLI applications. Cobra is used by popular Go projects like Kubernetes, Docker, OpenShift, Hugo and others to create their CLI interfaces. So the next time you type ‘docker run -it ubuntu’, you know it is powered by Cobra!

Code Generator

Cobra comes with a code generator/scaffold that can be run by typing cobra. Cobra makes it very easy to create CLI applications because it supports common operations like initializing a new project structure that contains bootstrap code and adding commands that contains skeleton code. The init command creates a new project and the add command creates new commands to the application.

Installing Cobra

To install Cobra type:

$ go get github.com/spf13/cobra/cobra

$ cobra --help
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.
...

Create Greeter

Lets create a ‘greeter’ app that prints a greeting message to the console.

$ cobra init --author "Dennis Vriend" --license apache github.com/dnvriend/greeter

The command created the following directory structure containing an Apache2 license file, a ‘main.go’ file that bootstraps the CLI application and a single ‘root.go’ command in the ‘cmd’ package. The root command is a container for commands. We haven’t added any commands yet.

.
├── LICENSE
├── cmd
│   └── root.go
└── main.go

Lets run the application:

$ go run github.com/dnvriend/greeter
A longer content 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.
This application is a tool to generate the needed files
to quickly create a Cobra application.

The output comes from text that has been configured at the ‘root.go’ command. Lets add a command.

Add Greet Command

$ cobra add greet -t github.com/dnvriend/greeter

We now have the following directory structure:

.
├── LICENSE
├── cmd
│   ├── greet.go
│   └── root.go
└── main.go

The ‘greet.go’ command has been added. Lets run the application:

$ go run github.com/dnvriend/greeter
A longer content 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.
This application is a tool to generate the needed files
to quickly create a Cobra application.

Usage:
  greeter [command]

Available Commands:
  greet       A brief content of your command
  help        Help about any command

Flags:
      --config string   config file (default is $HOME/.greeter.yaml)
  -h, --help            help for greeter
  -t, --toggle          Help message for toggle

Use "greeter [command] --help" for more information about a command.

$ go run github.com/dnvriend/greeter greet
greet called

The message is quite boring, lets edit the greet.go file:

package cmd

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

var greetCmd = &cobra.Command{
    Use:   "greet",
    Short: "Prints a greet message",
    Long: `Prints a greet message`,
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("Hello World! " + strings.Join(args, " "))
    },
}

func init() {
    rootCmd.AddCommand(greetCmd)
}

Lets run the ‘greeter’:

$ go run github.com/dnvriend/greeter greet a b c
Hello World! a b c

Adding a Flag

Lets add the ‘name’ flag to the ‘greet’ command. To do that, we must edit the ‘greet.go’ file and add the ‘name’ flag to the greetCmd. After the name flag has been added, the flag can be queried in the Run command handler.

package cmd

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

var greetCmd = &cobra.Command{
    Use:   "greet",
    Short: "Prints a greet message",
    Long: `Prints a greet message`,
    Run: func(cmd *cobra.Command, args []string) {
        name := cmd.Flag("name")
        if name.Value.String() == "" {
            fmt.Printf("Hello World! %s\n", strings.Join(args, " "))
        } else {
            fmt.Printf("Hello %s, %s\n", name.Value.String(), strings.Join(args, " "))
        }
    },
}

func init() {
    rootCmd.AddCommand(greetCmd)
    greetCmd.Flags().StringP("name", "n", "", "The name to use")
}

Greeter is now finished. Lets install the application in the ‘bin’ folder to use.

$ go install github.com/dnvriend/greeter

$ $GOPATH/bin/greeter greet --name "Dennis Vriend" a b c
Hello Dennis Vriend, a b c

Conclusion

Cobra makes it possible to create powerful CLI applications powered by Go. Cobra comes with a code generator for quickly bootstrapping CLI applications. Cobra also provides a library for implementing CLI applications. Cobra provides Commands to define behavior and Flags to modify behavior of your CLI apps. Next time we’ll look at how to integrate the Go AWS SDK with Cobra to create handy utilities that help us with common tasks.

Share this article: Tweet this post / Post on LinkedIn