gargle

package module
v0.0.0-...-429d80a Latest Latest
Warning

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

Go to latest
Published: Aug 9, 2018 License: Apache-2.0 Imports: 12 Imported by: 0

README

Gargle

GoDoc Reference Build Status

This is a work in progress and offers no compatibility guarantees.

Motivation

Gargle aims to provide a flexible command line parser while avoiding the complexity of deep integration.

What differentiates Gargle?

  • No special casing required for common flags and commands, such as --help.
  • Code-generated usage is more flexible, lighter weight, and often more readable than templates.
  • Minimal side-effects help separate declaration from execution.
  • Light-weight and isolated.

Examples

Adding Help

Any action can be written to write application usage. Following is an example which illustrates adding help using the default usage writer.

cmd := &Command{/*...*/}
cmd.AddFlags(gargle.NewHelpFlag(nil))

The value nil could be replaced by any Action to customize usage.

Negative Booleans

Some applications prefer to provide negated versions of boolean flags. This example shows how to create a flag which can be explicitly enabled or disabled via --enable-foo and --disable-foo.

var foo bool
cmd := &Command{/*...*/}
cmd.NewFlag("enable-foo", "...").BoolVar(&foo)
cmd.NewFlag("disable-foo", "...").NegatedBoolVar(&foo).Hide()
)
Environment Defaults

It's often convenient to accept environment variables in place of flags. This example shows how to wrap a value with an environment-backed default value.

func EnvDefault(v gargle.Value, key string) gargle.Value {
    if s, ok := os.LookupEnv(key); ok {
        return gargle.WithDefault(v, s)
    }
    return v
}
setting := "<none>"
Flag(Name: "setting", EnvDefault(gargle.StringVar(&setting), "APP_SETTING")

This sets value in order of precedence to:

  1. The flag --setting if provided.
  2. The environment variable APP_SETTING if provided.
  3. The value "<none>" if none of the above.

Why "Gargle"?

The Go ecosystem is rife with really bad puns. In short, GoArgParse -> GArg -> Gargle.

Alternatives

  • flag:
    • Fast, simple, and built in
    • Doesn't directly support sub-commands
    • Difficult to customize
  • Cobra:
    • Extremely customizable
    • Complex interface, provides a code generator
    • Integrates with Viper
    • Template-based usage formatting
  • Kingpin
    • Fluent-style interface
    • Template-based usage formatting

Documentation

Overview

Package gargle implements a library for command-line parsing.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsAggregate

func IsAggregate(v Value) bool

IsAggregate returns whether a value can be set multiple times.

func IsBoolean

func IsBoolean(v Value) bool

IsBoolean returns whether a value is of boolean type.

Types

type Action

type Action func(context *Command) error

Action is a function which is invoked during or after parsing. The passed context is actively parsed command, i.e. the last encountered during parsing.

func DefaultUsage

func DefaultUsage() Action

DefaultUsage returns the default usage writer as an action. This is usually attached to help flags and commands as a PreAction.

Example
var b bool
var i int
var s []string

root := &Command{Name: "root", Help: "A root command which does something."}
root.AddCommands(
	NewHelpCommand(nil),
	&Command{Name: "subcommand1", Help: "The first subcommand does some things too."},
	&Command{Name: "sub2", Help: "The second command has long explanatory text. Perhaps there is a complex edge case which is very important for a user to know."},
)
root.AddFlags(
	NewHelpFlag(nil),
	&Flag{Short: 'v', Help: "Show version information"},
	&Flag{Short: 'a', Help: "Short flag with no long form", Value: IntVar(&i)},
	&Flag{Name: "long-only", Help: "Long flag with no short form", Value: IntVar(&i)},
	&Flag{Name: "bool", Short: 'b', Help: "Boolean flag", Value: BoolVar(&b)},
	&Flag{Name: "hidden", Help: "A hidden flag", Hidden: true},
	&Flag{
		Name: "slice", Short: 's',
		Placeholder: "STR",
		Help:        "Aggregate value with custom placeholder",
		Value:       StringsVar(&s),
	},
)
root.Parse([]string{"help"})
Output:

Usage: root [<flags>] <command>

A root command which does something.

Commands:
  help         Show usage
  sub2         The second command has long explanatory text. Perhaps there is a
               complex edge case which is very important for a user to know.
  subcommand1  The first subcommand does some things too.

Options:
  -a VALUE               Short flag with no long form
  -b, --bool             Boolean flag
  -h, --help             Show usage
      --long-only VALUE  Long flag with no short form
  -s, --slice STR...     Aggregate value with custom placeholder
  -v                     Show version information

type AggregateValue

type AggregateValue interface {
	IsAggregate() bool
}

AggregateValue is an optional interface which may be implemented by aggregate types, such as slices and maps. This affects how values are displayed in help and allows positional arguments to consume multiple values.

type Arg

type Arg struct {
	// An optional name to display in help and errors.
	Name string

	// Text describing the argument. It may be a single line or an arbitrarily
	// long description. Usage writers may assume the first line can serve
	// independently as a short-form description.
	Help string

	// Required sets the argument to generate an error when absent.
	Required bool

	// PreAction is invoked after parsing, but before values are set. All pre-actions
	// are executed unconditionally in the order encountered during parsing.
	PreAction Action

	// Underlying value for the argument, set during parsing.
	Value Value
}

Arg represents a positional argument attached to a command.

func NewArg

func NewArg(name, help string) *Arg

NewArg creates a new positional argument.

func (*Arg) BoolVar

func (a *Arg) BoolVar(v *bool) *Arg

func (*Arg) DurationVar

func (a *Arg) DurationVar(v *time.Duration) *Arg

func (*Arg) Float64Var

func (a *Arg) Float64Var(v *float64) *Arg

func (*Arg) Int64Var

func (a *Arg) Int64Var(v *int64) *Arg

func (*Arg) IntVar

func (a *Arg) IntVar(v *int) *Arg

func (*Arg) IntsVar

func (a *Arg) IntsVar(v *[]int) *Arg

func (*Arg) NegatedBoolVar

func (a *Arg) NegatedBoolVar(v *bool) *Arg

func (*Arg) Require

func (a *Arg) Require() *Arg

Require sets an argument to generate an error when absent.

func (*Arg) RunPre

func (a *Arg) RunPre(action Action) *Arg

RunPre sets or replaces an argument's pre-action.

func (*Arg) StringVar

func (a *Arg) StringVar(v *string) *Arg

func (*Arg) StringsVar

func (a *Arg) StringsVar(v *[]string) *Arg

func (*Arg) Uint64Var

func (a *Arg) Uint64Var(v *uint64) *Arg

func (*Arg) UintVar

func (a *Arg) UintVar(v *uint) *Arg

func (*Arg) Var

func (a *Arg) Var(v Value) *Arg

Var sets an argument's Value.

type BooleanValue

type BooleanValue interface {
	IsBoolean() bool
}

BooleanValue is an optional interface which may be implemented by bool types.

Flags backed by boolean values are parsed differently from others. Bool flags are set to "true" if provided without an explicit value.

type Command

type Command struct {
	// Name of the command.
	Name string

	// Text describing the command. It may be a single line or an arbitrarily
	// long description. Usage writers may assume the first line can serve
	// independently as a short-form description.
	Help string

	// Hidden sets whether the command should be omitted from usage text.
	Hidden bool

	// PreAction is invoked after parsing, but before values are set. All pre-actions
	// are executed unconditionally in the order encountered during parsing.
	PreAction Action

	// Action invoked after parsing and argument validation. Only the active
	// context, i.e. the last command parsed, is invoked.
	Action Action

	// Client-defined labels for grouping and processing commands.
	Labels map[string]string
	// contains filtered or unexported fields
}

Command is a hierarchical structured argument. It can serve as an application entry point, a command group, or both. For exmple, in the command line "go test .", "go" is a root command and "test" is a subcommand of "go".

func NewCommand

func NewCommand(name, help string) *Command

NewCommand creates an empty command.

func NewHelpCommand

func NewHelpCommand(writeHelp Action) *Command

NewHelpCommand creates a standard help command, which prints help for a given subcommand. If no arguments are passed, it prints its parent's help. This should be added to each command group.

func (*Command) AddArgs

func (c *Command) AddArgs(args ...*Arg) *Command

AddArgs creates a new positional argument under a command.

func (*Command) AddCommands

func (c *Command) AddCommands(commands ...*Command)

AddCommands adds any number of child commands. It is an error to add the same child command to multiple parents, or to add a command to itself.

func (*Command) AddFlags

func (c *Command) AddFlags(flags ...*Flag) *Command

AddFlags creates a new flag under a command. Flags are inherited by subcommands unless overridden by a flag with the same name.

func (*Command) Args

func (c *Command) Args() []*Arg

Args returns a command's positional arguments, not including those of its parents.

func (*Command) Commands

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

Commands returns a command's immediate children.

func (*Command) Flags

func (c *Command) Flags() []*Flag

Flags returns a command's flags, not including those of its parents.

func (*Command) FullFlags

func (c *Command) FullFlags() []*Flag

FullFlags returns a command's flags along with those of its parents. Flags are ordered parent to child.

func (*Command) FullName

func (c *Command) FullName() string

FullName returns a command's fully qualified name.

func (*Command) NewArg

func (c *Command) NewArg(name, help string) *Arg

NewArg creates a new positional argument within a command.

func (*Command) NewCommand

func (c *Command) NewCommand(name, help string) *Command

NewCommand creates a new subcommand.

func (*Command) NewFlag

func (c *Command) NewFlag(name, help string) *Flag

NewFlag creates a new flag within a command. The name must take the form "[long][,short]", where short is a single character.

func (*Command) Parent

func (c *Command) Parent() *Command

Parent returns a command's parent command, if any.

func (*Command) Parse

func (c *Command) Parse(args []string) error

Parse reads arguments and executes a command or one of its subcommands.

func (*Command) Run

func (c *Command) Run(action Action) *Command

Run sets or replaces a command's action.

func (*Command) RunPre

func (c *Command) RunPre(action Action) *Command

RunPre sets or replaces a command's pre-action.

type Flag

type Flag struct {
	// Name is an optional unprefixed long form of the flag.
	// For example, "help" would match the argument "--help".
	Name string

	// Text describing the command. It may be a single line or an arbitrarily
	// long description. Usage writers may assume the first line can serve
	// independently as a short-form description.
	Help string

	// Placeholder is an optional override for the name of a flag's value.
	Placeholder string

	// Short is an optional single-character short form for the flag.
	// For example, 'h' would match the argument "-h".
	Short rune

	// Hidden sets whether the flag should be omitted from usage text.
	Hidden bool

	// Required sets the flag to generate an error when absent.
	Required bool

	// PreAction is invoked after parsing, but before values are set. All pre-actions
	// are executed unconditionally in the order encountered during parsing.
	PreAction Action

	// Underlying value for the flag, set during parsing.
	Value Value
}

Flag is a single named/value argument pair

func NewFlag

func NewFlag(name, help string) *Flag

NewFlag creates a new flag given a composite name and help string. The name must take the form "[long][,short]", where short is a single character.

Examples:

"foo,f": --foo, -f
"long-only": --long (long-form only)
",s": -s (short-form only)

func NewHelpFlag

func NewHelpFlag(writeHelp Action) *Flag

NewHelpFlag creates a standard help flag which invokes the an action when parsed. This flag should be attached to the root command.

func (*Flag) BoolVar

func (f *Flag) BoolVar(v *bool) *Flag

func (*Flag) DurationVar

func (f *Flag) DurationVar(v *time.Duration) *Flag

func (*Flag) Float64Var

func (f *Flag) Float64Var(v *float64) *Flag

func (*Flag) Hide

func (f *Flag) Hide() *Flag

Hide removes a flag from display in usage text.

func (*Flag) Int64Var

func (f *Flag) Int64Var(v *int64) *Flag

func (*Flag) IntVar

func (f *Flag) IntVar(v *int) *Flag

func (*Flag) IntsVar

func (f *Flag) IntsVar(v *[]int) *Flag

func (*Flag) NegatedBoolVar

func (f *Flag) NegatedBoolVar(v *bool) *Flag

func (*Flag) Require

func (f *Flag) Require() *Flag

Require sets a flag to generate an error when absent.

func (*Flag) RunPre

func (f *Flag) RunPre(action Action) *Flag

RunPre sets or replaces a flag's pre-action.

func (*Flag) StringVar

func (f *Flag) StringVar(v *string) *Flag

func (*Flag) StringsVar

func (f *Flag) StringsVar(v *[]string) *Flag

func (*Flag) Uint64Var

func (f *Flag) Uint64Var(v *uint64) *Flag

func (*Flag) UintVar

func (f *Flag) UintVar(v *uint) *Flag

func (*Flag) ValueName

func (f *Flag) ValueName(s string) *Flag

ValueName sets a flag's value placeholder.

func (*Flag) Var

func (f *Flag) Var(v Value) *Flag

Var sets a flag's Value.

type UsageWriter

type UsageWriter struct {
	// Indent is an indentation prefix for subsections.
	Indent string

	// Divider is a string to print between columns.
	Divider string

	// MaxFirstColumn is the maximum width of the left column in split sections.
	MaxFirstColumn int

	// MaxLineWidth overrides the maximum width of each line of text, defaults
	// to terminal width in TTY or 80 columns otherwise.
	MaxLineWidth int

	// Writer overrides the default writer, default os.Stdout.
	Writer io.Writer
}

UsageWriter is a configurable usage formatter which can be used as a safe default for most applications.

func (*UsageWriter) Format

func (u *UsageWriter) Format(command *Command) error

Format writes a given command's usage using the writer's configuration.

type Value

type Value interface {
	String() string
	Set(s string) error
}

Value is an interface implemented by all value types.

func BoolVar

func BoolVar(v *bool) Value

BoolVar wraps a single boolean value.

func DurationVar

func DurationVar(v *time.Duration) Value

DurationVar wraps a time duration, including units.

func Float64Var

func Float64Var(v *float64) Value

Float64Var wraps a double-precision floating point.

func Int64Var

func Int64Var(v *int64) Value

Int64Var wraps a 64-bit signed integer.

func IntVar

func IntVar(v *int) Value

IntVar wraps a signed integer with machine-dependent bit width.

func IntsVar

func IntsVar(v *[]int) Value

IntsVar wraps a slice of integers.

func NegatedBoolVar

func NegatedBoolVar(v *bool) Value

NegatedBoolVar wraps a single boolean value. It sets v to the opposite of a parsed string. It's most useful when paired with a positive counterpart.

Example
var value bool
NegatedBoolVar(&value).Set("false")
fmt.Println(value)
Output:

true

func StringVar

func StringVar(v *string) Value

StringVar wraps a string.

func StringsVar

func StringsVar(v *[]string) Value

StringsVar wraps a slice of strings.

func Uint64Var

func Uint64Var(v *uint64) Value

Uint64Var wraps a 64-bit unsigned integer.

func UintVar

func UintVar(v *uint) Value

UintVar wraps an unsigned integer with machine-dependent bit width.

func WithDefault

func WithDefault(v Value, s ...string) Value

WithDefault wraps a value with string default value(s) which will be applied after parsing if (and only if) a value is left unset.

Jump to

Keyboard shortcuts

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