clap

package module
v0.0.0-...-250c7b9 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2022 License: MIT Imports: 16 Imported by: 0

README

Tests (dev) Tests

Command-Line Argument Parser (In Development)

clap is a command-line argument parser for Go.

Inspired by the standard flag package and the clap Rust crate.

Motivation

I loved the idea behind the flag package, but I always found myself wanting more from this package (and any packages that extended it):

  • Ability to use this same API for any data-type;
  • Ability to use this same logic for 'different' types of input;
  • Ability to access the internals of the arguments for complex use-cases;

This package aims to solve this issue by providing a unified API for dealing with 3 (4, with 1 unstable) different types of Arg - each of which is bound to some Go variable and can be added to a Parser to allow it to be parsed from user input.

The general constructor API is pretty much identical to the flag package, but with Type instantiations:

var (
	myValue string 
	myFlag = clap.NewFlag[string](&myValue, "my-flag-value", parse.String{})
	//myKey = clap.NewKeyValue[string](&myValue, "my-key-value", parse.String{})
	//myPos = clap.NewPosition[string](&myValue, 1, parse.String{})
)

Note: the packages github.com/runaek/clap/pkg/{flag,keyvalue,pos} provide a number of convenient constructors for some common-types which does not require the generic type instantiation or the parse.Parser[T] being specified.

Features

  • Standard API for command-line arguments;
  • Standard parse.Parse[T] interface for extending arguments to custom data-types;
  • Supports dynamic generation of Arg(s) via struct-tags;
  • Supports a number if different command-line inputs types:
    • <key>=<vallue style arguments: KeyValueArg[T];
    • --<flag>=<value>, -<f>=<value> style arguments: FlagArg[T];
    • <arg1> <arg2> <argRemaining ...> positional style arguments: PositionalArg[T]
    • <some data> | my_program pipe style arguments: PipeArg[T] (unstable);

Usage

go get -u github.com/runaek/clap (requires go1.18+)

// examples/readme/main.go
package main

import (
	"fmt"
	"github.com/runaek/clap"
	"github.com/runaek/clap/pkg/flag"
	"github.com/runaek/clap/pkg/pos"
	"github.com/runaek/clap/pkg/keyvalue"
	"strings"
)

var (
	id     string
	idFlag = flag.String(&id, "id", clap.WithAlias("i"), clap.WithDefault("default-id"))

	words    []string
	wordsArg = pos.Strings(&words, 1, clap.WithAlias("words"))

	num    int
	numArg = keyvalue.Int(&num, "number", clap.AsRequired())

	parser = clap.Must("my-program", idFlag, numArg, wordsArg)
)

func main() {
	parser.Parse()
	parser.Ok()

	fmt.Printf("ID:     %s", id)
	fmt.Printf("Number: %d", num)
	fmt.Printf("Words:  %s", strings.Join(words, ", "))
	// do stuff with args 
}   

Types

The package provides a number of types which can be used to configure a Go program that relies on command-line input.

See github.com/runaek/cliche for more advanced usage.

Parser

The Parser (not to be confused with the Parser[T] interface from the github.com/runaek/clap/pkg/parse package) is the handler/container for a number of command-line arguments. You can add arguments to a parser, validate they are correct, and then you can parse command-line input with it.

The API and behaviour is very similar flag.FlagSet in idea, but a direct conversion is likely not possible.

Arguments

Arguments are defined by the Arg interface - there are 4 distinct implementations. The main difference between all the implementations is where the source of their string-input comes from.

There is also the generic TypedArg[T] interface, which is satisfied by all Arg, but less convenient to work with when we want to store them in a Parser, but if you know the type, you will always be able to extract the TypedArg[T].

Package github.com/runaek/clap/parse provides a generic interface which is used to parse user-supplied string (and default values) into concrete types:

type Parser[T any] interface {
	Parse(...string) (T, error)
}

At runtime, the Parser[T] will be provided all the input that maps to the Arg and the resulting type (error withstanding) will then be assigned to the underlying variable.

A number of implementations for built-in (and some clap-specific) types for this Parser are also contained within the package.

Flag: FlagArg[T]

Flag arguments are your traditional flag arguments as you would find in the flag package or any other programming language.

KeyValue: KeyValueArg[T]

Key-value arguments are the same as flag arguments, except they do not expect to be prefixed with a -- or -.

Note: key-value args are treated essentially the same as flags, however, it would always expect a value (i.e. not ideal for bool data types).

Positional: PositionalArg[T]

Positional arguments are the anonymous arguments supplied to the program.

Note: positional arguments can only be required if the argument preceding them is also required, and variable numbers of positional arguments cannot be required.

Pipe: PipeArg[T]

Note: this is still under development and the API/implementation may change for this type.

Pipe arguments are mainly a convenience - the intended use was to allow them to 'replace' other argument types. The way the implementation works is each PipeArg has a Piper which is responsible for consuming a reader (provided by the pipe) and parsing string-input. This outputted string input is passed down into the underlying parse.Parser[T] just like any other argument.

Currently, the package provides a SeparatedValuePiper for piping some string-separated data, more implementations will come in time, but this can easily be implemented by users as they wish.

Note: There can only ever be one pipe active within a Parser at a time.

Derived Arguments

Arguments can dynamically be generated through struct-tags. These tags should specify a deriver which will be mapped to some type and if supported, the type will be used by the argument. The deriver referenced should be 'registered' with the same value using RegisterKeyValueDeriver, RegisterPositionalDeriver and RegisterFlagDeriver.

Struct-tags can be supplied in the following formats:

> `cli:"#<index>|<human_name>:<deriver>"` for a positional argument
> `cli:"#<start>...|<human_name>:<deriver>"` for positional arguments
> `cli:"-<flag_name>|<flag_shorthand>:<deriver>"` for a flag argument
> `cli:"@<key_name>|<key_shorthand>:<deriver>"` for a key-value argument

A ! can be prefixed to a tag to mark the input as Required.

Examples

Arguments derived from struct-tags

// examples/derive/main.go 
package main

import (
	"fmt"
	"github.com/runaek/clap"
	_ "github.com/runaek/clap/pkg/derive"
	"github.com/runaek/clap/pkg/parse"
)

type MyProgram struct {
	Name       string `cli:"!#1:string"`
	NameUsage  string
	Roles      []string `cli:"#2...:strings"`
	RolesUsage string

	Level        int `cli:"-level:int"`
	LevelUsage   string
	LevelDefault string

	Counter      parse.C `cli:"-counter:counter"`
	CounterUsage string

	Account        string `cli:"!@account:string"`
	AccountUsage   string
	AccountDefault string
}

var (
	prog = MyProgram{
		NameUsage:      "Enter your name!",
		RolesUsage:     "Enter a number of random words (roles).",
		LevelUsage:     "Enter a level (number).",
		LevelDefault:   "73",
		CounterUsage:   "A counter for the number of times the flag is supplied.",
		AccountUsage:   "A key-value for the 'account' to be used",
		AccountDefault: "[default]",
	}

	parser = clap.Must("derived_demo", &prog)
)

func main() {
	parser.Parse()
	parser.Ok()

	fmt.Printf("MyProgram Arguments:\n%+v\n", prog)
}

Custom Deriver

Custom Parser

Documentation

Index

Constants

View Source
const (
	ContinueOnError = ErrorHandling(flag.ContinueOnError)
	ExitOnError     = ErrorHandling(flag.ExitOnError)
	PanicOnError    = ErrorHandling(flag.PanicOnError)
)
View Source
const PipeName = "MAIN"

Variables

View Source
var (
	System = Must("default")
)

Functions

func Add

func Add(args ...Arg) error

func Err

func Err() error

func GetLogger

func GetLogger() *zap.Logger

GetLogger returns the dev logger for the clap package.

func NameOf

func NameOf(id Identifier) string

NameOf is a helper function for getting the name of an Arg from an Identifier.

func Ok

func Ok()

func Parse

func Parse(args ...string) error

func RawFlags

func RawFlags() map[string][]string

func RawKeyValues

func RawKeyValues() map[string][]string

func RawPositions

func RawPositions() []string

func ReferenceTo

func ReferenceTo[T any](arg Arg) (*T, error)

ReferenceTo is a helper function for retrieving a reference to the value for an Arg.

func RegisterFlagDeriver

func RegisterFlagDeriver(name string, d FlagDeriver)

RegisterFlagDeriver adds a FlagDeriver to the program so that it can be detected and used within struct-tags.

func RegisterKeyValueDeriver

func RegisterKeyValueDeriver(name string, d KeyValueDeriver)

RegisterKeyValueDeriver adds a KeyValueDeriver to the program so that it can be detected and used within struct-tags.

func RegisterPositionalDeriver

func RegisterPositionalDeriver(name string, d PositionalDeriver)

RegisterPositionalDeriver adds a PositionalDeriver to the program so that it can be detected and used within struct-tags.

func SetDescription

func SetDescription(description string)

func SetLogger

func SetLogger(l *zap.Logger)

SetLogger sets the dev logger for the clap package.

func SetName

func SetName(name string)

func UpdateMetadata

func UpdateMetadata(u Updater, options ...Option)

UpdateMetadata is the public helper function to update the Metadata of some Arg.

func UpdateValue

func UpdateValue(u Updater, input ...string) error

UpdateValue is a public helper function to update the value of some Arg.

func Using

func Using(elements ...any) error

func Valid

func Valid() error

func ValidateDefaultValue

func ValidateDefaultValue[T any](arg TypedArg[T]) (T, error)

ValidateDefaultValue is a helper function for retrieving and attempting to parse the actual typed default value of an Arg.

func ValueOf

func ValueOf[T any](arg Arg) (T, error)

ValueOf is a helper function for retrieving the value of an Arg.

Types

type Arg

type Arg interface {
	Identifier

	Updater

	// Name returns the key/identifier of the Arg, this should be unique for each Type.
	Name() string

	// Type indicates the type of command-line argument the Arg is, returns one of:
	//
	// 	> FlagType;
	//
	//	> KeyValueType;
	//
	//	> PositionType;
	//
	//	> PipeType;
	Type() Type

	// Shorthand is the single character alias/identifier for the Arg, if applicable
	//
	// Can be updated via the WithAlias Option
	Shorthand() string

	// Usage returns a usage of the Arg for the user
	//
	// Can be updated via the WithUsage Option
	Usage() string

	// Default returns the default string value for the Arg
	//
	// Can be updated via the WithDefault Option, if applicable
	Default() string

	// IsRequired returns true if the Arg is required
	//
	// Can be updated via the AsRequired, AsOptional Option(s)
	IsRequired() bool

	// IsParsed returns true if the Arg has been parsed
	IsParsed() bool

	// IsSupplied returns true if the Arg was supplied by the user
	IsSupplied() bool

	// IsRepeatable returns true if the Arg can be supplied multiple times
	IsRepeatable() bool
}

Arg is the shared behaviour of all command-line input types (FlagType, KeyValueType and PositionType). It essentially exposes an API similar to the behaviour seen in the standard 'flags' package, extending support to key-value and positional arguments.

Metadata is attached to each Arg giving each arg some mutable properties which can be managed via Option(s).

Each Arg has its own go-argumentVariable which it is responsible for updating:

 import (
		. "github.com/runaek/clap"
		"github.com/runaek/clap/pkg/parse"
	)

	var (
		strVal string
		numVal int
		myArg = NewKeyValue[string](&strVal, "arg1", parse.String, <options>...) // arg1=Test123 => strVal=Test123
		numFlag = NewFlag[int](&numVal, "amount", parse.Int, <options>...)       // --amount=123 => numVal=123

		parser = clap.New("program-Id").
				Add(myArg, numFlag).
				OK()
	)

	...

	func main() {
		parser.Parse()
		parser.OK()

		... // do stuff with 'strVal' and 'numVal'
	}

func Derive

func Derive(source any) ([]Arg, error)

Derive attempts to construct a number of Arg dynamically from some struct-tags.

The tags are applied on the fields to be bound to the Arg (i.e. at runtime, the Field will hold the value of the Arg). There are 4 formats for each of the types and all can be prefixed with a '!' which will mark the Arg as required:

1. KeyValueArg: `cli:"@<name>|<alias>:<deriver>"

2. FlagArg: `cli:"-<name>|<alias>:<deriver>"

3. PositionalArg: `cli:"#<index>:<deriver>"

4. PositionalArg(s): `cli:"#<index>...:<deriver>"

Where the 'deriver' is the name assigned to the deriver when it was registered (using one of RegisterKeyValueDeriver, RegisterFlagDeriver or RegisterPositionalDeriver).

Usage strings can be supplied by creating a string field in the struct called <Name>Usage, the same can be done for a default value (i.e. <Name>Default). At runtime, the values held by the variable will be used for the respective usage/default.

Package `github.com/runaek/clap/pkg/derivers` provides support to a number of the built-in Go types. The program `github.com/runaek/clap/cmd/generate_derivers` is a codegen tool for helping generate FlagDeriver, KeyValueDeriver and PositionalDeriver implementations using a specified parse.Parse[T].

type Args struct {
	// a "name" or "N" KeyValueArg
	Name string `cli:"!@name|N:string"`

	// usage/description for the KeyValueArg
	NameUsage string

	// default value for the KeyValueArg
	NameDefault string

	// a variable number of string args, starting from the first index
	Values []string `cli:"#1...:string"`

	// usage/description for the positional args
	ValuesUsage string
}

...

var (
	args = Args{
		NameUsage:   "Supply your name.",
		NameDefault: "John",
		ValuesUsage: "A number of values to be supplied."
	}

	parser = clap.Must("demo", &args)
)

func main() {
	parser.Parse()
	parser.Ok()

	// use args
}

NOTE: Fields should be defined in the same order you would expect to add them to a Parser manually (i.e. Field referring to the 1st positional argument must come before the Field referring to the 2nd positional argument).

func DeriveAll

func DeriveAll(sources ...any) ([]Arg, error)

DeriveAll is a convenient wrapper around Derive.

func Generalize

func Generalize[T any](typed ...TypedArg[T]) []Arg

Generalize is a helper function for converting some TypedArg[T] -> Arg.

type Error

type Error string

Error is a simple indicator for some error that occurs.

The value of the error should indicate the 'cause' of the problem and context should be provided by the returning process.

const (
	ErrUnidentified Error = "unidentified argument"
	ErrMissing      Error = "argument is missing"
	ErrDuplicate    Error = "identifier already exists"
	ErrInvalidIndex Error = "invalid positional index"
	ErrPipeExists   Error = "pipe already exists"
	ErrUnknownType  Error = "unrecognised argument type"
	ErrInvalid      Error = "invalid argument syntax"
	ErrHelp         Error = "help requested"
)
const (
	ErrDeriverNotFound Error = "deriver not found"
)
const (
	ErrInvalidType Error = "invalid type"
)

func (Error) Error

func (err Error) Error() string

func (Error) Is

func (err Error) Is(target error) bool

type ErrorHandling

type ErrorHandling int

type FileInfo

type FileInfo = os.FileInfo

type FileReader

type FileReader interface {
	io.Reader
	Stat() (os.FileInfo, error)
	Fd() uintptr
}

FileReader represents some time of file-like object that would be used as an input we can read from.

Usually, in this package, values of this type will be set to os.Stdin by default

type FileWriter

type FileWriter interface {
	io.Writer
	Stat() (os.FileInfo, error)
	Fd() uintptr
}

FileWriter represents some type of file-like object that would be used as an output we can write to.

Usually, in this package, values of this type will be set to os.Stdout by default.

type Flag

type Flag string

Flag is an Identifier for some FlagArg.

type FlagArg

type FlagArg[T any] struct {
	Key string
	// contains filtered or unexported fields
}

A FlagArg argument of some type T.

func FlagUsingVariable

func FlagUsingVariable[T any](name string, v Variable[T], opts ...Option) *FlagArg[T]

FlagUsingVariable is a constructor for a FlagArg using a Id and some Variable.

func FlagsUsingVariable

func FlagsUsingVariable[T any](name string, v Variable[[]T], opts ...Option) *FlagArg[[]T]

FlagsUsingVariable is a constructor for a repeatable FlagArg using a Id and some Variable.

func Help

func Help(helpRequested *bool, desc string) *FlagArg[bool]

Help is a constructor for some *FlagArg[bool] (identified by '--help'/'-h') type.

func NewFlag

func NewFlag[T any](val *T, name string, parser parse.Parser[T], opts ...Option) *FlagArg[T]

NewFlag is a constructor for a new *FlagArg[T].

func NewFlagP

func NewFlagP[T any](val *T, name string, shorthand string, parser parse.Parser[T], opts ...Option) *FlagArg[T]

NewFlagP is a constructor for some new *FlagArg[T] with a shorthand.

func NewFlags

func NewFlags[T any](val *[]T, name string, parser parse.Parser[T], options ...Option) *FlagArg[[]T]

NewFlags is a constructor for a repeatable *FlagArg[[]T].

func NewFlagsP

func NewFlagsP[T any](val *[]T, name string, shorthand string, parser parse.Parser[T], options ...Option) *FlagArg[[]T]

NewFlagsP is a constructor for a repeatable *FlagArg[[]T] with a shorthand.

func (*FlagArg[T]) Default

func (f *FlagArg[T]) Default() string

func (*FlagArg[T]) HasDefault

func (f *FlagArg[T]) HasDefault() bool

func (*FlagArg[T]) IsIndicator

func (f *FlagArg[T]) IsIndicator() bool

func (*FlagArg[T]) IsParsed

func (f *FlagArg[T]) IsParsed() bool

func (*FlagArg[T]) IsRepeatable

func (f *FlagArg[T]) IsRepeatable() bool

func (*FlagArg[T]) IsRequired

func (f *FlagArg[T]) IsRequired() bool

func (*FlagArg[T]) IsSupplied

func (f *FlagArg[T]) IsSupplied() bool

func (*FlagArg[T]) Name

func (f *FlagArg[T]) Name() string

func (*FlagArg[T]) Shorthand

func (f *FlagArg[T]) Shorthand() string

func (*FlagArg[T]) Type

func (f *FlagArg[T]) Type() Type

func (*FlagArg[T]) Usage

func (f *FlagArg[T]) Usage() string

func (*FlagArg[T]) ValueType

func (f *FlagArg[T]) ValueType() string

func (*FlagArg[T]) Variable

func (f *FlagArg[T]) Variable() Variable[T]

type FlagDeriver

type FlagDeriver interface {
	DeriveFlag(v any, name string, opts ...Option) (IFlag, error)
}

A FlagDeriver is responsible for constructing a FlagArg dynamically.

type IFlag

type IFlag interface {
	Arg

	// IsIndicator returns true if the FlagArg does not require a value (e.g. a bool or C)
	IsIndicator() bool

	// HasDefault returns true if the flag has a defined default string value
	HasDefault() bool
	// contains filtered or unexported methods
}

IFlag is the interface satisfied by a FlagArg.

type IKeyValue

type IKeyValue interface {
	Arg

	// HasDefault returns true if the Arg has a defined default string value
	HasDefault() bool
	// contains filtered or unexported methods
}

IKeyValue is the interface satisfied by a KeyValueArg.

type IPipe

type IPipe interface {
	Arg

	// PipeInput returns the FileReader wrapping the underlying input for the pipe - this is usually os.input
	PipeInput() FileReader

	// PipeDecode decodes the contents of the pipe into string arguments to be parsed later
	PipeDecode(io.Reader) ([]string, error)
	// contains filtered or unexported methods
}

IPipe is the interface satisfied by a PipeArg.

type IPositional

type IPositional interface {
	Arg

	// Index returns the index (position) of the PositionalArg (or the starting index of the remaining args if
	// ArgRemaining is true)
	Index() int
	// contains filtered or unexported methods
}

IPositional is the interface satisfied by a PositionalArg.

type Identifier

type Identifier interface {
	// contains filtered or unexported methods
}

An Identifier represents something we can use to identify an Arg.

type Key

type Key string

A Key is an Identifier for some KeyValueArg.

type KeyValueArg

type KeyValueArg[T any] struct {
	Key string
	// contains filtered or unexported fields
}

A KeyValueArg represents a key=value argument where the key is a string and the value is a string representation for some type T.

Should be created by the functions: NewKeyValue, NewKeyValues, KeyValueUsingVariable and KeyValuesUsingVariable.

func KeyValueUsingVariable

func KeyValueUsingVariable[T any](name string, v Variable[T], opts ...Option) *KeyValueArg[T]

KeyValueUsingVariable allows a KeyValueArg to be constructed using a Variable.

func KeyValuesUsingVariable

func KeyValuesUsingVariable[T any](name string, v Variable[[]T], opts ...Option) *KeyValueArg[[]T]

KeyValuesUsingVariable allows a repeatable KeyValueArg to be constructed using Variable.

func NewKeyValue

func NewKeyValue[T any](variable *T, name string, p parse.Parser[T], opts ...Option) *KeyValueArg[T]

NewKeyValue is a constructor for a key-value argument from the command-line.

func NewKeyValues

func NewKeyValues[T any](variables *[]T, name string, p parse.Parser[T], opts ...Option) *KeyValueArg[[]T]

NewKeyValues is a constructor for a repeatable key-valued arguments from the command-line.

Automatically converts the Func[T] into a Func[[]T] via parse.Slice - use KeyValuesUsingVariable to be able to change this behaviour as required.

func (*KeyValueArg[T]) Default

func (k *KeyValueArg[T]) Default() string

func (*KeyValueArg[T]) HasDefault

func (k *KeyValueArg[T]) HasDefault() bool

func (*KeyValueArg[T]) IsParsed

func (k *KeyValueArg[T]) IsParsed() bool

func (*KeyValueArg[T]) IsRepeatable

func (k *KeyValueArg[T]) IsRepeatable() bool

func (*KeyValueArg[T]) IsRequired

func (k *KeyValueArg[T]) IsRequired() bool

func (*KeyValueArg[T]) IsSupplied

func (k *KeyValueArg[T]) IsSupplied() bool

func (*KeyValueArg[T]) Name

func (k *KeyValueArg[T]) Name() string

func (*KeyValueArg[T]) Shorthand

func (k *KeyValueArg[T]) Shorthand() string

func (*KeyValueArg[T]) Type

func (k *KeyValueArg[T]) Type() Type

func (*KeyValueArg[T]) Usage

func (k *KeyValueArg[T]) Usage() string

func (*KeyValueArg[T]) ValueType

func (k *KeyValueArg[T]) ValueType() string

func (*KeyValueArg[T]) Variable

func (k *KeyValueArg[T]) Variable() Variable[T]

type KeyValueDeriver

type KeyValueDeriver interface {
	DeriveKeyValue(v any, name string, opts ...Option) (IKeyValue, error)
}

A KeyValueDeriver is responsible for constructing a KeyValueArg dynamically.

type Metadata

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

Metadata holds the metadata for some Arg.

Metadata can only be updated through Option implementations.

func NewMetadata

func NewMetadata(opts ...Option) *Metadata

NewMetadata is a constructor for a new Metadata.

func (*Metadata) Default

func (m *Metadata) Default() string

func (*Metadata) HasDefault

func (m *Metadata) HasDefault() bool

func (*Metadata) IsRequired

func (m *Metadata) IsRequired() bool

func (*Metadata) Shorthand

func (m *Metadata) Shorthand() string

func (*Metadata) Usage

func (m *Metadata) Usage() string

type Option

type Option interface {
	// contains filtered or unexported methods
}

An Option describes a change to some *Metadata.

func AsOptional

func AsOptional() Option

AsOptional makes an Arg optional.

func AsRequired

func AsRequired() Option

AsRequired makes an Arg required.

func WithAlias

func WithAlias(sh string) Option

WithAlias adds a shorthand/alias to some Arg if applicable.

func WithDefault

func WithDefault(defaultValue string) Option

WithDefault adds a default string value for some Arg, if applicable.

func WithUsage

func WithUsage(usage string) Option

WithUsage adds a usage string to some Arg.

type ParseError

type ParseError struct {
	Id    Identifier
	Cause error
}

ParseError indicates that an error occurred parsing the variable for some argument.

func ErrParsing

func ErrParsing(id Identifier, cause error) *ParseError

ErrParsing is a constructor for a ParseError.

func (*ParseError) Error

func (err *ParseError) Error() string

func (*ParseError) Unwrap

func (err *ParseError) Unwrap() error

type Parser

type Parser struct {
	// Id for the Parser
	Id string

	// Name of the program
	Name string

	// Description of the program
	Description string

	// ErrorHandling mode to be used by the Parser
	ErrorHandling ErrorHandling

	// underlying Set for the Parser - holding all the Arg types the Parser is responsible for
	*Set

	// Shift shifts the Parser along, ignoring the first 'shifted' arguments
	Shift int

	// Strict defines whether unrecognised tokens (e.g. flag/keys) are ignored, or return ErrUnidentified
	Strict bool

	// SuppressUsage stops the Usage from being written out when an error occurs
	SuppressUsage bool

	// SuppressValidation stops validation errors (i.e. adding arguments to the Parser) from breaking
	// the program
	SuppressValidation bool

	Stdin  FileReader
	Stdout FileWriter
	Stderr FileWriter
	// contains filtered or unexported fields
}

A Parser contains and parses a number of flag, key-value or positional inputs from the command-line.

Once all desired Arg have been added to the Parser (see Add), the arguments can be parsed using the Parse method.

By default, a Parser will read from os.Stdin and write to os.Stdout and os.Stderr - these fields can be changed as required to any FileReader or FileWriter.

func Must

func Must(name string, elements ...any) *Parser

Must is a constructor for a *Parser that panics if any error occurs.

func New

func New(name string, elements ...any) (*Parser, error)

New creates a new command-line argument Parser with ErrorHandling mode ContinueOnError.

`elements` can be either concrete Arg implementations, or structs with Arg(s) defined via struct-tags, which will be derived at runtime.

func NewAt

func NewAt(name string, errHandling ErrorHandling, elements ...any) (*Parser, error)

NewAt is a constructor for a Parser at a specific ErrorHandling level.

If no elements are supplied, NewAt is guaranteed to return a nil error.

func NewParser

func NewParser(n string, errHandling ErrorHandling) *Parser

NewParser is a constructor for a new command-line argument Parser.

func (*Parser) Add

func (p *Parser) Add(args ...Arg) *Parser

Add a number of Arg(s) to the Parser.

func (*Parser) AddFlag

func (p *Parser) AddFlag(f IFlag, opts ...Option) *Parser

AddFlag adds a flag argument to the Parser.

func (*Parser) AddKeyValue

func (p *Parser) AddKeyValue(kv IKeyValue, opts ...Option) *Parser

AddKeyValue adds a key-value argument to the Parser.

func (*Parser) AddPipe

func (p *Parser) AddPipe(pipe IPipe, options ...Option) *Parser

AddPipe adds a pipe argument to the Parser.

func (*Parser) AddPosition

func (p *Parser) AddPosition(a IPositional, opts ...Option) *Parser

AddPosition adds a positional argument to the Parser.

func (*Parser) Complete

func (p *Parser) Complete(cmd *complete.Command)

Complete attaches arguments and flags to the completion Command for autocompletion support.

func (*Parser) Err

func (p *Parser) Err() error

Err returns the error(s) for the *latest* call to Parse.

func (*Parser) Ok

func (p *Parser) Ok() *Parser

Ok checks the state of the Parser (both parse and validation errors, unless SuppressValidation is set)

Returns the *Parser for convenience.

func (*Parser) Parse

func (p *Parser) Parse(argv ...string)

Parse command-line input.

Parse does not return an error, instead, during the run any errors that occur are collected and stored internally to be retrieved via the Err method. If the ErrorHandling is not set to ContinueOnError, then errors during Parse will cause the program to either panic of exit.

func (*Parser) RawFlags

func (p *Parser) RawFlags() map[string][]string

RawFlags returns the raw flag arguments and their associated values detected by the Parser.

func (*Parser) RawKeyValues

func (p *Parser) RawKeyValues() map[string][]string

RawKeyValues returns the raw key-value arguments detected by the Parser.

func (*Parser) RawPositions

func (p *Parser) RawPositions() []string

RawPositions returns the raw ordered positional arguments detected by the Parser.

func (*Parser) State

func (p *Parser) State(id Identifier) error

State checks the 'state' of some Arg by its Identifier *after* Parse has been called (always returning nil before).

func (*Parser) Usage

func (p *Parser) Usage()

Usage writes the help-text/usage to the output.

func (*Parser) Valid

func (p *Parser) Valid() error

Valid returns validation error(s) that occurred trying to add arguments to the Parser.

func (*Parser) WithDescription

func (p *Parser) WithDescription(desc string) *Parser

WithDescription sets a description for the Parser.

type Pipe

type Pipe string

Pipe is an Identifier for the PipeArg.

Any value of Pipe will Identify the singular PipeArg in a Parser.

type PipeArg

type PipeArg[T any] struct {
	// contains filtered or unexported fields
}

PipeArg represents *the* (there can only be a single PipeArg defined per Parser) command-line inpu provided from the Stdout of another program.

func CSVPipe

func CSVPipe[T any](variable *T, parser parse.Parser[T], options ...Option) *PipeArg[T]

CSVPipe is a constructor for a PipeArg which reads comma-separated values from a pipe supplied via the command-line.

func NewLinePipe

func NewLinePipe[T any](variable *T, parser parse.Parser[T], options ...Option) *PipeArg[T]

NewLinePipe is a constructor for a PipeArg which reads new lines from a pipe supplied via the command-line.

func NewPipeArg

func NewPipeArg[T any](variable *T, parser parse.Parser[T], piper Piper, input FileReader, options ...Option) *PipeArg[T]

func PipeUsingVariable

func PipeUsingVariable[T any](piper Piper, input FileReader, v Variable[T], options ...Option) *PipeArg[T]

func (*PipeArg[T]) Default

func (p *PipeArg[T]) Default() string

Default returns an empty string - a pipe cannot have a default value.

func (*PipeArg[T]) IsParsed

func (p *PipeArg[T]) IsParsed() bool

func (*PipeArg[T]) IsRepeatable

func (p *PipeArg[T]) IsRepeatable() bool

IsRepeatable returns false - a pipe can only be supplied once.

func (*PipeArg[T]) IsRequired

func (p *PipeArg[T]) IsRequired() bool

IsRequired returns false - a pipe is not required.

func (*PipeArg[T]) IsSupplied

func (p *PipeArg[T]) IsSupplied() (cond bool)

IsSupplied checks if a pipe has been supplied & data has been written to the pipe.

func (*PipeArg[T]) Name

func (p *PipeArg[T]) Name() string

func (*PipeArg[T]) PipeDecode

func (p *PipeArg[T]) PipeDecode(in io.Reader) ([]string, error)

func (*PipeArg[T]) PipeInput

func (p *PipeArg[T]) PipeInput() FileReader

func (*PipeArg[T]) Shorthand

func (p *PipeArg[T]) Shorthand() string

func (*PipeArg[T]) Type

func (p *PipeArg[T]) Type() Type

func (*PipeArg[T]) Usage

func (p *PipeArg[T]) Usage() string

func (*PipeArg[T]) Variable

func (p *PipeArg[T]) Variable() Variable[T]

type Piper

type Piper interface {
	Pipe(in io.Reader) ([]string, error)
}

A Piper is responsible for decoding the data from a pipe into raw command-line arguments

type Position

type Position int

Position is an Identifier for some PositionalArg.

type PositionalArg

type PositionalArg[T any] struct {
	// contains filtered or unexported fields
}

A PositionalArg represents a particular index (or indexes) of positional arguments representing some type T.

Should be created by the NewPosition and NewPositions functions.

func NewPosition

func NewPosition[T any](variable *T, index int, parser parse.Parser[T], opts ...Option) *PositionalArg[T]

NewPosition is a constructor for a positional argument at some index.

func NewPositions

func NewPositions[T any](variables *[]T, fromIndex int, parser parse.Parser[T], opts ...Option) *PositionalArg[[]T]

NewPositions is a constructor for a number of positional arguments starting from some index.

func PositionUsingVariable

func PositionUsingVariable[T any](index int, v Variable[T], opts ...Option) *PositionalArg[T]

func PositionsUsingVariable

func PositionsUsingVariable[T any](fromIndex int, v Variable[[]T], opts ...Option) *PositionalArg[[]T]

func (*PositionalArg[T]) Default

func (p *PositionalArg[T]) Default() string

func (*PositionalArg[T]) Index

func (p *PositionalArg[T]) Index() int

func (*PositionalArg[T]) IsParsed

func (p *PositionalArg[T]) IsParsed() bool

func (*PositionalArg[T]) IsRepeatable

func (p *PositionalArg[T]) IsRepeatable() bool

func (*PositionalArg[T]) IsRequired

func (p *PositionalArg[T]) IsRequired() bool

func (*PositionalArg[T]) IsSupplied

func (p *PositionalArg[T]) IsSupplied() bool

func (*PositionalArg[T]) Name

func (p *PositionalArg[T]) Name() string

func (*PositionalArg[T]) Shorthand

func (p *PositionalArg[T]) Shorthand() string

func (*PositionalArg[T]) Type

func (p *PositionalArg[T]) Type() Type

func (*PositionalArg[T]) Usage

func (p *PositionalArg[T]) Usage() string

func (*PositionalArg[T]) ValueType

func (p *PositionalArg[T]) ValueType() string

func (*PositionalArg[T]) Variable

func (p *PositionalArg[T]) Variable() Variable[T]

type PositionalDeriver

type PositionalDeriver interface {
	DerivePosition(v any, index int, opts ...Option) (IPositional, error)
}

A PositionalDeriver is responsible for constructing a PositionalArg dynamically.

type ScanError

type ScanError struct {
	Tokens []string // Tokens are the offending tokens
	Cause  error    // Cause is the error that the tokens lead to
}

ScanError indicates that there was an error scanning the command-line inpu.

func ErrScanning

func ErrScanning(cause error, tokens ...string) *ScanError

ErrScanning is a constructor for a ScanError.

func (*ScanError) Error

func (err *ScanError) Error() string

func (*ScanError) Unwrap

func (err *ScanError) Unwrap() error

type SeparatedValuePiper

type SeparatedValuePiper struct {
	Separator string
}

func (*SeparatedValuePiper) Pipe

func (s *SeparatedValuePiper) Pipe(in io.Reader) ([]string, error)

type Set

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

A Set is a container for a command-line Arg(s) of any Type.

func NewSet

func NewSet() *Set

NewSet is a constructor for a new empty *Set.

func NewSetWithHelp

func NewSetWithHelp() *Set

func (*Set) AddFlag

func (s *Set) AddFlag(f IFlag, opts ...Option) error

AddFlag adds a flag argument to the Parser.

Returns ErrDuplicate if the key or alias already exists in the Set.

func (*Set) AddKeyValue

func (s *Set) AddKeyValue(kv IKeyValue, opts ...Option) error

AddKeyValue adds a key-value argument to the Set.

Returns ErrDuplicate if the key or alias already exists in the Set.

func (*Set) AddPipe

func (s *Set) AddPipe(p IPipe, opts ...Option) error

AddPipe adds a pipe argument to the Set.

Returns ErrPipeExists if a pipe already exists in the Set.

func (*Set) AddPosition

func (s *Set) AddPosition(a IPositional, opts ...Option) error

AddPosition adds a positional argument to the Set.

The Set expects positional arguments to be supplied in order and returns a wrapped ErrInvalidIndex if arguments are specified in an invalid order.

func (*Set) Args

func (s *Set) Args() []Arg

Args returns all the Arg(s) within the Set.

func (*Set) ByShorthand

func (s *Set) ByShorthand(sh string) Arg

ByShorthand returns the Arg for the given shorthand identifier, if it exists, otherwise nil.

func (*Set) Flag

func (s *Set) Flag(name string) IFlag

Flag returns the flag for the given Id/identifier, if it exists, otherwise nil.

func (*Set) Flags

func (s *Set) Flags() []IFlag

Flags returns all flags(s) within the argMap.

func (*Set) Get

func (s *Set) Get(id Identifier) Arg

Get returns an Arg with the given Identifier, if it exists in the Set.

func (*Set) Has

func (s *Set) Has(id Identifier) bool

Has returns true if there is an Arg with the given Identifier in the Set.

func (*Set) Key

func (s *Set) Key(name string) IKeyValue

Key returns the key-value argument for the given Id/identifier, if it exists, otherwise nil.

func (*Set) KeyValues

func (s *Set) KeyValues() []IKeyValue

KeyValues returns all key-value arguments within the Set.

func (*Set) Pipe

func (s *Set) Pipe() IPipe

Pipe returns the pipe argument for the Set, if it exists, otherwise nil.

func (*Set) Pos

func (s *Set) Pos(index int) IPositional

Pos returns the positional argument at the supplied index, if it exists, otherwise nil.

func (*Set) PosS

func (s *Set) PosS(sindex string) IPositional

PosS is a wrapper around Pos which accepts a string representation of the integer position.

func (*Set) Positions

func (s *Set) Positions() []IPositional

Positions returns all positional arguments within the Set.

type Type

type Type int

Type indicates the 'type' of input being processed (either a flag, key-value argument or a positional argument).

const (
	Unrecognised Type = iota
	FlagType
	KeyValueType
	PositionType
	PipeType
)

func TypeOf

func TypeOf(id Identifier) Type

TypeOf is a helper function for getting the type of Arg from an Identifier.

func (Type) String

func (t Type) String() string

type TypedArg

type TypedArg[T any] interface {
	Arg
	// Variable returns the underlying Variable for the Arg
	Variable() Variable[T]
}

TypedArg is the generic interface that is satisfied by all Arg implementations.

This is a convenience interface that provides access to the underlying generic Variable.

type Updater

type Updater interface {
	// contains filtered or unexported methods
}

Updater is the shared private behaviour shared by all Arg which allows mutable *Metadata fields to be updated and the underlying value/variable of an Arg to be updated.

type Variable

type Variable[T any] interface {
	// Update parses the given input and attempts to update the underlying variable
	Update(...string) error
	// Ref returns a reference to the underlying variable
	Ref() *T
	// Unwrap returns the value of the underlying variable
	Unwrap() T
	// Parser returns the Func for the variable
	Parser() parse.Parser[T]
}

A Variable refers to some program variable that can be parsed from string input.

Internally, a Variable uses a Func to parse some string input into the underlying variable.

func NewVariable

func NewVariable[T any](variable *T, p parse.Parser[T]) Variable[T]

NewVariable is a constructor for a Variable.

func NewVariables

func NewVariables[T any](variables *[]T, p parse.Parser[T]) Variable[[]T]

NewVariables is a constructor for a Variable that has an underlying argumentVariable of slice-type.

This is a helper function which converts the supplied Func into one that supports slices via Slice.

A specific Func can be used by creating a Variable using NewVariablesWithParser.

func NewVariablesWithParser

func NewVariablesWithParser[T any](variables *[]T, p parse.Parser[[]T]) Variable[[]T]

NewVariablesWithParser is a constructor for a Variable that has an underlying Func of slice-type.

Directories

Path Synopsis
cmd
examples
internal
pkg
flag
Package flag provides helper functions for creating clap.FlagArg(s) with common types.
Package flag provides helper functions for creating clap.FlagArg(s) with common types.
keyvalue
Package keyvalue provides helper functions for creating clap.KeyValueArg(s) with common types.
Package keyvalue provides helper functions for creating clap.KeyValueArg(s) with common types.
pos
Package pos provides helper functions for creating clap.PositionalArg(s) with common types.
Package pos provides helper functions for creating clap.PositionalArg(s) with common types.

Jump to

Keyboard shortcuts

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