Create a CLI in golang with Cobra
In this tutorial, we will create a color cli in golang using cobra library. CLI is a standard interface between a software and a user.
A command-line interface (CLI) processes commands to a computer program in the form of lines of text. – Wikipedia
Objective of the color cli
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/cobra
Project Setup
Create a colorcli
project using cobra cli.
cobra init colorcli --pkg-name colorcli
This will create a colorcli
scaffolding.
colorcli
|- cmd
|- root.go
|- main.go
The 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 colorcli
We’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\shubh\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. 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 colorcli
This will create a new file go.mod
.
Now, try again to build the binary.
go install colorcli
The binary is generated and saved in the $GOPATH/bin/
. Now, you can directly run the colorcli
command without setting the environment variable.
colorcli
Output
$ 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 required
Hexcode 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/color-name-list@5.7.0/dist/colornames.min.json
You 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 cobra.
cobra add name
This will create a new file name.go
in the cmd
folder.
Build the binary.
go install colorcli
Run the name
command.
colorcli name
Output
$ colorcli name
name called
Open 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. Read the full tutorial how to use json in golang.
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 colorcli
Run the cli.
colorcli name ffffff
colorcli name fffeee
Output
Name: White, Hex: ffffff
Color name not found
Add 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 addcolor
Open 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 colorcli
Add a new color. The first argument is hexcode and second is color name.
colorcli addcolor fffeee lightcream
Output
Hex to color added successfully!
Check the color.
colorcli name fffeee
Output
Name: lightcream, Hex: fffeee
In 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.