In this post, we’ll walk through creating a simple CLI application in Go. Our CLI will print a greeting such as “Hello, World” by default, but it also lets the user customize the greeting via a —greeting flag and the name via a —name flag. Additionally, we’ll add a version subcommand that prints the version of the CLI.
Why Build a CLI in Go?
Go is known for its simplicity and powerful standard library, which makes it a great choice for building command-line tools. In this tutorial, we’ll leverage Go’s built-in packages to parse flags and handle subcommands without relying on any external libraries.
In addition, we’ll use Cobra, a popular Go library for creating powerful CLI applications. Cobra provides a simple interface for defining commands, flags, and subcommands, making it easy to build robust CLI tools.
Setting Up Your Project
Start by creating a new directory for your project and initialize a new Go module:
mkdir simple-go-cli
cd simple-go-cli
go mod init github.com/your-username/simple-go-cli
Project Structure
We assume the following structure for our project:
simple-cli/
├── main.go
└── cmd
├── root.go
└── version.go
- main.go: The entry point that calls the Cobra command.
- cmd/root.go: Contains the root command, which processes the greeting flags.
- cmd/version.go: Defines the version subcommand.
Creating the Files
main.go
This file initializes the CLI by executing the root command.
// main.go
package main
import "github.com/your-username/simple-cli/cmd"
func main() {
cmd.Execute()
}
cmd/root.go
Set up the root command with persistent flags for greeting and name. When run without any subcommands, it prints the greeting message.
package cmd
import (
"fmt"
"os"
"github.com/your-username/simple-cli/cmd"
"github.com/spf13/cobra"
)
var (
greeting string
name string
)
var rootCmd = &cobra.Command{
Use: "simple-cli",
Short: "A simple CLI that greets you",
Long: "A simple CLI tool built with Cobra in Go that prints a greeting message. You can customize the greeting and name using flags.",
Run: func(cmd *cobra.Command, args []string) {
hello := fmt.Sprintf("%s, %s!", greeting, name)
fmt.Println(hello)
github.WriteOutput("greeting", hello)
},
}
func Execute() {
rootCmd.AddCommand(versionCmd)
rootCmd.PersistentFlags().StringVar(&name, "name", "World", "Your name")
rootCmd.PersistentFlags().StringVar(&greeting, "greeting", "Hello", "Greeting message")
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
cmd/version.go
The version subcommand prints the version of the CLI.
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
const version = "1.0.0"
// versionCmd represents the version subcommand.
var versionCmd = &cobra.Command{
Use: "version",
Short: "Print the version of the CLI",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Version:", version)
},
}
Building and Running the CLI
To build and run the CLI, use the following commands:
go mod tidy
go build -o simple-cli
./simple-cli --greeting "Hi" --name "Alice"
# Hi, Alice!
./simple-cli version
# Version: 1.0.0
Conclusion
In this post, we built a simple CLI tool using Cobra in Go. We learned how to:
- Initialize the project with a proper module path using go mod init github.com/your-username/simple-cli.
- Structure a project with separate files for the main function and commands.
- Use persistent flags for customization.
- Add a subcommand to display the CLI version.
Cobra makes it easy to build robust CLI applications with minimal setup. Once you’re comfortable with this foundation, consider expanding your tool with additional subcommands and more advanced flag parsing. Happy coding!