Interactive command line sessions library

Build Status Go Report Card codecov

I usually have some trouble when it comes to creating a cli for an application. That, of course, led me to create my own library.

ICLS

ICLS stands for Interactive Command Line Session. That means that when the program is executed, it creates its own prompt for entering commands.

For more information of the different types of cli’s see wiki.

go-icls

The library I can provide both an ICLS and a usual cli. The difference is that the cli takes a command, executes, and exits, while the ICLS return to a prompt instead of exiting.

Run vs Execute

Run() and Execute(cmd string) are the definitions of two seperate methods. Run() has an infinate loop, waiting for user input, that gets passed to the Execute(cmd string) method. The Execute(cmd string) method takes as input a line, usually from os.Args.

Parser

In the core of Execute(cmd string) method, lies the parser. It takes the line and returns the command name and a map[string]string for the flags.

Command definition

Commands are defined beforehand. Every command is part of the CLI struct, and has a name, a short description, a long description, and a handler.

The handler is a func that takes a map[string]string, which is the flags that user passed along the command and returns an error:

func(flags map[string]string) error

This is an example of a command definition:

c := cli.New() // return a CLI struct without any commands
g := c.New("cmdName", "short description", "long description", func(flags map[string]string) {
	// do something
})

Flag definition

With commands come flags that change the behavior of the command in very specific ways.

A flag has a name, an alias, a data type, a default value, a description, and a required flag. The generic method to add flags to a command is the following:

func (c *command) Flag(name, alias, dataType string, defaultValue interface{}, description string, isRequired bool) error

The default value must be of type defined as the dataType of flag.

However, the data type can be ommited when using the specific type methods to define a flag:

g.IntFlag("i", "intFlag", 0, "this is an int flag", false)
g.StringFlag("s", "stringFlag", "0", "this is a string flag", false)
g.BoolFlag("s", "stringFlag", "this is a string flag", false)

In bool flag definition, the default value is ommited entirally, because it is expected to be always false, since the existance of the flag in user input implies a true value.

Example usage

Following is an example program that defines two commands and some flags for each command.

package main

import (
	"fmt"

	"github.com/RomanosTrechlis/go-icls/cli"
)

func main() {
	// create a new cli
	c := cli.New()
	// add 'get' command to cli
	get := c.New("get", "get gets", "get gets", func(flags map[string]string) error {
		fmt.Println("This is the get command")
		return nil
	})
	// add 'get' command flags
	get.StringFlag("d", "", "", "directory name", false)
	get.StringFlag("t", "tetetetetetetet", "", "directory name", true)

	// add 'put' command to cli
	put := c.New("puttertesttest", "putter puts", "putter puts", func(flags map[string]string) error {
		i, err := c.IntValue("g", "puttertesttest", flags)
		if err != nil {
			return err
		}
		fmt.Printf("This is the putter command: %d\n", i)
		return nil
	})
	// add 'put' command flags
	put.StringFlag("f", "file", "", "filename to put", true)
	put.IntFlag("g", "int", 1, "int to put", false)

	c.Run()
}

And this is the output:

$ go-icls
> -h
Usage:

        go-icls.exe <command> [options]

Commands:
        get                   get gets
        puttertesttest        putter puts

Use "go-icls.exe <command> -h" for more information about a command.
> get -h
usage: get [get flags]

get gets

Flags:

        -d
                                directory name
        -h    --help
                                prints out information about the command
        -t    --tetetetetetetet
                                directory name (required: true)
> get -d test
This is the get command
> quit

$

In order to include go-icls functionality into an application, import:

import "github.com/RomanosTrechlis/go-icls/cli"

Use the quit command to exit the interactive interface.

TODO

Get the full code here