DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

How to Create a CLI in Go in Minutes

Get up and Go with this quick and effective tutorial.

Aurelie Vache user avatar by
Aurelie Vache
·
Oct. 18, 19 · Tutorial
Like (7)
Save
Tweet
Share
32.56K Views

Join the DZone community and get the full member experience.

Join For Free

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

  • Migrating From Commons CLI to Picocli.
  • Java Command-Line Interfaces (Part 1): Apache Commons CLI.
  • Command Line Magic With Aiven CLI.
Command-line interface Command (computing) application

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • How To Get Page Source in Selenium Using Python
  • Top 12 Technical Skills Every Software Tester Must Have
  • How and Why You Should Start Automating DevOps
  • Java Development Trends 2023

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: