{{announcement.body}}
{{announcement.title}}

How to Create a CLI in Go in Minutes

DZone 's Guide to

How to Create a CLI in Go in Minutes

Get up and Go with this quick and effective tutorial.

· Web Dev Zone ·
Free Resource

Image title

Gopher

In our day-to-day work, we are used to using nifty tools in the command line. We are surrounded by CLI (Docker, Kubectl, Terraform, AWS, etc.). We will see in this tutorial, that in just a few minutes, it is possible to create a CLI with Go language and the Cobra library. Are you ready?


Why Go?

Gopher friend

Go, created in 2009, and used in production by thousands of companies around the world (including Uber, Lyft, Slack, Pinterest ... and of course Google), is becoming the preferred language of the Cloud. It is easy to install, provides libraries and tools, and is fast to compile and not very greedy in memory.

With its ecosystem riddled with tools and CLIs, it would be wrong not to put Go in our toolbox. If you have not started Go yet, you can start by doing the interactive "tour de go" tutorial: https://tour.golang.org.

As you will see in this article, writing a CLI with GO is a breeze!

You may also like: Golang Tutorial: Learn Golang by Examples.

Prerequisites:

Go!

The first step is, if you have not already done so, to install Go on your machine. For this, you can follow the installation procedure on the official website or go through GVM. GVM is a very practical version for Go, which allows you to update your version of Go by specifying which version you want.

Installation:

For bash:

bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)


For zsh:

zsh < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)


Usage:

$ gvm 

Usage: gvm [command]


Description:

  GVM is the Go Version Manager


Commands:

  version    - print the gvm version number

  get        - gets the latest code (for debugging)

  use        - select a go version to use (--default to set permanently)

  diff       - view changes to Go root

  help       - display this usage text

  implode    - completely remove gvm

  install    - install go versions

  uninstall  - uninstall go versions

  cross      - install go cross compilers

  linkthis   - link this directory into GOPATH

  list       - list installed go versions

  listall    - list available versions

  alias      - manage go version aliases

  pkgset     - manage go packages sets

  pkgenv     - edit the environment for a package set


The GVM command that will interest us especially is the command gvm install, it is used like this:

$ gvm install [version] [options]



Go installation:

$ gvm install go1.12.9 -B
$ gvm use go1.12.9 --default


In your .zshrc or .bashrc file, set your $GOROOT and $GOPATH environment variables. Here is an example :

[[ -s"$HOME/.gvm/scripts/gvm" ]] && source"$HOME/.gvm/scripts/gvm"

export GOPATH=$HOME/go

export GOBIN=$GOPATH/bin

export PATH=${PATH}:$GOBIN



That's it, Go is installed, its version manager also, it's time to get to the heart of the matter and create our first CLI.


Cobra


Cobra is both a library for creating powerful modern CLI applications and a program for generating applications and batch files.

Using Cobra is easy. First, use the go get command to download the latest version. This command will install the cobra generator executable with the library and its dependencies:

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



The cobra binary is now in the bin/ directory of your $GOPATH, which is itself in your PATH, so it can be used directly.

We will start by generating our first application with the command cobra init followed by the package and the name of your app. The command will generate the application with the correct file structure and imports.

$ cd $GOPATH/src 

$ cobra init github.com/scraly/hello-world

Using config file: /home/scraly/.cobra.yaml

Your Cobra application is ready at

/home/scraly/git/src/github.com/scraly/hello-world


Give it a try by going there and running `go run main.go`.

Add commands to it by running `cobra add [cmdname]`.


Your application is initialized, a main.go file and a cmd/ package has been created:


$ cd github.com/scraly/hello-world

$ tree
.
├── cmd
│   └── root.go
├── LICENSE
└── main.go

1 directory, 3 files


At the execution of our CLI we want to display:

* a short description
* a long description
* using our app


To do this, simply modify the cmd/root.go file:

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
   Use:   "hello-world",
   Short: "A brief description of your application",
   Long: `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.`,
   // Uncomment the following line if your bare application
   // has an action associated with it:
   // Run: func(cmd *cobra.Command, args []string) { },
}


Now, we want to add a start command in our small application. For that, we will use the add command of the cobra CLI:

$ cobra add start

Using config file: /home/scraly/.cobra.yaml

start created at /home/scraly/git/src/github.com/scraly/hello-world/cmd/start.go


/!\ Warning: Note that the command names must be in camelCase format.


Once you have executed these three commands, you get an application structure similar to this one:

$ tree
.
├── cmd
│   ├── root.go
│   └── start.go
├── LICENSE
└── main.go


At this point, you can run go run main.go to run your application:

$ go run main.go 

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.


Usage:

  hello-world [command]


Available Commands:

  help        Help about any command

  start       A brief description of your command


Flags:

      --config string   config file (default is $HOME/.hello-world.yaml)

  -h, --help            help for hello-world

  -t, --toggle          Help message for toggle


Use "hello-world [command] --help" for more information about a command.


Then, run main.go to run the start command:

$ go run main.go start

start called


If we had created another command, for example, cobra add config, we could also test the command by typing go run config.go.

We will now modify the cmd/start.go file, with our own code, so that our application displays the message we want for the start command:

var startCmd = &cobra.Command{

        Use:   "start",

        Short: "This command will show you a hello world message",

        Long: `Welcome in start command, this cmd will display to you a hello world message.`,

        Run: func(cmd *cobra.Command, args []string) {

                fmt.Println("Hello world, start have been called!")

        },

}


We can test the help of our start command right now:

$ go run main.go start -h

Welcome in start command, this cmd will display to you a hello world message.


Usage:

  hello-world start [flags]


Flags:

  -h, --help   help for start


Global Flags:

      --config string   config file (default is $HOME/.hello-world.yaml)


Then, run the start command to see the updated message:

$ go run main.go start

Hello world, start have been called!


We can also display the help message from our start command:

$ go run main.go start -h

Welcome in start command, this cmd will display to you a hello world message.


Usage:

  hello-world start [flags]


Flags:

  -h, --help   help for start


Global Flags:

      --config string   config file (default is $HOME/.hello-world.yaml)


Your application is ready, you just have to build/install it in your $GOPATH then use it:

$ go install

$ hello-world start
Hello world, start have been called!


Want to go further?


We will add a say command and a hello subcommand to make our little program say: "hello, world!"

Let's add our say command:

$ cobra add say
say created at /Users/uidn3817/go/src/github.com/scraly/hello-world/cmd/say.go


Let's edit this file to warn the user that the say command is not used alone. Just replace the Run method with this one:

    RunE: func(cmd *cobra.Command, args []string) error {

        return errors.New("Provide item to the say command")

    },


Next, we add hello sub command:

$ cobra add hello -p 'sayCmd'

hello created at /Users/uidn3817/go/src/github.com/scraly/hello-world/cmd/hello.go


Let's modify the hello.go file that has just been generated, so that the CLI can display "hello, world!"

    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("hello world !")
    },


Now, we need to install the app again in our machine:

$ go install


And we test again:

$ hello-world say

Error: Provide item to the say command

Usage:

  hello-world say [flags]

  hello-world say [command]


Available Commands:

  hello       A brief description of your command


Flags:

  -h, --help   help for say


Global Flags:

      --config string   config file (default is $HOME/.hello-world.yaml)


Use "hello-world say [command] --help" for more information about a command.


Provide item to the say command


And now we can just test again our app with the say command and hello sub command:

$ hello-world say hello

hello world !


And that's it, you coded your CLI in Go in a few minutes; it's a good start! :-)

If you liked this article, I'll write several articles to go further with your first CLI and your first application in Go!


Further Reading

Topics:
golang ,cli

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}