commander

package module
v0.0.0-...-30fc570 Latest Latest
Warning

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

Go to latest
Published: Dec 26, 2023 License: Apache-2.0 Imports: 10 Imported by: 0

README

commander

Go package for building commands with sub commands.

This package is useful for writing tools that have subcommands. An example of a command with subcommands is git.

It uses the github.com/pborman/flags package for declaring flags in a structured way. That package is a wrapper around the standard flags package.

Documentation

Overview

Package commander is yet another commander packge that facilitates a sub command structure. It uses the github.com/pborman/flags package to specify the flags for a given command. Since the flags package is a wrapper around the standard flag package.

A Command is specified by the Command structure. The simplest declaration is

var mycmd = &commander.Command{
	Name: "mycmd",
	Func: func(context.Context, *Command, []string, ...any) error {
		fmt.Print("Hello World\n")
		return nikl
	},
}

The simplest decleration of a command that has sub commands is:

var cmd = &commander.Command{
	Name:        "cmd",
	SubCommands: []*commander.Command{mycmd},
}

Each command can have a set of flags associated with it. Flags are declared as a structure as defined by the github.com/pborman/flags. A simple example is:

var options = &struct{
	N    int    `flag:"-n=N          number of itterations"
	Name string `flag:"--name=NAME   set the projects name"
} {
	N: 1, // -n defaults to 1.
}

The flags are specified by either the Defaults or the Flags field. If the Defaults field is set to the Flags field will be automatically set to a copy of the flags. This is useful if the command might be executed more than once as each invocation will have a fresh set of flags. If the Flags field is set no copies are made and the values will persist between invocations.

For example:

var cmd = &commander.Command{
	Name:        "cmd",
	Defaults:    options,
	SubCommands: []*commander.Command{mycmd},
}

The commander package has a predefined help command:

var HelpCmd = &Command{
	Name: "help",
	Help: "display help",
	Func: Help,
}

The Help command utilizes three optional fields:

Help - A single line description of the command
Description - A long description of the command
Parameters - What parameters the command takes.

As an example:

var HelpCmd = &Command{
	Name:        "help",
	Help:        "display help",
	Description: `
}

The help command displays help for the program or sub command.
Example usage:

	help
	help sub
	help sub subsub
`,
	Parameters: "[cmd [cmd ...]",
}

There are also optional fields to help with parsing the command.

The MinArgs and MaxArgs fields specify the minimum and maximum number of position parameters for the command. If MaxArgs is 0 there is no upper limit. If MaxArgs is set to commander.NoArgs then the command takes no positional parameters.

The Stderr field specifies where commandeer should send output (usage or help). If Stderr is not specified it defaults to os.Stderr. All sub commands that do not specify Stderr will inherit the main command's Stderr.

OnError, when specified, is set to a function to be called when a usage error is encountered. There are two pre-defined OnError functions:

ExitOnError - Display the message on Stderr and call os.Exit(1) ContinueOnError - Display the message on Stderr and return nil

If OnError is nil, the default, then the error is returned.

Index

Constants

View Source
const (
	StrictDelim   = 0
	TrailingDelim = 1 << iota
	PreceedingDelim
	AnyDelim
)

The following are options to the SplitCommand function. They determine how to split the command. Assuming the deliminter is ';' then command1 and command2:

StrictDelim - command1 ; command2 (always works)
TrailingDelim - command1; command2
PreceedingDelim - command1 ;command2
AnyDelim - command1;command2
View Source
const NoArgs = -1

If MaxArgs is set to NoArgs then the command takes no arguments.

Variables

View Source
var Exit = os.Exit

Exit can be overriden by tests.

View Source
var HelpCmd = &Command{
	Name: "help",
	Help: "display help",
	Func: Help,
}

HelpCmd is a sub command that calls the Help function.

Functions

func ContinueOnError

func ContinueOnError(c *Command, _ []string, _ []any, err error) error

ContinueOnError is on OnError func that displays the error and returns no error.

func ExitOnError

func ExitOnError(c *Command, _ []string, _ []any, err error) error

ExitOnError is an OnError func that displays the error and exits with a return code of 1.

func Help

func Help(ctx context.Context, c *Command, args []string, extra ...any) error

Help implements the help command.

Usage: help [subcommand [subcommand [...]]]

func SplitCommand

func SplitCommand(args []string, delim string, options int) [][]string

Types

type Command

type Command struct {
	Name        string // Name of this command
	Help        string // Short description of this command
	Description string // Long description displayed by help
	Parameters  string // Parameters to go at the end of the usage line
	MinArgs     int    // The command must have at least this many arguments
	MaxArgs     int    // Maximum number of arguments.  0 means no limit
	Defaults    any    // An options struct as defined by the flags package
	Flags       any    // See above for Defaults vs Flags
	Func        func(context.Context, *Command, []string, ...any) error
	SubCommands []*Command // Sub-Commands -- Ignored if Func is set

	// Errors are displayed to Stderr (defaults to os.Stderr).
	// If not nil, OnError is called when there is a usage error
	// running a command.  If these values are nil then
	// their parent's values are used.
	Stderr  io.Writer
	OnError func(*Command, []string, []any, error) error
	// contains filtered or unexported fields
}

A Command can either be a function and/or a list of subcommands. A Command normally only declares Func or SubCommands. If they are both set only Func is called. Func may call c.RunSubcommands to execute a sub command.

Flags for the command are a structure as defined by the github.com/pborman/flags package. Use the Flags field to see the value of a flags. If the flags are provided through the Default field instead of the Flags field then Flags will contain a copy of the flags. Using Defaults makes it possible to run the command multiple times with the same set of flags.

Currently an individual Command cannot be run concurrently with itself.

To run the command c, call c.Run. The arguments passed to c.Run must not include the command name.

func (*Command) Command

func (c *Command) Command() string

Command returns the possibly multi-part command name for c.

func (*Command) Lookup

func (c *Command) Lookup(cmd, name string) any

Lookup returns the value of the flag named flag. If cmd is not empty Lookup will look for a command in the tree that is named cmd. For example, consider the command "foo" that has a sub command "bar":

foo --name VALUE1 bar --name VALEUE2

bar.Lookup("", "name") -> VALUE2
bar.Lookup("foo", "name") -> VALUE1

func (*Command) PrintUsage

func (c *Command) PrintUsage(w io.Writer)

PrintUsage write the usage information for c to w.

func (*Command) Run

func (c *Command) Run(ctx context.Context, args []string, extra ...any) (err error)

Run runs the command with the provided arguments after parsing any flags. The command name itself is not part of the arguments. If c does not have a Func defined then the first argument is used to find the subcommand listed in SubCommands. The subcommand's Run method is then called with the arguments following the subcommand. An error is returned if the command could not be run or the command failed.

If the command has both Func and SubCommands then Func is called if there are no positional parameters otherwise the first argument is used to find the sub command listed in SubCommands.

func (*Command) RunSubcommands

func (c *Command) RunSubcommands(ctx context.Context, args []string, extra ...any) (err error)

RunSubcommands is similar to Run excpet it ignores c.Func and just runs sub commands.

type UsageError

type UsageError struct {
	C   *Command
	Err error
}

A UsageError is returned when there is an error in usage.

func (*UsageError) Error

func (u *UsageError) Error() string

Implements the error interface.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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