Build a CLI in Golang with the Cobra library

In this tutorial, we will create color CLI in Golang using the Cobra library.
CLI is a standard interface between software and a user.
The objective of CLI in Golang
The objective of the colorcli is to return the name of the hexcode of the color.
If the hexcode doesn’t exist then colorcli can add the color.
Pre-requisites
- Golang
- Cobra library
go get -u github.com/spf13/cobra/cobra
Cobra
Cobra is a library providing a simple interface and application scaffolding to create a CLI interface.
Cobra is built on a structure of commands, arguments & flags. Learn more.
- Commands are Verb
- Arguments are Noun
- Flags are Adjective
Example:
App Command -Flag Argument
go get -u github.com/spf13/cobra/cobraProject Setup
Create a colorcli project using Cobra cli.
cobra init colorcli --pkg-name colorcliThis will create a colorcli scaffolding.
colorcli
|- cmd
|- root.go
|- main.goThe main.go will execute the root command from the cmd/root.go.
package main
import "colorcli/cmd"
func main() {
cmd.Execute()
}The root command is the cli name or app name. In this case, it is colorcli.
Let’s build the cli and run the colorcli.
go install colorcliWe’ll get an error.
can't load package: package colorcli: cannot find package "colorcli" in any of:
C:\Go\src\colorcli (from $GOROOT)
C:\Users\user\go\src\colorcli (from $GOPATH)You’ll not encounter this error if the project is inside the GOPATH.
By default go find the packages inside the GOROOT and GOPATH.
We have to initiate the Go modules inside the project to tell go to find the package in the project.
Go Modules is a package manager in the Golang. The go module tracks all the packages and their version used in the project.
You can consider it similar to node modules in the nodejs. Learn more.
Initiate the go modules
go mod init colorcliThis will create a new file go.mod.
Now, try again to build the binary.
go install colorcliThe binary is generated and saved in the $GOPATH/bin/. Now, you can directly run the colorcli command without setting the environment variable.
colorcliOutput
$ colorcli
A longer description that spans multiple lines and likely contains
examples and usage of using your application. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.
subcommand is requiredHexcode Color names
We are going to use the meodai/color-names git repo. This repo has a handpicked list of 18376 unique color names from various sources and thousands of curated user submissions.
Download the hexcode to color name Json file
Open the terminal in the project directory.
curl -O https://unpkg.com/[email protected]/dist/colornames.min.jsonYou can download it in other formats. Link
Create a name command in the colorcli
To add a command, we are going to use add command of the cobra.
cobra add nameThis will create a new file name.go in the cmd folder.
Build the binary.
go install colorcliRun the name command.
colorcli nameOutput
$ colorcli name
name calledOpen the name.go and check the init function.
rootCmd.AddCommand(nameCmd)The AddCommand is adding the nameCmd to the rootCmd. In this case it is colorcli.
Add a new function hexToName.
import (
"encoding/json"
"fmt"
"io/ioutil"
"github.com/spf13/cobra"
)
...
func hexToName(args []string) {
var hexMap map[string]string
// read the color.min.json
content, err := ioutil.ReadFile("colornames.min.json")
if err != nil {
fmt.Printf("Error while reading the file %v", err)
}
_ = json.Unmarshal(content, &hexMap)
name, ok := hexMap[args[0]]
if ok {
fmt.Printf("Name: %s, Hex: %s\n", name, args[0])
} else {
fmt.Println("Color name not found")
}
}We are using ioutil package to read the file. The file is in json format. We are using encoding/json package to convert the json into struct to read it.
Update the nameCmd.
var nameCmd = &cobra.Command{
Use: "name",
Short: "A brief description of your command",
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
Run: func(cmd *cobra.Command, args []string) {
// call hexToName function
hexToName(args)
},
}Build the binary to reflect the changes.
go install colorcliRun the cli.
colorcli name ffffff
colorcli name fffeeeOutput
Name: White, Hex: ffffff
Color name not foundAdd a color name to the colornames.min.json
Add an addcolor command, to add custom or extra color to the colornames.min.json file.
cobra add addcolorOpen the addcolor.go and add the addColor function.
import (
"encoding/json"
"fmt"
"io/ioutil"
"github.com/spf13/cobra"
)
...
func addColor(args []string) {
hex := args[0]
colorName := args[1]
// Read the file
content, err := ioutil.ReadFile("colornames.min.json")
if err != nil {
fmt.Printf("Error while reading a file %v", err)
}
// map hex value to color name
var hexMap map[string]string
// unmarshal to hexMap
_ = json.Unmarshal(content, &hexMap)
// check if hex exist
name, ok := hexMap[hex]
if ok {
fmt.Printf("Hex already exist. Color Name is :%s\n", name)
} else {
hexMap[hex] = colorName
// marshal to json or convert to json
hexJSON, _ := json.Marshal(hexMap)
// write to colornames.min.json
err = ioutil.WriteFile("colornames.min.json", hexJSON, 0777)
if err != nil {
fmt.Printf("Error while writing a file %v", err)
}
fmt.Println("Hex to color added successfully!")
}
}We are using ioutil package for updating the file. It is creating a new file instead of just updating the existing one. Learn more.
Update the addcolorCmd.
// addcolorCmd represents the addcolor command
var addcolorCmd = &cobra.Command{
Use: "addcolor",
Short: "A brief description of your command",
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
Run: func(cmd *cobra.Command, args []string) {
addColor(args)
},
}Build the binary.
go install colorcliAdd a new color. The first argument is hexcode and second is color name.
colorcli addcolor fffeee lightcreamOutput
Hex to color added successfully!Check the color.
colorcli name fffeeeOutput
Name: lightcream, Hex: fffeeeIn cobra library, all the arguments are in string format. You have to explicitly convert the string into the respective type.
Conclusion
Congratulations. We just created a colorcli in Golang using the Cobra library. There are many features you can add in it, like creating a flag to return the color in RGB format. The colorcli has a dependency on the colornames.min.json file. There are many free apis you can utilize to remove the dependencies.
Any suggestion is most welcome. Keep coding.
The complete code is saved in GitHub.