DEV Community

Cover image for Getting started with CLI's using Golang.
Siddhesh Khandagale
Siddhesh Khandagale

Posted on

Getting started with CLI's using Golang.

Introduction :

In this blog we are going to get started with CLI using Golang and Cobra CLI. We are just going to make a simple Quiz game CLI and get friendly with the Cobra-CLI library.

Why Cobra-CLI?

Cobra is both a library for creating powerful modern CLI applications and a program to generate applications and CLI applications in Go. Cobra powers most of the popular Go applications including CoreOS, Delve, Docker, Dropbox, Git Lfs, Hugo, Kubernetes, and many more. With integrated command help, autocomplete and documentation.

Prerequisites :

To continue with tutorial, firstly you need to have Golang and Cobra-CLI installed.

Installation :

  • Golang
  • For installing Cobra-CLI you can go to Cobra or run go install github.com/spf13/cobra-cli@latest in the terminal.

Initializing the Project

After completing the Installation part to get started make a folder for eg. go_quiz , run the given command

go mod init github.com/Siddheshk02/go_quiz
Enter fullscreen mode Exit fullscreen mode

In place of Siddheshk02 use the name in which your project directories are. Now the structure will look like this

Image description

Cobra-cli init
Enter fullscreen mode Exit fullscreen mode

This command initializes the CLI and make a main.go file along with cmd folder containing root.go

Image description

The main.go file will have the following code,

package main

import "github.com/Siddheshk02/go_quiz/cmd"

func main() {
    cmd.Execute()
}
Enter fullscreen mode Exit fullscreen mode

This means the main cli commands implementation will be in cmd which is called through main.go.

Make the following changes in the root.go file.

package cmd

import (
    "os"

    "github.com/spf13/cobra"
)
var rootCmd = &cobra.Command{
    Use:   "go_quiz",
    Short: "A Simple Quiz game CLI",
    Long: `A Simple Quiz game CLI using Golang.`,

}

func Execute() {
    err := rootCmd.Execute()
    if err != nil {
        os.Exit(1)
    }
}

func init() {
    rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
Enter fullscreen mode Exit fullscreen mode

In root.go, function Execute gets called from main.go and it executes the rootCmd. Use is used to define the command to be used and Short and Long contains the information or description for the Command in short and long format respectively.

Now run go run main.go or go build . and .\go_quiz or go_quiz.

C:\Users\Admin\Go\src\github.com\Siddheshk02\go_quiz> go run main.go
A Simple Quiz game CLI using Golang.
Enter fullscreen mode Exit fullscreen mode
C:\Users\Admin\Go\src\github.com\Siddheshk02\go_quiz> go build .
C:\Users\Admin\Go\src\github.com\Siddheshk02\go_quiz> .\go_quiz
A Simple Quiz game CLI using Golang.
Enter fullscreen mode Exit fullscreen mode
C:\Users\Admin\Go\src\github.com\Siddheshk02\go_quiz>go_quiz -h       
A Simple Quiz game CLI using Golang.

Usage:
  go_quiz [flags]
  go_quiz [command]

Available Commands:
  completion  Generate the autocompletion script for the specified shell
  help        Help about any command
  start       Starting a new Quiz

Flags:
  -h, --help     help for go_quiz
  -t, --toggle   Help message for toggle

Use "go_quiz [command] --help" for more information about a command.
Enter fullscreen mode Exit fullscreen mode

Now let's make a csv file data.csv in the go_quiz directory, to store the questions and answers for the quiz.

Store the following values in the file.

5+5,10
7+3,10
1-1,0
8+3,11
1+2,3
8-6,2
3-1,2
1+4,5
5-1,4
2+3,5
3+3,6
7-4,3
5+2,7
9-2,7
4+8,12
1+8,9
Enter fullscreen mode Exit fullscreen mode

Lets make a new command which will be used to start a Quiz.

for adding a new command run this code Cobra-cli add start, here start is the new command made.

This will create a new file start.go in the cmd folder.

Image description

Make the following changes in the start.go file

package cmd

import (
    "fmt"

    "github.com/spf13/cobra"
)

var startCmd = &cobra.Command{
    Use:   "start",
    Short: "Starting a new Quiz",
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("start called")
    },
}

func init() {
    rootCmd.AddCommand(startCmd)
}
Enter fullscreen mode Exit fullscreen mode

let's try running our new command. Run go build . in the terminal and then run go_quiz start

C:\Users\Admin\Go\src\github.com\Siddheshk02\go_quiz>go_quiz start    
start called
Enter fullscreen mode Exit fullscreen mode

you can also try running go_quiz start -h.

Now, for the main implementation of the Quiz game, we will make a folder pkg in the project directory i.e. go_quiz and a file quiz.go in the pkg folder.

Image description
In the quiz.go make a function Quiz that returns a string res

func Quiz() (res string) {

    return res
}
Enter fullscreen mode Exit fullscreen mode

This function will be called in the start.go as :

Run: func(cmd *cobra.Command, args []string) {
        res := pkg.Quiz
},
Enter fullscreen mode Exit fullscreen mode

Now, let's code in the Quiz function in quiz.go

Firstly, we need to open and read the data.csv file to get the questions and there answers.

package pkg

import (
    "encoding/csv"
    "errors"
    "fmt"
    "io"
    "log"
    "os"
    "strconv"
)

func Quiz() (res int, err error) {
    res = 0

    f, err := os.Open("C:/Users/Admin/Go/src/github.com/Siddheshk02/go_quiz/data.csv")
    if err != nil {
        log.Fatal(err)
    }

    defer f.Close()

    csvReader := csv.NewReader(f)
    var ans int
    for {
        rec, err := csvReader.Read()
        if err == io.EOF {
            break
        }
        if err != nil {
            log.Fatal(err)
        }

        fmt.Print(rec[0] + " : ")

        c, _ := strconv.Atoi(rec[1])

        fmt.Scanf("%d\n", &ans)

        if ans == c {
            res = res + 1
            fmt.Println("correct")
            continue

        } else {
            err = errors.New("Incorrect Response!!")

            break
        }

    }
    return res, err
}
Enter fullscreen mode Exit fullscreen mode

Here, we are taking the questions and answers in rec which is a string array, so for each iteration in the loop the rec array takes question in rec[0] and answer in rec[1].

Then for comparing the user input ans with the original answer i.e. rec[1], we first convert rec[1] into integer type as ans is in integer whereas rec is string.

A res variable is created to store the result count, which is returned along with err error after completing the quiz or after giving an Incorrect response.

So, the start.go will look like the following code after all changes :

Run: func(cmd *cobra.Command, args []string) {
        res, err := pkg.Quiz()
        if err != nil {
            fmt.Println(err)
            fmt.Printf("Your Score is %d", res)
        } else {
            if res == 16 {
                fmt.Println("Congrats!, you got all questions Correct")
            }
            fmt.Printf("Your Score is %d", res)
        }
    },
Enter fullscreen mode Exit fullscreen mode

Now, run go build . and then go_quiz start to test the CLI.

C:\Users\Admin\Go\src\github.com\Siddheshk02\go_quiz>go_quiz start 
5+5 :
Enter fullscreen mode Exit fullscreen mode

Enter the answers after getting the question :)

If all the given responses are correct

.
.
.
1+8 : 9
correct
Congrats!, you got all questions Correct
Your Score is 16
Enter fullscreen mode Exit fullscreen mode

And if any of the response is Incorrect :(

.
.
7+3 : 10
correct
1-1 : 0
correct
8+3 : 1 
Your Score is 3
Enter fullscreen mode Exit fullscreen mode

The complete code is saved on GitHub

Conclusion :

In this tutorial we learnt how to create a command-line application with Go and Cobra. In the next upcoming tutorial , we will learn how to add flags, commands, etc. and build more such amazing stuff.

If you enjoyed this article and you'd like more, consider following Siddhesh on Twitter to get the latest updates.

Congratulations🎉, you did great. Keep learning and keep coding :)

Top comments (0)