command

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Apr 4, 2017 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package command provides a Command interface and a Commander type that is able to execute a command line application that does "one" thing, i.e. without subcommands.

The Command type provides methods needed for parsing and setting command line arguments and executing code once parsing is complete.

The Commander type is a simple wrapper that handles executing a Command and providing help and error output in the case of errors not related to executing a Command.

The help and error output follow the general form loosely based on Go templates.

{{.ErrorIfAParsingErrorNotAnExecutionError}}

{{.CommandNameAndDescriptionIfErrHelp}}

usage: {{.Commander.Name}} {{.AvailableCommandLineArguments}}

{{.AvailableFlagOptionUsageIfThereAreOptions}}

{{.AvailableParameterUsageIfThereAreParameters}}

Please see the examples for actual output.

Example
count := 0
fs := clitest.FlagSetterFunc(func(f *flag.FlagSet) {
	f.IntVar(&count, "count", count, "number of times to print parameters")
})

var params []string
command := &CommandStruct{
	DescriptionValue: "example description",
	FlagSetter:       fs,
	ParameterSetter: &clitest.ParameterSetterStruct{
		SetParametersValue: func(p []string) error {
			params = append([]string{}, p...)
			return nil
		},
	},
	ExecuteValue: func(_ context.Context, _ io.Reader, out, _ io.Writer) error {
		for _, p := range params {
			for c := 0; c < count; c++ {
				fmt.Fprintf(out, "%s", p)
			}
		}
		fmt.Fprintln(out)
		return nil
	},
}

commander := &Commander{
	Name:    "example",
	Command: command,
}

err := commander.Execute(strings.Fields("a -count 2 b"))
if err != nil {
	fmt.Println(err)
}
Output:
aabb
Example (ErrorFlagErrHelp)
command := &CommandStruct{
	DescriptionValue: "this is a description.",
	ParameterSetter: &clitest.ParameterSetterStruct{
		ParameterUsageValue: func() ([]*cli.Parameter, string) {
			return []*cli.Parameter{
				&cli.Parameter{
					Name: "p1",
				},
				&cli.Parameter{
					Name:     "p2s",
					Optional: true,
					Many:     true,
				},
			}, "extra parameter usage"
		},
	},
}

commander := &Commander{
	Name:    "example_help",
	Command: command,
}

//We set the outErr parameter to os.Stdout so that we can validate the test output.
commander.ExecuteContext(
	context.Background(),
	strings.Fields("-h"),
	os.Stdin,
	os.Stdout,
	os.Stdout,
)
Output:
example_help - this is a description.

usage: example_help [parameters...]

parameters: <P1> [P2S...]
extra parameter usage
Example (ErrorParsingArguments)
fs := clitest.FlagSetterFunc(func(f *flag.FlagSet) {
	f.Int("count", 0, "number of times to print parameters")
})

command := &CommandStruct{
	DescriptionValue: "this is a description.",
	FlagSetter:       fs,

	//Note that we do not set ExecuteValue. It will not be called since there
	//is an argument parsing error.
}

commander := &Commander{
	Name:    "example_error",
	Command: command,
}

//We set the outErr parameter to os.Stdout so that we can validate the test output.
commander.ExecuteContext(
	context.Background(),
	strings.Fields("-value foobar"),
	os.Stdin,
	os.Stdout,
	os.Stdout,
)

//The Output: below may look weird because of the tab and space formatting
//and what is required by the testing package.
Output:
flag provided but not defined: -value

usage: example_error [options...]

options:
  -count int
    	number of times to print parameters

Index

Examples

Constants

View Source
const (
	Usage = "usage:"

	OptionsName = "options"

	ParametersName = "parameters"

	ArgumentSeparator = " | "
)

Output values that affect error and help output.

Variables

View Source
var FormatArgument = cli.FormatArgument

FormatArgument formats an argument's name given whether or not it is optional or multiple values are allowed.

This value may be changed to affect the output of this package.

View Source
var FormatParameter = cli.FormatParameter

FormatParameter returns a string representation of p appropriate for help and error output.

This value may be changed to affect the output of this package.

View Source
var FormatParameterName = cli.FormatParameterName

FormatParameterName returns a string representation of a Parameter name appropriate for help and error output.

This value my be changed to affect the output of this package.

Functions

func IsExecutionError

func IsExecutionError(err error) bool

IsExecutionError returns whether or not err is an ExecutingcommandError.

Types

type Command

type Command interface {
	//Description returns a description of the Command.
	Description() string

	//FlagSetter for Command flags.
	//
	//This value may be called multiple times with different values for f if argument
	//parsing fails. This is done to obtain possible help and error output.
	//If there are no errors during the argument parsing process, then SetFlags
	//is only called once. Thus SetFlags should be idempotent and set static
	//values on f.
	cli.FlagSetter

	//ParameterSetter for Command parameters.
	cli.ParameterSetter

	//Execute is where the Command should do its work.
	//A non-nil return value indicates the execution failed and that error will
	//be processed by a Commander.
	//Ctx is the Command's Context provided by the calling code.
	//In, out, and outErr are the standard in, out, and err that the Command should
	///use.
	Execute(ctx context.Context, in io.Reader, out, outErr io.Writer) error
}

Command defines the options for executing a command.

The methods of this interface (except SetParameters and Execute) may be called multiple times to obtain help and error output when needed. These methods should be idempotent.

type CommandStruct

type CommandStruct struct {
	//DescriptionValue is returned from Command's Description() method.
	DescriptionValue string

	//FlagSetter is used as the Command's implementation for SetFlags if not nil.
	cli.FlagSetter

	//ParameterSetter is used as the Command's implementation for ParameterSetter's
	//methods if not nil.
	cli.ParameterSetter

	//ExecuteValue is used as the Command's implementation if not nil.
	ExecuteValue func(context.Context, io.Reader, io.Writer, io.Writer) error
}

CommandStruct is a struct type implementation of Command where each field represents the value to delegate to in Command methods. Nil interface and func values are not used and the zero values are used for return values if not supplied.

func (*CommandStruct) Description

func (cs *CommandStruct) Description() string

Description returns cs.DescriptionValue.

func (*CommandStruct) Execute

func (cs *CommandStruct) Execute(ctx context.Context, in io.Reader, out, outErr io.Writer) error

Execute calls and returns the result from cs.ExecuteValue(ctx, out, outErr) if the field is not nil. Otherwise, it returns nil.

func (*CommandStruct) ParameterUsage

func (cs *CommandStruct) ParameterUsage() ([]*cli.Parameter, string)

ParameterUsage delegates to cs.ParameterSetter if the field is not nil. Otherwise, it returns nil and the empty string.

func (*CommandStruct) SetFlags

func (cs *CommandStruct) SetFlags(f *flag.FlagSet)

SetFlags delegates to cs.FlagSetter if the field is not nil.

func (*CommandStruct) SetParameters

func (cs *CommandStruct) SetParameters(params []string) error

SetParameters delegates to cs.ParameterSetter if the field is not nil. Otherwise it returns nil.

type Commander

type Commander struct {
	//The program name to execute. Used in help and error output.
	//This will usually be os.Args[0].
	Name string

	//Command is the Command to execute.
	Command
}

Commander provides options and methods for executing a Command.

Note that Commander is NOT safe for use with multiple goroutines.

func (*Commander) Execute

func (c *Commander) Execute(args []string) error

Execute is syntactic sugar for ExecuteContext() with context.Background(), args, os.Stdin, os.Stdout, and os.Stderr.

func (*Commander) ExecuteContext

func (c *Commander) ExecuteContext(ctx context.Context, args []string, in io.Reader, out, outErr io.Writer) error

ExecuteContext executes c.Command with the provided parameters.

Ctx is the Context passed unaltered to c.Command.Execute.

Args should be the program arguments excluding the program name - usually os.Args[1:]. They will be parsed using cli.ParseArgumentsInterspersed.

The parameters in, out, and outErr are passed unaltered to c.Command.Execute and should represent the standard input, output, and error files for the executing Command.

Err will be non-nil if parsing args failed - with type *ParsingCommandError or *ExecutingCommandError if the c.Command.Execute method returns an error.

If the returned error is of type *ParsingCommandError, then error and help output will be written to outErr. See the package documentation for more details on error and help output. If this is the error, then execution stops and c.Command.Execute is never called.

If the error is an *ExecutingCommandError then nothing is output by c.

type ExecutingCommandError

type ExecutingCommandError struct {
	Err error
}

ExecutingCommandError is an error wrapper denoting command execution failed.

func (*ExecutingCommandError) Error

func (e *ExecutingCommandError) Error() string

Err returns e.Err.Error().

type ParsingCommandError

type ParsingCommandError struct {
	Err error
}

ParsingCommandError is an error wrapper denoting command argument parsing failed.

func (*ParsingCommandError) Error

func (e *ParsingCommandError) Error() string

Error returns e.Err.Error().

Jump to

Keyboard shortcuts

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