grumble

package module
v0.0.0-...-3953015 Latest Latest
Warning

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

Go to latest
Published: Mar 28, 2023 License: MIT Imports: 12 Imported by: 0

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

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

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

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

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

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

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

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

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

Write to the underlying output, using readline if available.

type ArgMap

type ArgMap map[string]*ArgMapItem

ArgMap holds all the parsed arg values.

func (ArgMap) Bool

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

type ArgMapItem struct {
	Value     interface{}
	IsDefault bool
}

ArgMapItem holds the specific arg data.

type ArgOption

type ArgOption func(*argItem)

ArgOption can be supplied to modify an argument.

func Default

func Default(v interface{}) ArgOption

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

func Max

func Max(m int) ArgOption

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

func Min

func Min(m int) ArgOption

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

type Args

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

Args holds all the registered args.

func (*Args) Bool

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

Bool registers a bool argument.

func (*Args) BoolList

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

BoolList registers a bool list argument.

func (*Args) Duration

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

Duration registers a duration argument.

func (*Args) DurationList

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

DurationList registers an duration list argument.

func (*Args) Float64

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

Float64 registers a float64 argument.

func (*Args) Float64List

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

Float64List registers an float64 list argument.

func (*Args) Int

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

Int registers an int argument.

func (*Args) Int64

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

Int64 registers an int64 argument.

func (*Args) Int64List

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

Int64List registers an int64 list argument.

func (*Args) IntList

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

IntList registers an int list argument.

func (*Args) String

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

String registers a string argument.

func (*Args) StringList

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

StringList registers a string list argument.

func (*Args) Uint

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

Uint registers an uint argument.

func (*Args) Uint64

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

Uint64 registers an uint64 argument.

func (*Args) Uint64List

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

Uint64List registers an uint64 list argument.

func (*Args) UintList

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

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

Remove a command from the slice.

func (*Commands) RemoveAll

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) 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) 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) 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) 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) 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) 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) Uint

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

Uint registers an uint flag.

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

Jump to

Keyboard shortcuts

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