Skip to main content
  1. Blogs/

Simple CLI Colorizing in Go

·3 mins

Golang Gopher
Photo by Chinmay Bhattar on Unsplash

I have recently been spending some time learning Go and I wrote my first command-line interface (CLI) tool at work.

When I make CLI tools or scripts, I like trying to make the output as clear and easy as possible to understand quickly by highlighting important information for people using them. This is usually achieved through using color or different font choices (bold, italic, etc.). While I absolutely am not a Golang expert, I found what I think is a nice flexible way of colorizing CLI output for macOS/Linux terminals. This will also work for CLI applications run via the Windows Terminal, which implemented support for ANSI escape sequences in 2019.

I noticed that there are a number of libraries written by people on GitHub that offer “easy” ways to do what I’m doing here, but I would rather implement a simple function in my script that does this for me than need a whole new dependency added to all my scripts.

Color Function and Expected Variables #

var (
	// Colors and font options via ANSI escape codes
	Reset     = "\033[0m"
	Black     = "\033[30m"
	Red       = "\033[31m"
	Green     = "\033[32m"
	Yellow    = "\033[33m"
	Blue      = "\033[34m"
	Magenta   = "\033[35m"
	Cyan      = "\033[36m"
	Gray      = "\033[37m"
	White     = "\033[97m"
	Bold      = "\033[1m"
	Italic    = "\033[3m"
	Underline = "\033[4m"
	Invert    = "\033[7m"
)

func Color(input interface{}, color ...string) string {
	var s string
	c := ""
	for i := range color {
		c = c + color[i]
	}
	switch v := input.(type) {
	case int:
		s = c + strconv.Itoa(v) + Reset
	case bool:
		s = c + strconv.FormatBool(v) + Reset
	case []string:
		s = c + strings.Join(v, ", ") + Reset
	case string:
		s = c + v + Reset
	default:
		fmt.Printf("Unsupported type provided to Color func - %T\n", v)
	}
	return s
}

The example script below shows how the declared color variables can be implemented using a function that takes different input types (int, bool, string, and slice of strings) and outputs the required string with the ANSI escape sequences attached.

If a different type is required for printing out in color to the console, it can be added as a new switch case in the Color function and doing the necessary conversion to make the input type into a string. The way I have the function configured now, the default case will print out a message saying that the type provided to the Color function is not supported if one is provided that does not have a switch case.

Example Go Script #

The way the function works allows multiple font choices and color option to be applied to a single input.

For example, the line with fmt.Println(Color(fruits, **Blue, Bold, Underline, Italic, Invert**)) takes the fruits slice and applies a list of colorizing options against it. Only a single color can be applied using the function though, so if you want multiple colors on a single line, you’ll need to split it out like the following:

fmt.Printf(Color("My fruit list has %s %s\n", **Green**), Color(len(fruits), **Magenta, Bold**), Color("items.", **Green**))

Output of the example script in the Windows Terminal