options

package
v0.0.0-...-aeb6c29 Latest Latest
Warning

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

Go to latest
Published: May 28, 2022 License: MIT Imports: 5 Imported by: 1

Documentation

Overview

Package options provides a command line option parser.

This package is meant as an alternative to the core flag package. It is more powerful without attempting to support every possible feature some parsing library ever introduced. It is arguably easier to use.

Usage:

Create an OptionSpec that documents your program's allowed flags. This begins with a free-text synopsis of your command line interface, then a line containing only two dashes, then a series of option specifications:

import "github.com/gaal/go-options/options"
s := options.NewOptions(`
cat - concatenate files to standard input
Usage: cat [OPTIONS] file...
This version of cat supports character set conversion.
Fancifully, you can say "-r 3" and have everything told you three times.
--
n,numerate,number     number input lines
e,escape              escape nonprintable characters
i,input-encoding=     charset input is encoded in [utf-8]
o,output-encoding=    charset output is encoded in [utf-8]
r,repeat=             repeat every line some number of times [1]
v,verbose             be verbose
`)

Then parse the command line:

opt := s.Parse(os.Args[1:])

This return value is of Options type and has the parsed command line (for an alternate way of parsing the command line, see the "Callback interface" descibed below).

Options may have any number of aliases; the last one is the "canonical" name and the one your program must use when reading values.

opt.Get("input-encoding")  // Returns "utf-8", or whatever user set.
opt.Get("i")               // Error! No option with that canonical name.
opt.Get("number")          // Returns "" if the user didn't specify it.

Get returns a string. Several very simple conversions are provided but you are encouraged to write your own if you need more.

opt.GetBool("escape")      // false (by default)
opt.GetBool("number")      // false (by default)
opt.GetInt("repeat")       // 1 (by default)

Options either take a required argument or take no argument. Non-argument options have useful values exposed as bool and ints.

// cat -v -v -v, or alternatively,
// cat -vvv
opt.GetBool("verbose")     // true
opt.GetInt("verbose")      // 3

The user can say either "--foo=bar" or "--foo bar". Short options may be clustered; "-abc foo" means the same as "-a -b -c=foo".

Parsing stops if "--" is given on the command line.

The "Extra" field of the returned Options contains all non-option command line input. In the case of a cat command, this would be the filenames to concat.

By default, options permits such extra values. Setting UnknownValuesFatal causes it to panic when it enconters them instead.

The "Flags" field of the returned Options contains the series of flags as given on the command line, including repeated ones (which are suppressed in opt -- it only contains the last value). This allows you to do your own handling of repeated options easily.

By default, options does not permit unknown flags. Setting UnknownOptionsFatal to false causes them to be recorded in "flags" instead. Note that since they have no canonical name, they cannot be accessed via opt. Also note that since options does not know about the meaning of these flags, it has to guess whether they consume the next argument or not. This is currently done naively by peeking at the first character of the next argument.

Callback interface:

If you prefer a more type-safe, static interface to your options, you can use options to get that too. Instead of looking at opt and friends, set OptionSpec.ParseCallback:

var (foo string; bar int; baz float64; lst []string; verbose bool)

func myParseCallback(spec *OptionSpec, option string, argument *string) {
  if argument != nil {
    switch option {
    case "string-option":  foo = *argument
    case "int-option":     fmt.Sscanf(*argument, "%d", &bar)
    case "decimal-option": fmt.Sscanf(*argument, "%f", &baz)
    case "list-option":    lst = append(lst, *argument)
    default: spec.PrintUsageAndExit("Unknown option: " + option)
    }
  } else {
    switch option {
    case "verbose": verbose = true
    case "help":    spec.PrintUsageAndExit("")  // No error
    default:        spec.PrintUsageAndExit("Unknown option: " + option)
  }
}

spec.ParseCallback = myParseCallback
opt := spec.Parse(os.Args[1:])
// Note that the opt.Get won't work when using a custom parse callback.

Index

Constants

View Source
const EX_USAGE = 64 // Exit status for incorrect command lines.

Variables

This section is empty.

Functions

func GetAll

func GetAll(flag string, flags [][]string) []string

GetAll is a convenience function which scans the "flags" return value of OptionSpec.Parse, and gathers all the values of a given option. This must be a required-argument option.

Types

type OptionSpec

type OptionSpec struct {
	Usage               string // Formatted usage string
	UnknownOptionsFatal bool   // Whether to die on unknown flags [true]
	UnknownValuesFatal  bool   // Whether to die on extra nonflags [false]

	ParseCallback func(*OptionSpec, string, *string) // Custom callback function
	Exit          func(code int)                     // Function to use for exiting [os.Exit]
	ErrorWriter   io.Writer                          // Alternate Writer for usage writing
	// contains filtered or unexported fields
}

OptionSpec represents the specification of a command line interface.

func NewOptions

func NewOptions(spec string) *OptionSpec

NewOptions takes a string speficiation of a command line interface and returns an OptionSpec for you to call Parse on.

func (*OptionSpec) GetCanonical

func (s *OptionSpec) GetCanonical(option string) string

GetCanonical returns the canonical name of an option, or the empty string if the option is unkown. Useful to tidy up switch statements when using the custom callback interface.

func (*OptionSpec) Parse

func (s *OptionSpec) Parse(args []string) Options

Parse performs the actual parsing of a command line according to an OptionSpec. It returns an Options value; see the package description for an overview of what it means and how to use it. In case of parse error, a panic is thrown. TODO(gaal): decide if gentler error signalling is more useful.

func (*OptionSpec) PrintUsageAndExit

func (s *OptionSpec) PrintUsageAndExit(err string)

PrintUsageAndExit writes the usage string and exits the program. If an error message is given, usage is written to standard error. Otherwise, it is written to standard output; this makes invocations such as "myprog --help | less" work as the user expects. Likewise, the status code is zero when no error was given.

func (*OptionSpec) SetParseCallback

func (s *OptionSpec) SetParseCallback(callback func(*OptionSpec, string, *string)) *OptionSpec

SetParseCallback is a convencience function designed to be chained after NewOptions.

func (*OptionSpec) SetUnknownOptionsFatal

func (s *OptionSpec) SetUnknownOptionsFatal(val bool) *OptionSpec

SetUnknownOptionsFatal is a conveience function designed to be chained after NewOptions.

func (*OptionSpec) SetUnknownValuesFatal

func (s *OptionSpec) SetUnknownValuesFatal(val bool) *OptionSpec

SetUnknownValuesFatal is a conveience function designed to be chained after NewOptions.

type Options

type Options struct {
	Flags    [][]string // Original flags presented on the command line
	Extra    []string   // Non-option command line arguments left on the command line
	Leftover []string   // Untouched arguments (after "--")
	// contains filtered or unexported fields
}

Options represents the known formal options provided on the command line.

func (*Options) Get

func (o *Options) Get(flag string) string

Get returns the value of an option, which must be known to this parse. Options that take an argument return the argument. Options with no argument return values hinting whether they were specified or not; GetInt or GetBool may be more suited for looking them up.

func (*Options) GetBool

func (o *Options) GetBool(flag string) bool

GetBool returns the value of an option as a bool. All values are treated as true except for the following which yield false:

"" (empty), "0", "false", "off", "nil", "null", "no"

func (*Options) GetInt

func (o *Options) GetInt(flag string) int

GetInt returns the value of an option as an integer. The empty string is treated as zero, but otherwise the option must parse or a panic occurs.

func (*Options) Have

func (o *Options) Have(flag string) bool

Have returns false when an option has no default value and was not given on the command line, or true otherwise.

Notes

Bugs

  • Option groups are not yet supported.

  • The usage string is not yet formatted prettily. It should consider tty width, etc.

  • Negated options ("--no-frobulate") are not yet supported.

Jump to

Keyboard shortcuts

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