grumble

package module
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Mar 31, 2026 License: MIT Imports: 12 Imported by: 391

README

Grumble - A powerful modern CLI and SHELL

GoDoc Go Report Card

There are a handful of powerful go CLI libraries available (spf13/cobra, urfave/cli). However sometimes an integrated shell interface is a great and useful extension for the actual application. This library offers a simple API to create powerful CLI applications and automatically starts an integrated interactive shell, if the application is started without any command arguments.

Hint: We do not guarantee 100% backwards compatiblity between minor versions (1.x). However, the API is mostly stable and should not change much.

asciicast

Introduction

Create a grumble APP.

var app = grumble.New(&grumble.Config{
	Name:        "app",
	Description: "short app description",

	Flags: func(f *grumble.Flags) {
		f.String("d", "directory", "DEFAULT", "set an alternative directory path")
		f.Bool("v", "verbose", false, "enable verbose mode")
	},
})

Register a top-level command. Note: Sub commands are also supported...

app.AddCommand(&grumble.Command{
    Name:      "daemon",
    Help:      "run the daemon",
    Aliases:   []string{"run"},

    Flags: func(f *grumble.Flags) {
        f.Duration("t", "timeout", time.Second, "timeout duration")
    },

    Args: func(a *grumble.Args) {
        a.String("service", "which service to start", grumble.Default("server"))
    },

    Run: func(c *grumble.Context) error {
        // Parent Flags.
        c.App.Println("directory:", c.Flags.String("directory"))
        c.App.Println("verbose:", c.Flags.Bool("verbose"))
        // Flags.
        c.App.Println("timeout:", c.Flags.Duration("timeout"))
        // Args.
        c.App.Println("service:", c.Args.String("service"))
        return nil
    },
})

Run the application.

err := app.Run()

Or use the builtin grumble.Main function to handle errors automatically.

func main() {
	grumble.Main(app)
}

Shell Multiline Input

Builtin support for multiple lines.

>>> This is \
... a multi line \
... command

Flags

You can pass flags in two ways: cmd --flag value or cmd --flag=value
There are some exceptions/additions to this:

  • bool: cmd --boolflag offer a third option that does not require a value
  • string: cmd --stringflag="some test string" leads to value some test string, as double quotes are stripped from the value

Separate flags and args specifically

If you need to pass a flag-like value as positional argument, you can do so by using a double dash:
>>> command --flag1=something -- --myPositionalArg

Remote shell access with readline

By calling RunWithReadline() rather than Run() you can pass instance of readline.Instance. One of interesting usages is having a possibility of remote access to your shell:

handleFunc := func(rl *readline.Instance) {

    var app = grumble.New(&grumble.Config{
        // override default interrupt handler to avoid remote shutdown
        InterruptHandler: func(a *grumble.App, count int) {
            // do nothing
        },
		
        // your usual grumble configuration
    })  
    
    // add commands
	
    app.RunWithReadline(rl)

}

cfg := &readline.Config{}
readline.ListenRemote("tcp", ":5555", cfg, handleFunc)

In the client code just use readline built in DialRemote function:

if err := readline.DialRemote("tcp", ":5555"); err != nil {
    fmt.Errorf("An error occurred: %s \n", err.Error())
}

Samples

Check out the sample directory for some detailed examples.

Projects using Grumble

Known issues

  • Windows unicode not fully supported (issue)

Additional Useful Packages

Credits

This project is based on ideas from the great ishell library.

License

MIT

Documentation

Overview

Package grumble is a powerful modern CLI and SHELL.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Main

func Main(a *App)

Main is a shorthand to run the app within the main function. This function will handle the error and exit the application on error.

Types

type App

type App struct {
	closer.Closer
	// contains filtered or unexported fields
}

App is the entrypoint.

func New

func New(c *Config) (a *App)

New creates a new app. Panics if the config is invalid.

func (*App) AddCommand

func (a *App) AddCommand(cmd *Command)

AddCommand adds a new command. Panics on error.

func (*App) Commands

func (a *App) Commands() *Commands

Commands returns the app's commands. Access is not thread-safe. Only access during command execution.

func (*App) Config

func (a *App) Config() *Config

Config returns the app's config value.

func (*App) IsShell

func (a *App) IsShell() bool

IsShell indicates, if this is a shell session.

func (*App) OnInit

func (a *App) OnInit(f func(a *App, flags FlagMap) error)

OnInit sets the function which will be executed before the first command is executed. App flags can be handled here.

func (*App) OnShell

func (a *App) OnShell(f func(a *App) error)

OnShell sets the function which will be executed before the shell starts.

func (*App) Print added in v1.1.1

func (a *App) Print(args ...interface{}) (int, error)

Print writes to terminal output. Print writes to standard output if terminal output is not yet active.

func (*App) PrintError

func (a *App) PrintError(err error)

PrintError prints the given error.

func (*App) Printf added in v1.0.4

func (a *App) Printf(format string, args ...interface{}) (int, error)

Printf formats according to a format specifier and writes to terminal output. Printf writes to standard output if terminal output is not yet active.

func (*App) Println added in v1.0.4

func (a *App) Println(args ...interface{}) (int, error)

Println writes to terminal output followed by a newline. Println writes to standard output if terminal output is not yet active.

func (*App) Run

func (a *App) Run() (err error)

Run the application and parse the command line arguments. This method blocks.

func (*App) RunCommand

func (a *App) RunCommand(args []string) error

RunCommand runs a single command.

func (*App) RunWithReadline added in v1.2.0

func (a *App) RunWithReadline(rl *readline.Instance) (err error)

func (*App) SetDefaultPrompt

func (a *App) SetDefaultPrompt()

SetDefaultPrompt resets the current prompt to the default prompt as configured in the config.

func (*App) SetInterruptHandler

func (a *App) SetInterruptHandler(f func(a *App, count int))

SetInterruptHandler sets the interrupt handler function.

func (a *App) SetPrintASCIILogo(f func(a *App))

SetPrintASCIILogo sets the function to print the ASCII logo.

func (*App) SetPrintCommandHelp

func (a *App) SetPrintCommandHelp(f func(a *App, c *Command, shell bool))

SetPrintCommandHelp sets the print help function for a single command.

func (*App) SetPrintHelp

func (a *App) SetPrintHelp(f func(a *App, shell bool))

SetPrintHelp sets the print help function.

func (*App) SetPrompt

func (a *App) SetPrompt(p string)

SetPrompt sets a new prompt.

func (*App) Stderr added in v1.0.4

func (a *App) Stderr() io.Writer

Stderr returns a writer to Stderr, using readline if available. Note that calling before Run() will return a different instance.

func (*App) Stdout added in v1.0.4

func (a *App) Stdout() io.Writer

Stdout returns a writer to Stdout, using readline if available. Note that calling before Run() will return a different instance.

func (*App) Write added in v1.0.4

func (a *App) Write(p []byte) (int, error)

Write to the underlying output, using readline if available.

type ArgMap added in v1.1.0

type ArgMap map[string]*ArgMapItem

ArgMap holds all the parsed arg values.

func (ArgMap) Bool added in v1.1.0

func (a ArgMap) Bool(long string) bool

Bool returns the given arg value as bool. Panics if not present. Args must be registered.

func (ArgMap) BoolList added in v1.1.0

func (a ArgMap) BoolList(long string) []bool

BoolList returns the given arg value as bool slice. Panics if not present. Args must be registered.

func (ArgMap) Duration added in v1.1.0

func (a ArgMap) Duration(long string) time.Duration

Duration returns the given arg value as duration. Panics if not present. Args must be registered.

func (ArgMap) DurationList added in v1.1.0

func (a ArgMap) DurationList(long string) []time.Duration

DurationList returns the given arg value as duration. Panics if not present. Args must be registered.

func (ArgMap) Float64 added in v1.1.0

func (a ArgMap) Float64(long string) float64

Float64 returns the given arg value as float64. Panics if not present. Args must be registered.

func (ArgMap) Float64List added in v1.1.0

func (a ArgMap) Float64List(long string) []float64

Float64List returns the given arg value as float64. Panics if not present. Args must be registered.

func (ArgMap) Int added in v1.1.0

func (a ArgMap) Int(long string) int

Int returns the given arg value as int. Panics if not present. Args must be registered.

func (ArgMap) Int64 added in v1.1.0

func (a ArgMap) Int64(long string) int64

Int64 returns the given arg value as int64. Panics if not present. Args must be registered.

func (ArgMap) Int64List added in v1.1.0

func (a ArgMap) Int64List(long string) []int64

Int64List returns the given arg value as int64. Panics if not present. Args must be registered.

func (ArgMap) IntList added in v1.1.0

func (a ArgMap) IntList(long string) []int

IntList returns the given arg value as int slice. Panics if not present. Args must be registered.

func (ArgMap) String added in v1.1.0

func (a ArgMap) String(name string) string

String returns the given arg value as string. Panics if not present. Args must be registered.

func (ArgMap) StringList added in v1.1.0

func (a ArgMap) StringList(long string) []string

StringList returns the given arg value as string slice. Panics if not present. Args must be registered. If optional and not provided, nil is returned.

func (ArgMap) Uint added in v1.1.0

func (a ArgMap) Uint(long string) uint

Uint returns the given arg value as uint. Panics if not present. Args must be registered.

func (ArgMap) Uint64 added in v1.1.0

func (a ArgMap) Uint64(long string) uint64

Uint64 returns the given arg value as uint64. Panics if not present. Args must be registered.

func (ArgMap) Uint64List added in v1.1.0

func (a ArgMap) Uint64List(long string) []uint64

Uint64List returns the given arg value as uint64. Panics if not present. Args must be registered.

func (ArgMap) UintList added in v1.1.0

func (a ArgMap) UintList(long string) []uint

UintList returns the given arg value as uint. Panics if not present. Args must be registered.

type ArgMapItem added in v1.1.0

type ArgMapItem struct {
	Value     interface{}
	IsDefault bool
}

ArgMapItem holds the specific arg data.

type ArgOption added in v1.1.0

type ArgOption func(*argItem)

ArgOption can be supplied to modify an argument.

func Default added in v1.1.0

func Default(v interface{}) ArgOption

Default sets a default value for the argument. The argument becomes optional then.

func Max added in v1.1.0

func Max(m int) ArgOption

Max sets the maximum required number of elements for a list argument.

func Min added in v1.1.0

func Min(m int) ArgOption

Min sets the minimum required number of elements for a list argument.

type Args added in v1.1.0

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

Args holds all the registered args.

func (*Args) Bool added in v1.1.0

func (a *Args) Bool(name, help string, opts ...ArgOption)

Bool registers a bool argument.

func (*Args) BoolList added in v1.1.0

func (a *Args) BoolList(name, help string, opts ...ArgOption)

BoolList registers a bool list argument.

func (*Args) Duration added in v1.1.0

func (a *Args) Duration(name, help string, opts ...ArgOption)

Duration registers a duration argument.

func (*Args) DurationList added in v1.1.0

func (a *Args) DurationList(name, help string, opts ...ArgOption)

DurationList registers an duration list argument.

func (*Args) Float64 added in v1.1.0

func (a *Args) Float64(name, help string, opts ...ArgOption)

Float64 registers a float64 argument.

func (*Args) Float64List added in v1.1.0

func (a *Args) Float64List(name, help string, opts ...ArgOption)

Float64List registers an float64 list argument.

func (*Args) Int added in v1.1.0

func (a *Args) Int(name, help string, opts ...ArgOption)

Int registers an int argument.

func (*Args) Int64 added in v1.1.0

func (a *Args) Int64(name, help string, opts ...ArgOption)

Int64 registers an int64 argument.

func (*Args) Int64List added in v1.1.0

func (a *Args) Int64List(name, help string, opts ...ArgOption)

Int64List registers an int64 list argument.

func (*Args) IntList added in v1.1.0

func (a *Args) IntList(name, help string, opts ...ArgOption)

IntList registers an int list argument.

func (*Args) String added in v1.1.0

func (a *Args) String(name, help string, opts ...ArgOption)

String registers a string argument.

func (*Args) StringList added in v1.1.0

func (a *Args) StringList(name, help string, opts ...ArgOption)

StringList registers a string list argument.

func (*Args) Uint added in v1.1.0

func (a *Args) Uint(name, help string, opts ...ArgOption)

Uint registers an uint argument.

func (*Args) Uint64 added in v1.1.0

func (a *Args) Uint64(name, help string, opts ...ArgOption)

Uint64 registers an uint64 argument.

func (*Args) Uint64List added in v1.1.0

func (a *Args) Uint64List(name, help string, opts ...ArgOption)

Uint64List registers an uint64 list argument.

func (*Args) UintList added in v1.1.0

func (a *Args) UintList(name, help string, opts ...ArgOption)

UintList registers an uint list argument.

type Command

type Command struct {
	// Command name.
	// This field is required.
	Name string

	// Command name aliases.
	Aliases []string

	// One liner help message for the command.
	// This field is required.
	Help string

	// More descriptive help message for the command.
	LongHelp string

	// HelpGroup defines the help group headline.
	// Note: this is only used for primary top-level commands.
	HelpGroup string

	// Usage should define how to use the command.
	// Sample: start [OPTIONS] CONTAINER [CONTAINER...]
	Usage string

	// Define all command flags within this function.
	Flags func(f *Flags)

	// Define all command arguments within this function.
	Args func(a *Args)

	// Function to execute for the command.
	Run func(c *Context) error

	// Completer is custom autocompleter for command.
	// It takes in command arguments and returns autocomplete options.
	// By default all commands get autocomplete of subcommands.
	// A non-nil Completer overrides the default behaviour.
	Completer func(prefix string, args []string) []string
	// contains filtered or unexported fields
}

Command is just that, a command for your application.

func (*Command) AddCommand

func (c *Command) AddCommand(cmd *Command)

AddCommand adds a new command. Panics on error.

func (*Command) Parent

func (c *Command) Parent() *Command

Parent returns the parent command or nil.

type Commands

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

Commands collection.

func (*Commands) Add

func (c *Commands) Add(cmd *Command)

Add the command to the slice. Duplicates are ignored.

func (*Commands) All

func (c *Commands) All() []*Command

All returns a slice of all commands.

func (*Commands) FindCommand

func (c *Commands) FindCommand(args []string) (cmd *Command, rest []string, err error)

FindCommand searches for the final command through all children. Returns a slice of non processed following command args. Returns cmd=nil if not found.

func (*Commands) Get

func (c *Commands) Get(name string) *Command

Get the command by the name. Aliases are also checked. Returns nil if not found.

func (*Commands) Remove added in v1.1.3

func (c *Commands) Remove(name string) (found bool)

Remove a command from the slice.

func (*Commands) RemoveAll added in v1.1.3

func (c *Commands) RemoveAll()

func (*Commands) Sort

func (c *Commands) Sort()

Sort the commands by their name.

func (*Commands) SortRecursive

func (c *Commands) SortRecursive()

SortRecursive sorts the commands by their name including all sub commands.

type Config

type Config struct {
	// Name specifies the application name. This field is required.
	Name string

	// Description specifies the application description.
	Description string

	// Define all app command flags within this function.
	Flags func(f *Flags)

	// Persist readline historys to file if specified.
	HistoryFile string

	// Specify the max length of historys, it's 500 by default, set it to -1 to disable history.
	HistoryLimit int

	// NoColor defines if color output should be disabled.
	NoColor bool

	// VimMode defines if Readline is to use VimMode for line navigation.
	VimMode bool

	// Prompt defines the shell prompt.
	Prompt      string
	PromptColor *color.Color

	// MultiPrompt defines the prompt shown on multi readline.
	MultiPrompt      string
	MultiPromptColor *color.Color

	// Some more optional color settings.
	ASCIILogoColor *color.Color
	ErrorColor     *color.Color

	// Help styling.
	HelpHeadlineUnderline bool
	HelpSubCommands       bool
	HelpHeadlineColor     *color.Color

	// Override default iterrupt handler
	InterruptHandler func(a *App, count int)
}

Config specifies the application options.

func (*Config) SetDefaults

func (c *Config) SetDefaults()

SetDefaults sets the default values if not set.

func (*Config) Validate

func (c *Config) Validate() error

Validate the required config fields.

type Context

type Context struct {
	// Reference to the app.
	App *App

	// Flags contains all command line flags.
	Flags FlagMap

	// Args contains all command line arguments.
	Args ArgMap

	// Cmd is the currently executing command.
	Command *Command
}

Context defines a command context.

func (*Context) Stop

func (c *Context) Stop()

Stop signalizes the app to exit.

type FlagMap

type FlagMap map[string]*FlagMapItem

FlagMap holds all the parsed flag values.

func (FlagMap) Bool

func (f FlagMap) Bool(long string) bool

Bool returns the given flag value as boolean. Panics if not present. Flags must be registered.

func (FlagMap) Duration

func (f FlagMap) Duration(long string) time.Duration

Duration returns the given flag value as duration. Panics if not present. Flags must be registered.

func (FlagMap) Float32 added in v1.3.0

func (f FlagMap) Float32(long string) float32

Float32 returns the given flag value as float32. Panics if not present. Flags must be registered.

func (FlagMap) Float64

func (f FlagMap) Float64(long string) float64

Float64 returns the given flag value as float64. Panics if not present. Flags must be registered.

func (FlagMap) Int

func (f FlagMap) Int(long string) int

Int returns the given flag value as int. Panics if not present. Flags must be registered.

func (FlagMap) Int8 added in v1.3.0

func (f FlagMap) Int8(long string) int8

Int8 returns the given flag value as int8. Panics if not present. Flags must be registered.

func (FlagMap) Int16 added in v1.3.0

func (f FlagMap) Int16(long string) int16

Int16 returns the given flag value as int16. Panics if not present. Flags must be registered.

func (FlagMap) Int32 added in v1.3.0

func (f FlagMap) Int32(long string) int32

Int32 returns the given flag value as int32. Panics if not present. Flags must be registered.

func (FlagMap) Int64

func (f FlagMap) Int64(long string) int64

Int64 returns the given flag value as int64. Panics if not present. Flags must be registered.

func (FlagMap) String

func (f FlagMap) String(long string) string

String returns the given flag value as string. Panics if not present. Flags must be registered.

func (FlagMap) StringList added in v1.3.0

func (f FlagMap) StringList(long string) []string

StringList returns the given flag value as string slice. Panics if not present. Flags must be registered.

func (FlagMap) Uint

func (f FlagMap) Uint(long string) uint

Uint returns the given flag value as uint. Panics if not present. Flags must be registered.

func (FlagMap) Uint8 added in v1.3.0

func (f FlagMap) Uint8(long string) uint8

Uint8 returns the given flag value as uint8. Panics if not present. Flags must be registered.

func (FlagMap) Uint16 added in v1.3.0

func (f FlagMap) Uint16(long string) uint16

Uint16 returns the given flag value as uint16. Panics if not present. Flags must be registered.

func (FlagMap) Uint32 added in v1.3.0

func (f FlagMap) Uint32(long string) uint32

Uint32 returns the given flag value as uint32. Panics if not present. Flags must be registered.

func (FlagMap) Uint64

func (f FlagMap) Uint64(long string) uint64

Uint64 returns the given flag value as uint64. Panics if not present. Flags must be registered.

type FlagMapItem

type FlagMapItem struct {
	Value     interface{}
	IsDefault bool
}

FlagMapItem holds the specific flag data.

type Flags

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

Flags holds all the registered flags.

func (*Flags) Bool

func (f *Flags) Bool(short, long string, defaultValue bool, help string)

Bool registers a boolean flag.

func (*Flags) BoolL

func (f *Flags) BoolL(long string, defaultValue bool, help string)

BoolL same as Bool, but without a shorthand.

func (*Flags) Duration

func (f *Flags) Duration(short, long string, defaultValue time.Duration, help string)

Duration registers a duration flag.

func (*Flags) DurationL

func (f *Flags) DurationL(long string, defaultValue time.Duration, help string)

DurationL same as Duration, but without a shorthand.

func (*Flags) Float32 added in v1.3.0

func (f *Flags) Float32(short, long string, defaultValue float32, help string)

Float32 registers an float32 flag.

func (*Flags) Float32L added in v1.3.0

func (f *Flags) Float32L(long string, defaultValue float32, help string)

Float32L same as Float32, but without a shorthand.

func (*Flags) Float64

func (f *Flags) Float64(short, long string, defaultValue float64, help string)

Float64 registers an float64 flag.

func (*Flags) Float64L

func (f *Flags) Float64L(long string, defaultValue float64, help string)

Float64L same as Float64, but without a shorthand.

func (*Flags) Int

func (f *Flags) Int(short, long string, defaultValue int, help string)

Int registers an int flag.

func (*Flags) Int8 added in v1.3.0

func (f *Flags) Int8(short, long string, defaultValue int8, help string)

Int8 registers an int8 flag.

func (*Flags) Int8L added in v1.3.0

func (f *Flags) Int8L(long string, defaultValue int8, help string)

Int8L same as Int8, but without a shorthand.

func (*Flags) Int16 added in v1.3.0

func (f *Flags) Int16(short, long string, defaultValue int16, help string)

Int16 registers an int16 flag.

func (*Flags) Int16L added in v1.3.0

func (f *Flags) Int16L(long string, defaultValue int16, help string)

Int16L same as Int16, but without a shorthand.

func (*Flags) Int32 added in v1.3.0

func (f *Flags) Int32(short, long string, defaultValue int32, help string)

Int32 registers an int32 flag.

func (*Flags) Int32L added in v1.3.0

func (f *Flags) Int32L(long string, defaultValue int32, help string)

Int32L same as Int32, but without a shorthand.

func (*Flags) Int64

func (f *Flags) Int64(short, long string, defaultValue int64, help string)

Int64 registers an int64 flag.

func (*Flags) Int64L

func (f *Flags) Int64L(long string, defaultValue int64, help string)

Int64L same as Int64, but without a shorthand.

func (*Flags) IntL

func (f *Flags) IntL(long string, defaultValue int, help string)

IntL same as Int, but without a shorthand.

func (*Flags) String

func (f *Flags) String(short, long, defaultValue, help string)

String registers a string flag.

func (*Flags) StringL

func (f *Flags) StringL(long, defaultValue, help string)

StringL same as String, but without a shorthand.

func (*Flags) StringList added in v1.3.0

func (f *Flags) StringList(short, long string, defaultValue []string, help string)

StringList registers a string list flag.

func (*Flags) StringListL added in v1.3.0

func (f *Flags) StringListL(long string, defaultValue []string, help string)

StringListL same as StringList, but without a shorthand.

func (*Flags) Uint

func (f *Flags) Uint(short, long string, defaultValue uint, help string)

Uint registers an uint flag.

func (*Flags) Uint8 added in v1.3.0

func (f *Flags) Uint8(short, long string, defaultValue uint8, help string)

Uint8 registers an uint8 flag.

func (*Flags) Uint8L added in v1.3.0

func (f *Flags) Uint8L(long string, defaultValue uint8, help string)

Uint8L same as Uint8, but without a shorthand.

func (*Flags) Uint16 added in v1.3.0

func (f *Flags) Uint16(short, long string, defaultValue uint16, help string)

Uint16 registers an uint16 flag.

func (*Flags) Uint16L added in v1.3.0

func (f *Flags) Uint16L(long string, defaultValue uint16, help string)

Uint16L same as Uint16, but without a shorthand.

func (*Flags) Uint32 added in v1.3.0

func (f *Flags) Uint32(short, long string, defaultValue uint32, help string)

Uint32 registers an uint32 flag.

func (*Flags) Uint32L added in v1.3.0

func (f *Flags) Uint32L(long string, defaultValue uint32, help string)

Uint32L same as Uint32, but without a shorthand.

func (*Flags) Uint64

func (f *Flags) Uint64(short, long string, defaultValue uint64, help string)

Uint64 registers an uint64 flag.

func (*Flags) Uint64L

func (f *Flags) Uint64L(long string, defaultValue uint64, help string)

Uint64L same as Uint64, but without a shorthand.

func (*Flags) UintL

func (f *Flags) UintL(long string, defaultValue uint, help string)

UintL same as Uint, but without a shorthand.

Directories

Path Synopsis
sample
full command
readline command
readline/cli command
simple command

Jump to

Keyboard shortcuts

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