commandline

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Oct 26, 2020 License: MIT Imports: 6 Imported by: 0

README

commandline

A command oriented command line parser.

Currently uses JSON by default to allow string to value conversion from arguments.

Description

Commands can be defined in the central Parser type and handler functions of those commands are invoked when Command is specified on command line, which can optionally abort the parse process. Command can have optional or required Param definitions which can write directly to Go values during parsing using JSON formatting and can also be analyzed in a Command handler function. Commands can have Commands of their own allowing for a Command hierarchy.

Example:


// Some variables that will receive values.
var (
	verbose     bool
	projectname string
	projectdir  string
)

// cmdGlobal gets invoked for "Global params" unnamed function.
func cmdGlobal(params *Params) error {
	verbose = params.Parsed("verbose")
	return nil
}

// cmdCreate gets invoked for "Create project" command.
func cmdCreate(params *Params) error {
	CreateProject(projectname, projectdir)
	return nil
}

// Create new parser. 
parser := New()

// Parser allows for a single unnamed command in root command definitions to
// allow the command line not to start with a command but parameters instead.
// If it is registered it must be the root command of all commands.
//
// Register a special "global flags" handler command that is automatically
// invoken if any of it's flags is specified by command line arguments and
// skipped if no "global flags" is given in arguments and the command line
// starts with a command.
cmd, err := parser.AddCommand("", "Global params", cmdGlobal)

// Register an optional "verbose" param on "global flags" command.
// It will not write to any Go value as pointer to one is nil.
cmd.AddParam("verbose", "v", "Be more verbose.", false, nil)

// Register a sub command for the "global flags" command so it can be invoken
// via arguments regardless if "global flags" executed.
cmd, err := cmd.AddCommand("create" "Create a project", cmdCreate)

// Add a prefixed parameter to "Create project" command that is required and
// converts an argument following the param to registered Go value projectname.
cmd.AddParam("name", "n", "Project name", true, &projectname)

// Add an optional raw param that isn't prefixed but is instead treated as a
// param value itself.
cmd.AddRawParam("directory", "Specify project directory", false, &projectdir)

// Parse command line.
if err := parser.Parse(os.Args[1:]); err != nil {
	log.Fatal(err)
}

Valid command line for this example would be: -v create --name myproject /home/me/myproject

Status

No API changes except additions planned.

What's left:

  • Specialcasing for JSON values passed via command line. Especially compound types and quoting stuffs.
  • Maybe abstract value parsing with codecs.

License

MIT

See included LICENSE file.

Documentation

Overview

Package commandline implements a command line parser.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoArgs is returned by Parse if no arguments were specified on
	// command line and there are defined Commands or Params.
	ErrNoArgs = errors.New("commandline: no arguments")
	// ErrInvalidName is returned by Add* methods when an invalid Command or
	// Param long or short name is specified.
	ErrInvalidName = errors.New("commandline: invalid name")
	// ErrInvalidValue is returned by Add* methods or during parsing if an
	// invalid parameter is given for a Param value, i.e. not a valid pointer
	// to a Go value.
	ErrInvalidValue = errors.New("commandline: invalid value")
)

Functions

This section is empty.

Types

type Command

type Command struct {
	Params   // Params are this Command's Params.
	Commands // Commands are this Command's Commands.
	// contains filtered or unexported fields
}

Command is a command definition. A Command can contain sub-Commands and propagate Parser args further down the Commands chain. It can have zero or more defined Param instances in its' Params.

type CommandFunc

type CommandFunc = func(*Params) error

CommandFunc is a prototype of a function that handles the event of a Command being parsed from command line arguments.

Parser parses Command's Params and pauses parsing when it finds next Command in arguments or it exhausts arguments, invokes parsed Command's CommandFunc carrying parsed Params then either continues parsing if the handler returns nil or stops and returns the error that the handler returned back to the Parse method whose caller is responsible for interpreting that error.

If the invoked Command has any raw Params registered, parsing will not continue after CommandFunc invocation.

type Commands

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

Commands holds a set of Commands with a unique name.

func (*Commands) AddCommand

func (c *Commands) AddCommand(name, help string, f CommandFunc) (*Command, error)

AddCommand registers a new Command under specified name and help text that invokes f when parsed from arguments if it is not nil. Name is the only required parameter.

If Commands is the root set in a Parser it can register a single Command with an empty name to be an unnamed container in a global params pattern.

If a registration error occurs it is returned with a nil *Command.

func (*Commands) GetCommand

func (c *Commands) GetCommand(name string) (cmd *Command, ok bool)

GetCommand returns a *Command by name if found and truth if found.

type Param

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

Param defines a Command parameter contained in a Params.

func (*Param) Value

func (p *Param) Value() interface{}

Value returns the Param value.

type Params

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

A Params defines a set of Command Params unique by long name.

func (*Params) AddParam

func (p *Params) AddParam(long, short, help string, required bool, value interface{}) error

AddParam registers a new Param in these Params.

Long param name is required, short is optional and can be empty, as is help.

If required is specified value must be a pointer to a supported Go value which will be updated to the value of the Param value parsed from args. If a required Param or its' value is not found in args during this Params parsing an error is returned.

If Param is not marked as required, specifying a pointer to a supported Go value via value parameter is optional: If nil, a value for the Param will not be parsed from args. If a pointer to a supported Go value the parser will look for an value following the param and return an error if not found.

If an error occurs Param is not registered.

func (*Params) AddRawParam

func (p *Params) AddRawParam(name, help string, required bool, value interface{}) error

AddRawParam registers a raw Param under specified name which must be unique in Params. Raw params can only be defined after prefixed params, i.e. calls to AddParam after AddRawParam will error.

Parsed arguments are applied to raw Params in order as they are defined. If Param value is a pointer to a valid Go value argument will be converted to that Go value.

A single non-required raw Param is allowed and it must be the last one.

If an error occurs it is returned and the Param is not registered.

func (*Params) Parsed

func (p *Params) Parsed(name string) bool

Parsed returns if the param under specified name was parsed. If the Param under specified name is not registered, returns false.

func (*Params) RawArgs

func (p *Params) RawArgs() []string

RawArgs returnes arguments of raw Params in order as passed on command line.

type Parser

type Parser struct {

	// Commands is the root command set.
	//
	// Root Commands as an exception allows a single Command
	// with an empty name that serves as "global flag" container.
	Commands
	// contains filtered or unexported fields
}

Parser is a command line parser. Its' Parse method is to be invoked with a slice of command line arguments passed to program. For example:

err := Parser.Parse(os.Args[1:])

It is command oriented, meaning that one or more Command instances can be defined in Parser's Commands which when parsed from command line arguments invoke CommandFuncs registered for those Command instances. Command can have its' own Commands so a Command hierarchy can be defined.

Root Commands, as an exception, allow for one Command with an empty name to be defined. This is to allow that program args need not start with a Command and to allow Params to be passed first which can act as "global". e.g. "--verbose list users"

Command can have one or more Param instances defined in its' Params which can have names, help text, be required or optional and have an optional pointer to a Go value which is written from a value following Param in command line arguments.

If a pointer to a Go value is registered with a Param, the Param will require an argument following it that the parser will try to convert to the Go value registered with Param. Otherwise the Param will act as a simple flag which can be checked if parsed in the handler by checking the result of handler's Params.Parsed("long param name").

Parser supports prefixed and raw params which can be combined on a Command with a caveat that the Command that has one or more raw params registered cannot have sub-Commands because of ambiguities in parsing command names and raw parameters as well as the fact that one last raw param can be optional.

Prefixed params are explicitly addressed on a command line and can have short and long forms. They can be marked optional or required and be registered in any order, but before any raw params.

Short Param names have the "-" prefix, can be one character long and can be combined together following the short form prefix if none of the combined Params require a Param Value. They are optional per Param.

Long Param names have the "--" prefix and cannot be combined.

Raw params are not addressed but are instead matched against registered raw Params in order of registration as they appear on command line, respectively.

Prefixed and raw params can both be registered for a Command but raw params must be registered last and specified after prefixed Params on the command line. e.g. "rmdir -v /home/me/stuff" where "rmdir" is a command, "-v" is a prefixed param and "/home/me/stuff" is a raw parameter.

If Params are defined as optional they do not cause a parse error if not parsed from program args and return a parse error if defined as required and not parsed from command line.

Command can have a CommandFunc registered optionaly so that a Command can serve solely as sub-Command selector. For more details see CommandFunc.

If no Params were defined on a Command all command line arguments following the command invocation will be passed to Command handler via Params.RawArgs.

If no params were defined on a Command and the command has no CommandFunc registered an error is returned.

func New

func New() *Parser

New returns a new instance of *Parser.

func (*Parser) Parse

func (p *Parser) Parse(args []string) error

Parse parses specified args, usually invoked as "Parse(os.Args[1:])". If a parse error occurs or an invoked Command handler returns an error it is returned. Returns ErrNoArgs if args are empty and there are defined Commands or Params.

func (Parser) Print

func (p Parser) Print() string

Print prints the Parser as currently configured. Returns output suitable for terminal display.

Jump to

Keyboard shortcuts

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