Building CLI applications in Go with Cobra
While GUIs can offer a nicer-looking interface and better user experience, command line (CLI) applications are still prevalent due to their simplicity, performance, and speed. In this article, we’ll dive into how you can get started building your own CLI application in Go with Cobra.
- What to know about building CLI applications
- Getting started with the Cobra package
- Anatomy of a CLI command
- The root command of your CLI application
- Adding commands to your CLI application
- Adding flags to your CLI app
- Learn more about building applications in Go
What to know about building CLI applications
Popular applications that use the command-line interface include Git, Docker, Kubernetes, and Homebrew. The command-line interface interacts with the operating system directly via a command shell.
Many programming languages like Go provide functionality for building CLI applications. In Go, you can use the flag package to build CLI applications without dependencies. You can also use the popular Cobra package, which is used in popular projects like Docker, Arduino, Github CLI, Kubernetes, Hugo, and Twitch. The Cobra package provides a simple interface for building command-line applications in Go fast with flexibility via the cobra-cli
binary, which generates CLI apps and files that you need to integrate the Cobra package into your applications.
Getting started with the Cobra package
With Go installed, use the following command to install Cobra in your Go workspace
(~/go
by default):
$ go install github.com/spf13/cobra-cli@latest
You’ll need to set your $GOPATH environment variable in your Bash to use the cobra-cli package. Next, create and enter a new directory for your project in your $GOPATH/src
directory (~/go/src
by default). I’ll call mine teachingCobra
:
$ mkdir teachingCobra && cd teachingCobra
Run these commands to initialize your new Cobra application:
$ go mod init teachingCobra
$ cobra-cli init
The command above will generate some files in your workspace, as shown below:
The root.go
file in the cmd
directory contains the root command that runs when your CLI application is called. The generated main.go
file has the main function, the application’s entry point.
You’ll need to build and install your CLI application whenever you make changes. You can use the build
command to build the application.
$ go build
Then you can use the ./teachingCobra
command to use your locally compiled command. Or you can install the application with the install command, which builds and installs the application to your Go binaries folder so you can use it anywhere:
$ go install
Now, let’s examine the anatomy of a CLI command to help you understand the various parts of a CLI application you can build.
Anatomy of a CLI command
As a Go developer, you’re familiar with the go CLI and at least the get
command for installing packages and modules to your workspace. Another popular command-line tool you may be familiar with is the Git CLI for version control and making commits using the commit command:
$ git commit -m "made changes to the main branch."
Every command-line tool uses the application name, commands, flags, and/or arguments.
Commands trigger specific functionalities of the application, and arguments are optional parameters on commands for the command’s functionalities. This functionality can be further modified with flags. Commands may support any combination of arguments and/or flags.
The root command of your CLI application
When you use the name of your application without additional commands and flags, the root command gets executed. To initialize a CLI application using the cobra-cli init
command on your workspace, the root.go
file in the cmd
directory contains the code for the root command of your application. Here’s the code generated by Cobra for the root command:
The Use
field is initialized with the name of your application; you can change it if you choose to rename your application. The Short
field should be a one-line (roughly 80 character) description of your app, and the Long
field should be a longer description. The Short
and Long
fields are used with the help
command and flags that are added to your application by default.
The Run
field is the function that is triggered when the command is used.
More commands can be added to your application in a similar format as the root command, and you can configure them based on the command’s functionality.
Adding commands to your CLI application
You don’t need to create a new file or function by hand to add commands to your application. You can use the cobra-cli add
command to create a new command on your initialized application. For example, let’s add a command called new
:
$ cobra-cli add new
The add
command creates a new command for your initialized cobra-cli application and adds a file to your cmd
folder. The file contains the code for executing the command, and you can make changes to the file based on the functionalities of the command.
The new
command has been added to the initialized application. In this case, the app’s name is teachingCobra
. You can execute the new
command by specifying it alongside your application name.
$ teachingCobra new
The code in the new command file is the same as the code in the root
command, and just like the root command, you can change the configurations of your new
command and add a function body to the Run
field.
Working with arguments on your CLI app
Your application might require some user input to function; Cobra also makes it easy to work with arguments. The arguments are passed via the args
parameter as an array of strings to the Run
field’s function, and you can access them individually via indexes on the array.
For example, the following command interacts with provided arguments:
Run: func(cmd *cobra.Command, args []string) {
if len(args) < 1 {
log.Fatal("You didn't specify the additional arguments\Use the --help flag for comprehensive help on how to use this tool") }
argument := args[0]
fmt.Println(argument)
}
In the Run
field above, the conditional statement checks if there are any arguments and quits the program when there are none. If there are arguments, the program continues and the first argument is passed to the argument
variable and printed out. You can try this command out in your own CLI. You may need to import the log
module in the command file.
Adding flags to your CLI app
If you’re building an application and require your users to choose from a variety of options by specification, you’ll find using flags handy for your command line application. Ideal flags are short and easy to remember.
You can add persistent flags (available to any command and all of its subcommands) or local flags assigned to only a specified command. You can think of persistent flags as being inherited by all subcommands. Let’s define flags and configurations in the init
function of the new
command file you created via Cobra.
Adding persistent flags to your CLI application
Want to add a flag to the new
command? newCmd
has a method called PersistentFlags
you can utilize, indicating the parameters via a returned String
method:
func init(){
newCmd.PersistentFlags().String("talk", "", "talk to the new command")
}
The String
method takes several arguments to initialize the flag. First is the name, second is the default value, and third is a description. In this case, the flag is talk
, the default value is an empty string, and the description is “talk to the new command.”
cmd
has a method called Flags
you can use with GetString
to fetch the flag’s provided argument. Once you have the user’s input, you can perform any necessary checks on the response:
Run: func(cmd *cobra.Command, args []string) {
talker, _ := cmd.Flags().GetString("talk")
if talker == "hello" {
fmt.Println("hi")
} else if talker == "hi" {
fmt.Println("hello")
}
}
In the code example, you anticipated that the value passed to the flag is either hello
or hi
, and then the other value is printed out in response.
Adding local flags to your CLI application
You can add local flags to your CLI application using the command’s BoolP
method of the Flags
method. The BoolP
method takes in the flag name, the flag shorthand, the value, and the usage of the flag:
newCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
The flag shorthand, in this case t
, should be one or two characters at most. You can access and use the local flag the same way you can access inputs from persistent flags using the GetString
method. As a boolean via the BoolP
method, this flag defaults to false but becomes true if the flag is present in the command.
Learn more about building applications in Go
The Cobra package is a handy tool; you can build your business logic for your application and quickly build the CLI application itself within minutes since the Cobra package provides all the framework you need.
This tutorial has taught you how to build command-line applications in Go using Cobra, from adding commands to receiving user input using arguments and options using flags.
Interested in learning more about building applications in Go? Here are some additional tutorials you might want to check out:
- Choosing a Go Framework: Gin vs. Echo
- How to Set up a Jenkins CI/CD Pipeline for Your Golang App
- Diving into Static Single Assignment with the Go Compiler
- How to Build an Authentication Microservice in Golang from Scratch
This blog post was created as part of the Mattermost Community Writing Program and is published under the CC BY-NC-SA 4.0 license. To learn more about the Mattermost Community Writing Program, check this out.