gomcli

package module
v0.0.0-...-28a4717 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 17, 2020 License: MIT Imports: 10 Imported by: 0

README

gomcli

GoDoc Go Report Card

gomcli is a simple Go library to help developers build interactive command-line interfaces in the style of Metasploit Framework's msfconsole.

It is heavily inspired by riposte, a similar library for Python (in fact, some chunks of the code are a direct conversion to Go). However, the scope is a bit narrower, since things like output formatting are intentionally left out of the library's functionality.

render1589707015032

It uses the Liner package under the hood. Therefore, many features already come for free, such as tab autocompletion, reverse search history, clear screen...

Usage and example

Instantiate a GomCLI, set a custom prompt and you are good to go.

import "github.com/jmreyes/gomcli"

func main() {
	cli := gomcli.New()
	cli.SetPrompt("myprompt$ ")
}

Add Commands to this instance to inform the CLI of the available options for autocompletion and execution. A Command is defined as follows:

type Command struct {
	Name       string
	Function   interface{}
	ErrHandler ErrHandler
	Completer  Completer
}
  • Name: The input that will trigger the execution of the Function.
  • Function: The function that will be called.
  • ErrHandler: Function to allow you to decide what happens when there are arguments missing, or invalid arguments are provided (e.g. provided string cannot be converted to the int argument the Function is expecting).
  • Completer: Function that returns the completions for this Command, to allow for subcommands. The subcommands will be additional Commands, with apropriate Name.

Check out the godoc for advanced configuration.

The following example tries to illustrate the basics, providing the functionality shown in the gif above.

package main

import (
	"math"
	"strings"

	"github.com/jmreyes/gomcli"
)

var cli *gomcli.GomCLI

var currentMode = "basic"

func sum(x int, y int) {
	gomcli.Printf("[+] Sum is %v\n\n", x+y)
}

func mode() {
	gomcli.Printf("[i] Current mode is %v\n\n", currentMode)
}

func modeCompleter(text string) (res []string) {
	for _, subcommand := range []string{"basic", "advanced"} {
		if strings.HasPrefix(subcommand, text) {
			res = append(res, subcommand)
		}
	}
	return
}

func modeAdvanced() {
	currentMode = "advanced"
	cli.SetPrompt("gomcli [advanced] > ")

	gomcli.Printf("[+] Advanced mode set!\n\n")

	cli.AddCommand(gomcli.Command{
		Name: "power",
		Function: func(x float64, y float64) {
			gomcli.Printf("[+] Power is %v\n\n", math.Pow(x, y))
		},
		ErrHandler: errorHandler,
	})
}

func errorHandler(c *gomcli.Command, s []string, err error) error {
    // Check out the godoc for a full list of errors!
    if err == gomcli.ErrCmdMissingArgs {
		gomcli.Printf("[-] Arguments missing!\n\n")
	} else {
		gomcli.Printf("[-] Error! Did you really use valid input?\n\n")
	}
	return nil
}

func main() {
	cli = gomcli.New()

	cli.SetPrompt("gomcli > ")
	cli.SetNotFoundHandler(func(cmd string) error {
		gomcli.Printf("[-] Command %v not found!\n\n", cmd)
		return nil
	})

	cli.SetCommands([]gomcli.Command{
		{
			Name:       "sum",
			Function:   sum,
			ErrHandler: errorHandler,
		},
		{
			Name:      "mode",
			Function:  mode,
			Completer: modeCompleter,
		},
		{
			Name:     "mode advanced",
			Function: modeAdvanced,
		},
	})

	cli.Start()
}

Dependencies

Documentation

Overview

Package gomcli provides a library to build interactive CLI interfaces in the style of msfconsole and riposte.

Index

Constants

This section is empty.

Variables

View Source
var ErrCliCannotParseLine = errors.New("Cannot parse line")

ErrCliCannotParseLine is returned from Start or StartWithInput if the input provided could not be be parsed to form command and arguments.

View Source
var ErrCliCommandNotFound = errors.New("Command not found")

ErrCliCommandNotFound is passed to the notFoundHandler function if the input provided does not match any known command.

View Source
var ErrCliPromptAborted = errors.New("Prompt aborted")

ErrCliPromptAborted is returned from Start or StartWithInput when the user presses Ctrl-C, if CtrlCAborts was set to true in the Conf struct.

View Source
var ErrCmdArgOverflow = errors.New("Value too big")

ErrCmdArgOverflow is passed to ErrHandler when the value provided via CLI overflows the type of the corresponding argument for its defined Function.

View Source
var ErrCmdArgUnsupportedKind = errors.New("Unsupported Kind")

ErrCmdArgUnsupportedKind is passed to ErrHandler when the Kind of a Function's argument is not supported.

View Source
var ErrCmdInvalidArgs = errors.New("Invalid arguments")

ErrCmdInvalidArgs is passed to ErrHandler when the arguments provided via CLI for a Command cannot be converted to the argument types for its defined Function.

View Source
var ErrCmdMissingArgs = errors.New("Missing arguments")

ErrCmdMissingArgs is passed to ErrHandler when the number of arguments provided via CLI for a Command is less than the number of arguments for its defined Function.

Functions

func Print

func Print(a ...interface{}) (n int, err error)

Print is a wrapper over fmt.Print for thread-safe usage from gomcli.

func Printf

func Printf(format string, a ...interface{}) (n int, err error)

Printf is a wrapper over fmt.Printf for thread-safe usage from gomcli

func Println

func Println(a ...interface{}) (n int, err error)

Println is a wrapper over fmt.Println for thread-safe usage from gomcli

Types

type Command

type Command struct {
	Name       string
	Function   interface{}
	ErrHandler ErrHandler
	Completer  Completer
}

Command represents a function that can be executed via the CLI. Name defines the string that needs to be provided via the CLI to execute the Function. ErrHandler allows to handle errors when converting the input to arguments for the Function. Completer allows to provide completions for subcommands.

type Completer

type Completer func(string) []string

Completer takes a string and returns a list of completion candidates. It can be set for a given Command to indicate gomcli how to complete subcommands.

type ErrHandler

type ErrHandler func(*Command, []string, error) error

ErrHandler takes a Command, an input string and a given error when parsing said Command, and returns an error to be propagated to GomCLI.Start, if needed. Otherwise, this is the point where the errors from CLI input for a Command are to be gracefully handled.

type GomCLI

type GomCLI struct {
	// contains filtered or unexported fields
}

GomCLI represents the state of the command-line interface, and is the main object to interact with within your program.

func New

func New() *GomCLI

New initializes a new *GomCLI with sane defaults. Further configuration is to be performed via the setters. The terminal is set to raw mode by Liner's action, therefore to restore the terminal to its previous state, GomCLI.Close() needs to be called.

func (*GomCLI) AddCommand

func (c *GomCLI) AddCommand(cmd Command)

AddCommand adds a single Command to the CLI.

func (*GomCLI) Close

func (c *GomCLI) Close()

Close stops the CLI processing, updating the history file if applicable and resetting the terminal into its previous mode.

func (*GomCLI) Commands

func (c *GomCLI) Commands() map[string]Command

Commands retrieves the map with the current list of Commands for the CLI.

func (*GomCLI) RemoveCommand

func (c *GomCLI) RemoveCommand(name string)

RemoveCommand removes a specific Command from the CLI by name.

func (*GomCLI) SetCommands

func (c *GomCLI) SetCommands(cmds []Command)

SetCommands replaces the current CLI set of Commands by a new slice.

func (*GomCLI) SetCtrlCAborts

func (c *GomCLI) SetCtrlCAborts(aborts bool)

SetCtrlCAborts sets whether Start will return an ErrPromptAborted when Ctrl-C is pressed. The default is false (will not return when Ctrl-C is pressed).

func (*GomCLI) SetExitOnCmdError

func (c *GomCLI) SetExitOnCmdError(value bool)

SetExitOnCmdError sets whether Start shall be interrupted and return the error as soon as an error unhandled in the Command.ErrHandler is propagated.

func (*GomCLI) SetHistoryFile

func (c *GomCLI) SetHistoryFile(path string)

SetHistoryFile sets the path for the command history file. If not set, no history file will be used. The history file has a fixed limit of 1000 entries.

func (*GomCLI) SetNotFoundHandler

func (c *GomCLI) SetNotFoundHandler(function NotFoundHandler)

SetNotFoundHandler sets the function that will be called when the provided input does not match any known Command.

func (*GomCLI) SetPrompt

func (c *GomCLI) SetPrompt(prompt string)

SetPrompt sets the prompt for the CLI. Note that due to Liner's multi-platform nature, colored prompts are not supported.

func (*GomCLI) Start

func (c *GomCLI) Start() error

Start starts the CLI, iteratively displaying the prompt and handling user input until Close is called or an error is returned during user input processing.

func (*GomCLI) StartWithInput

func (c *GomCLI) StartWithInput(input string) error

StartWithInput starts the CLI by providing initial input that will be split into lines and, if applicable, into commands.

type NotFoundHandler

type NotFoundHandler func(string) error

NotFoundHandler is a function that indicates gomcli how to handle input that does not match any known Command. If not set, default action is to ignore it. An error can be returned, that will be propagated so that it is returned by Start, terminating the CLI.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL