Cobra is a popular Go (Golang) library used for building powerful command-line applications. It provides a simple and elegant framework to create and manage command-line interfaces (CLIs) with ease. Cobra helps developers structure their CLI programs by organizing commands, arguments, and flags in a hierarchical and user-friendly manner.
Key features of the Cobra library include:
- Command Hierarchy: Cobra allows you to define a hierarchy of commands, each with its own set of arguments and flags. This makes it suitable for both simple and complex CLIs.
- Subcommands: With Cobra, you can create subcommands that perform specific actions within your CLI, allowing users to navigate through different functionalities effortlessly.
- Flags and Arguments: Cobra provides a straightforward way to define flags (options) and arguments for each command. Flags can be persistent across subcommands, and Cobra supports various flag types.
- Help Generation: Cobra automatically generates helpful help texts and usage instructions for each command, making it easier for users to understand how to interact with your CLI.
- Customization: The library is highly customizable, allowing you to define custom help messages, change default behaviors, and customize the formatting of the output.
- Automatic Bash/Zsh Autocompletion: Cobra can generate autocompletion scripts for popular shells like Bash and Zsh, enhancing the user experience.
- Plugin Support: Cobra supports plugins, enabling you to extend your CLI’s capabilities easily.
In this project, we’ll use Go and the Cobra library to build a practical command-line app. Our initial focus will be on fetching AWS EC2 instance information. As we progress, we’ll introduce subcommands to expand the app’s capabilities. We will create a command line utility like this.
$ go run main.go aws fetch --region=ap-south-1 --aws-profile default --instance-id i-01f4af939a8d24434 - instance_id: i-01f4af939a8d24434, instance_name: prod-instance01.test, instance_type: t4g.small, instance_state: running
Let’s start by installing the Cobra CLI. Once that’s done, we’ll get things rolling by initializing the project. Using the Cobra CLI, we’ll build the project structure, specifying details like the author and license. With the help of Viper, we’ll seamlessly integrate environment variables and config files into our app’s flags. Moving on, we’ll introduce our first command ‘aws’ followed by a practical subcommand ‘fetch’ nested under ‘aws.’
$ go install github.com/spf13/cobra-cli@latest $ go mod init github.com/9999dude/cloud-ops $ cobra-cli init --author "9999dude" --license apache --viper $ cobra-cli add aws $ cobra-cli add fetch -p 'awsCmd'
Our code structure looks like this,
$ tree . ├── CHANGELOG.md ├── LICENSE ├── README.md ├── cmd │ ├── aws.go │ ├── fetch.go │ ├── root.go │ └── utils.go ├── go.mod ├── go.sum └── main.go
The heart of your Cobra-powered command-line application resides in main.go. This file serves as the starting point for executing your commands and subcommands, seamlessly orchestrating the functionality of your application.
func main() { cmd.Execute() }
All commands and subcommands are neatly organized within the cmd/ directory, each residing in its dedicated file. Within these files, you’ll find the init function, responsible for defining flags and configurations specific to each command or subcommand. These files also host a cobra.Command instance, which holds essential information like short and long command descriptions. In addition, you’ll uncover an anonymous function where the command’s logic is elegantly encapsulated.
utils.go hosts some of the functions used by the app to fetch the AWS EC2 instance details.
Flags can be of two types:
- local: Alternatively, a flag can be assigned with local scope, confining its impact solely to the command where it’s employed. This means that the flag’s influence remains localized, exerting its effects exclusively within that particular command.
- persistent: A flag can be designated as ‘persistent,’ which means that the flag remains accessible not only within the specific command it’s assigned to but also extends its availability to all commands nested underneath. This convenient feature ensures consistent usage of the flag across various levels of your command-line application.
Final usage of the command looks like
$ go run main.go -h cloud-ops is a CLI library used to perform tasks in different cloud. For example: Try help for more information. Usage: cloud-ops [flags] cloud-ops [command] Available Commands: aws The command has subcommands to do operations on aws resources. completion Generate the autocompletion script for the specified shell help Help about any command Flags: -h, --help help for cloud-ops -t, --toggle Help message for toggle Use "cloud-ops [command] --help" for more information about a command. $ go run main.go aws fetch --region=ap-south-1 --aws-profile default --instance-id i-01f4af939a8d24434 - instance_id: i-01f4af939a8d24434, instance_name: prod-instance01.test, instance_type: t4g.small, instance_state: running
Final code is available in the Github repo https://github.com/9999dude/cloud-ops/blob/0.1.1/main.go.