Skip to main content
Home
Gerald Villorente

Main navigation

  • Home
  • Blog

Breadcrumb

  1. Home

Building Command-Line Applications in Golang with Cobra and Viper

By gerald, 2 April, 2023
cli

Photo by Sora Shimazaki: https://bit.ly/3U0FX5j

If you're building command-line applications in Golang, you'll probably want to use a library to handle the command-line interface (CLI) and configuration options. Two popular libraries for this are Cobra and Viper.

Cobra is a CLI library that makes it easy to create powerful and complex command-line applications. It provides a simple interface for adding commands, flags, and arguments, and supports subcommands and nested commands. Cobra also generates help and usage information for your application automatically.

Viper, on the other hand, is a configuration library that provides a simple interface for working with configuration files, command-line arguments, and environment variables. It supports a variety of configuration file formats, including JSON, YAML, TOML, and INI, and allows you to easily read and write configuration options in your code.

In this blog post, we'll explore how to use Cobra and Viper together to create a powerful command-line application with flexible configuration options.

Installing Cobra and Viper

Before we get started, we need to install Cobra and Viper. You can do this using the go get command:

go get -u github.com/spf13/cobra
go get -u github.com/spf13/viper

Creating a Command-Line Application with Cobra

Let's start by creating a simple command-line application using Cobra. We'll create a hello command that prints a greeting to the user. First, create a new directory for your application:

mkdir hello cd hello

Next, create a new Go module:

go mod init github.com/yourusername/hello

Now, create a new file called main.go with the following contents:

package main

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

func main() {
    var rootCmd = &cobra.Command{
        Use: "hello",
        Short: "Prints a greeting",
        Long: `Prints a greeting to the user.`,
        Run: func(cmd *cobra.Command, args []string) {
            fmt.Println("Hello, world!")
        },
    }

    rootCmd.Execute()
}

This creates a new Cobra command called hello with a short description and a long description. When the command is run, it simply prints Hello, world! to the console.

To test your application, run the following command:

go run main.go hello

This should output Hello, world! to the console.

Adding Command-Line Flags with Cobra

Next, let's add a command-line flag to our hello command that allows the user to specify their name. We'll use the cobra package to define the flag and the viper package to read the flag's value.

Update the main.go file as follows:

package main

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

func main() {
    var name string
    var rootCmd = &cobra.Command{
        Use: "hello",
        Short: "Prints a greeting",
        Long: `Prints a greeting to the user.`,
        Run: func(cmd *cobra.Command, args []string) {
            fmt.Printf("Hello, %s!\n", name)
        },
    }

    rootCmd.PersistentFlags().StringVarP(&name, "name", "n", "", "Your name")
    viper.BindPFlag("name", rootCmd.PersistentFlags().Lookup("name"))
    rootCmd.Execute()
}

In this updated version of main.go, we've added a name variable that will hold the value of the --name command-line flag.

We've also added a PersistentFlags() method to the rootCmd variable, which allows us to add a flag to the command. In this case, we're using the StringVarP() method to add a flag called name with a short name of n.

Finally, we're using the BindPFlag() method from Viper to bind the name variable to the --name flag. This allows us to access the value of the flag using viper.GetString("name").

To test the updated application, run the following command:

go run main.go hello --name Alice

This should output Hello, Alice! to the console.

Using Configuration Files with Viper

Now that we've added a command-line flag to our application, let's add support for configuration files using Viper. This will allow users to specify their name in a configuration file rather than on the command line.

Create a new file called config.yaml in the same directory as main.go with the following contents:

name: Bob

Now, update the main.go file as follows:

package main

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

func main() {
    var rootCmd = &cobra.Command{
        Use: "hello",
        Short: "Prints a greeting",
        Long: `Prints a greeting to the user.`,
        Run: func(cmd *cobra.Command, args []string) {
            fmt.Printf("Hello, %s!\n", viper.GetString("name"))
        },
    }

    rootCmd.PersistentFlags().String("config", "", "config file")
    viper.BindPFlag("config", rootCmd.PersistentFlags().Lookup("config"))
    viper.SetConfigName("config")
    viper.AddConfigPath(".")
    viper.SetConfigType("yaml")

    err := viper.ReadInConfig()
    if err != nil {
        fmt.Printf("Error reading config file: %s\n", err)
    }

    rootCmd.Execute()
}

In this updated version of main.go, we've added a config flag that allows the user to specify a configuration file. We've also added code to read the configuration file using Viper.

The viper.SetConfigName() method sets the name of the configuration file (in this case, config). The viper.AddConfigPath() method adds the current directory as a search path for the configuration file. Finally, the viper.SetConfigType() method sets the configuration file type to YAML.

We've also added an error check to viper.ReadInConfig() to handle cases where the configuration file cannot be read.

To test the updated application, run the following command:

go run main.go hello --config=config.yaml

This should output Hello, Bob! to the console.

Conclusion

In this blog post, we've explored how to use Cobra and Viper together to create a powerful command-line application with flexible configuration options. We've seen how to use Cobra to create commands and command-line flags, and how to use Viper to read configuration files and command-line flags.

Cobra and Viper are powerful tools that can simplify the development of command-line applications in Golang. With these tools, you can quickly create complex applications with flexible configuration options.

Tags

  • golang
  • programming
  • cobra-cli
  • viper
  • command-line
  • Log in or register to post comments

Comments

Recent content

  • Fixing the "Malware Detected" Error in Docker for macOS
  • How to Manage Large Log Files in Go: Truncate a Log File to a Specific Size
  • Taming the Slowpokes: A Guide to Conquering Sluggish MySQL Queries
  • Taming the Slow Beast: Using Percona pt-query-digest to Diagnose MySQL Bottlenecks
  • Speed Up Your Web App: The Ins and Outs of Redis
  • Cherishing the Present: A Timeless Gift for Your Loved Ones
  • Diving Deep: Redis Slowlog vs. Redis MONITOR
  • MSET vs. HSET: Storing Data Efficiently in Redis
  • Installing TP-Link AC600 Wireless Adapter on Manjaro with Realtek RTL8811AU
  • Understanding Variadic Parameters in Go (Golang)
RSS feed

This website is powered by Drupal and Pantheon WebOps Platform.

pantheon