How to create CLI Applications in Go using Cobra and Viper”
This article will go through a basic Go program that leverages the Cobra and Viper libraries to build a simple Command-Line Interface (CLI) application. The Cobra library is primarily used for creating robust modern CLI applications, and Viper is intended to work with Cobra for configuration solution purposes.
Table of Contents:
- Real World Uses-Case and Adoption in Open Source
- Importing Cobra and Viper
- Adding a Persistent Flag
- Setting Default Configuration
- Root Command’s Run Function
- Executing the CLI
- Using the CLI tool
Real World Uses-Case and Adoption in Open Source
Cobra and Viper are incredibly versatile libraries in Go and have found many real-world use cases.
Cobra is widely used for creating robust modern CLI (Command Line Interface) applications. With features like command nesting, global flags, and powerful help generation, it offers a comprehensive solution for creating complex command-based applications. Real-world applications include:
- Building tools for system administration.
- Automating repetitive tasks.
- Building testing frameworks.
- Creating CLIs for controlling larger software packages or services.
Viper, on the other hand, is designed for application configuration. It offers a unified API to access configuration variables from different sources - environment variables, command-line flags, configuration files in various formats (JSON, TOML, YAML), remote config systems, or direct values. Real-world applications include any software requiring flexible configuration, such as web servers, game servers, database connectors, etc.
Many famous open-source projects use Cobra and Viper. These include:
- Kubernetes (k8s): Kubernetes, a widely adopted container orchestration system, uses Cobra for its CLI
- Hugo: Hugo, a popular static site generator written in Go, uses Cobra and Viper. Cobra provides the CLI interface, and Viper handles the site configuration.
- Docker (CLI): Docker, a platform that automates the deployment, scaling, and management of applications, uses Cobra for its command-line interface.
- CockroachDB: CockroachDB, an open-source, distributed SQL database, uses Cobra for its command-line interface.
- rkt: rkt, a security-minded, standards-based container runtime, uses Cobra for its CLI. By adopting these libraries, these projects have been able to focus more on their core functionalities, leaving the complexities of command parsing, configuration management, and user interface to Cobra and Viper.
Importing Cobra and Viper
Firstly, we import the necessary packages:
os are standard Go libraries for formatting and operating system functionalities. The
viper packages are used to build and manage the CLI configuration.
Creating the CLI Root Command
The next step is to create the root command for the CLI. This command will be executed if no other subcommands are provided.
Use field represents the command’s name when called, and
Short is the brief description of the command.
Adding a Persistent Flag
Next, we add a persistent flag to the root command. As the name suggests, a persistent flag remains consistent across the entire CLI application.
Binding the Flag to Viper Configuration
After defining the flag, we bind it to Viper’s configuration:
This allows us to use Viper’s features with the flag, such as default values and reading from a configuration file.
Setting Default Configuration
Then we set the default values for our configurations. This value will be used if no other value is provided:
Reading Configuration from a File
Next, we set up Viper to read configuration values from a file:
Viper will look for a file named
config in the current directory.
Root Command’s Run Function
We define what happens when the root command runs:
When the root command is run, it fetches the “message” configuration value and prints it out.
The next part of the code adds two subcommands to our CLI:
version command prints the version of our CLI, and the
sayhello command prints “Hello!”.
Executing the CLI
Finally, the CLI application is executed:
Using the CLI tool
To use this CLI tool, first, you need to build it. Run
go build in the directory with your Go source code to create an executable. For example, this command will produce an executable named
mycli if your source code file is named
Once built, you can run the CLI tool using the
./mycli command. Since we didn’t provide subcommands, the root command will execute and print the message from the configuration or the default message.
To use the subcommands, append them after the executable’s name. For example, the
./mycli version will run the
version subcommand and print
mycli v0.1. Similarly,
./mycli sayhello will run the
sayhello subcommand and print
message flag can be passed to any command. It’s a persistent flag, so it’s available for all commands and subcommands. Use
--message to set the message. For instance,
./mycli -m "This is a custom message" will print
"This is a custom message" instead of the default message or the message from the configuration file.
To make changes to the configuration, you can create a
config.yaml file in the same directory with your specified settings. For instance:
When you run the
./mycli command now, it will print
"This is a message from the config file.". If you pass a message with the
-m flag, the flag’s value will take precedence over the configuration file.
This simple CLI tool is very flexible. You can add as many commands and flags as you need and manage complex configurations with Viper.
If there’s any error during execution, the program prints the error and exits with a status code of
1, indicating a failure.
To call the
version subcommands of your CLI tool, you’ll append them to the root command.
Here’s how you’d use the
It should print out
Hello! to the console when you run this.
And here’s how you’d use the
When you run this, it should print out
mycli v0.1 to the console.
These subcommands are called directly from the command line and execute the respective function associated with them in your Go program. For example, the
sayhello subcommand triggers the function that prints out
Hello!, while the
version subcommand triggers the function that prints out
You can add the
--message flag to these commands if you want to display a custom message instead. For example:
This would print
Custom Hello Message! instead of the default
Hello!. Similarly, you can add the message flag to the
This code creates a straightforward command-line interface (CLI) application using Go’s Cobra and Viper libraries. It has a root command with a persistent flag and two subcommands. Viper is used for managing the application’s configuration, including default values and reading from a configuration file. You can extend this example to build complex CLI applications with multiple commands, flags, and configuration options.
Subscribe to Faizan Bashir
Get the latest posts delivered right to your inbox