getopt

package module
v0.0.0-...-a855b04 Latest Latest
Warning

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

Go to latest
Published: Aug 4, 2026 License: BSD-3-Clause Imports: 9 Imported by: 0

README

mattmc3/getopt

This project fixes what I believe to be the worst parts of Go's built-in flags:

  1. It drops the default lexicographical flag sorting in favor of insertion order, so that the developer can maintain better control of help output.
  2. It adds support for short flag aliases
  3. It provides a more standard and sane PrintDefaults help output.
  4. It adds a generic Define method to FlagSet, so one call covers every supported flag type instead of one method per type. (Requires Go >=1.27)

It is a fork of rsc/getopt which got us partway there.

fs := getopt.NewFlagSet("example", flag.ExitOnError)
// ... define flags in desired order ...
fs.PrintDefaults()

To get the lexicographical sorting that package flag does, call SortFlags() on your FlagSet.

fs := getopt.NewFlagSet("example", flag.ExitOnError)
fs.SortFlags()

Sorting affects Visit, VisitAll, and PrintDefaults output. Flags defined directly on the embedded flag.FlagSet are not tracked for insertion order, so they are listed last in lexicographical order.

Define

Define collapses the per-type methods into one generic call. The type comes from the default value, so there is nothing to spell out:

port := fs.Define("port", 8080, "port to listen on")          // *int
wait := fs.Define("wait", 5*time.Second, "how long to wait")  // *time.Duration
name := fs.Define("name", "", "your name")                    // *string

FlagType admits bool, int, int64, uint, uint64, float64, string, and time.Duration. Anything else is a compile error. The methods taking a function or an arbitrary flag.Value (Func, BoolFunc, TextVar, Var) have no default value to infer from, so they stay as they are.

Generic methods need Go 1.27, so Define lives in a file tagged //go:build go1.27. Older toolchains drop that file and build the rest of the module unchanged. Flags declared through Define keep insertion order like any other.

Implementation: Uses code generation (go generate) to wrap standard library flag methods while tracking insertion order internally. The getopt Parse method was modified to call FlagSet.Set() instead of Value.Set() directly, ensuring parsed flags are tracked correctly.

Original docs

[For full package documentation, see https://godoc.org/rsc.io/getopt.]

package getopt // import "github.com/mattmc3/getopt"

Package getopt parses command lines using getopt(3) syntax. It is a replacement for flag.Parse but still expects flags themselves to be defined in package flag.

Flags defined with one-letter names are available as short flags (invoked using one dash, as in -x) and all flags are available as long flags (invoked using two dashes, as in --x or --xylophone).

To use, define flags as usual with package flag. Then introduce any aliases by calling getopt.Alias:

getopt.Alias("v", "verbose")

Or call getopt.Aliases to define a list of aliases:

getopt.Aliases(
	"v", "verbose",
	"x", "xylophone",
)

One name in each pair must already be defined in package flag (so either "v" or "verbose", and also either "x" or "xylophone").

Then parse the command-line:

getopt.Parse()

If it encounters an error, Parse calls flag.Usage and then exits the program.

When writing a custom flag.Usage function, call getopt.PrintDefaults instead of flag.PrintDefaults to get a usage message that includes the names of aliases in flag descriptions.

At initialization time, package getopt installs a new flag.Usage that is the same as the default flag.Usage except that it calls getopt.PrintDefaults instead of flag.PrintDefaults.

This package also defines a FlagSet wrapping the standard flag.FlagSet.

Documentation

Overview

Package getopt parses command lines using getopt(3) syntax. It is a replacement for flag.Parse but still expects flags themselves to be defined in package flag.

Flags defined with one-letter names are available as short flags (invoked using one dash, as in -x) and all flags are available as long flags (invoked using two dashes, as in --x or --xylophone).

To use, define flags as usual with package flag. Then introduce any aliases by calling getopt.Alias:

getopt.Alias("n", "dry-run")
getopt.Alias("v", "verbose")

Or call getopt.Aliases to define a list of aliases:

getopt.Aliases(
	"n", "dry-run",
	"v", "verbose",
)

One name in each pair must already be defined in package flag (so either "n" or "dry-run", and also either "v" or "verbose").

Then parse the command-line:

getopt.Parse()

If it encounters an error, Parse calls flag.Usage and then exits the program.

When writing a custom flag.Usage function, call getopt.PrintDefaults instead of flag.PrintDefaults to get a usage message that includes the names of aliases in flag descriptions.

At initialization time, this package installs a new flag.Usage that is the same as the default flag.Usage except that it calls getopt.PrintDefaults instead of flag.PrintDefaults.

This package also defines a FlagSet wrapping the standard flag.FlagSet.

Caveat

In general Go flag parsing is preferred for new programs, because it is not as pedantic about the number of dashes used to invoke a flag (you can write -verbose or --verbose and the program does not care). This package is meant to be used in situations where, for legacy reasons, it is important to use exactly getopt(3) syntax, such as when rewriting in Go an existing tool that already uses getopt(3).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Alias

func Alias(short, long string)

Alias introduces an alias for an existing flag name. The short name must be a single letter, and the long name must be multiple letters. Exactly one name must be defined as a flag already: the undefined name is introduced as an alias for the defined name. Alias panics if both names are already defined or if both are undefined.

For example, if a flag named "v" is already defined using package flag, then it is available as -v (or --v). Calling Alias("v", "verbose") makes the same flag also available as --verbose.

func Aliases

func Aliases(list ...string)

Aliases introduces zero or more aliases. The argument list must consist of an even number of strings making up a sequence of short, long pairs to be passed to Alias.

func Parse

func Parse()

Parse parses the command-line flags from os.Args[1:].

func PrintDefaults

func PrintDefaults()

PrintDefaults is like flag.PrintDefaults but includes information about short/long alias pairs and prints the correct syntax for long flags.

Types

type FlagSet

type FlagSet struct {
	*flag.FlagSet
	// contains filtered or unexported fields
}

A FlagSet is a set of defined flags. It wraps and provides the same interface as flag.FlagSet but parses command line arguments using getopt syntax.

Note that "go doc" shows only the methods customized by package getopt; FlagSet also provides all the methods of the embedded flag.FlagSet, like Bool, Int, NArg, and so on.

var CommandLine FlagSet

func NewFlagSet

func NewFlagSet(name string, errorHandling flag.ErrorHandling) *FlagSet

NewFlagSet returns a new, empty flag set with the specified name and error handling property.

func (*FlagSet) Alias

func (f *FlagSet) Alias(short, long string)

Alias introduces an alias for an existing flag name. The short name must be a single letter, and the long name must be multiple letters. Exactly one name must be defined as a flag already: the undefined name is introduced as an alias for the defined name. Alias panics if both names are already defined or if both are undefined.

For example, if a flag named "v" is already defined using package flag, then it is available as -v (or --v). Calling Alias("v", "verbose") makes the same flag also available as --verbose.

func (*FlagSet) Aliases

func (f *FlagSet) Aliases(list ...string)

Aliases introduces zero or more aliases. The argument list must consist of an even number of strings making up a sequence of short, long pairs to be passed to Alias.

func (*FlagSet) Bool

func (f *FlagSet) Bool(name string, value bool, usage string) *bool

Bool defines a bool flag with specified name, default value, and usage string. The return value is the address of a bool variable that stores the value of the flag.

func (*FlagSet) BoolFunc

func (f *FlagSet) BoolFunc(name, usage string, fn func(string) error)

BoolFunc defines a flag with the specified name and usage string without requiring values. Each time the flag is seen, fn is called with the value of the flag. If fn returns a non-nil error, it will be treated as a flag value parsing error.

func (*FlagSet) BoolVar

func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string)

BoolVar defines a bool flag with specified name, default value, and usage string. The argument p points to a bool variable in which to store the value of the flag.

func (*FlagSet) Define

func (f *FlagSet) Define[T FlagType](name string, value T, usage string) *T

Define defines a flag with the specified name, default value, and usage string, dispatching to the FlagSet method matching T. The return value is the address of a variable that stores the value of the flag.

This needs the generic methods that landed in Go 1.27. The build tag raises the language version for this file alone, so the module still builds on older toolchains, just without Define.

func (*FlagSet) Duration

func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration

Duration defines a time.Duration flag with specified name, default value, and usage string. The return value is the address of a time.Duration variable that stores the value of the flag. The flag accepts a value acceptable to time.ParseDuration.

func (*FlagSet) DurationVar

func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string)

DurationVar defines a time.Duration flag with specified name, default value, and usage string. The argument p points to a time.Duration variable in which to store the value of the flag. The flag accepts a value acceptable to time.ParseDuration.

func (*FlagSet) Float64

func (f *FlagSet) Float64(name string, value float64, usage string) *float64

Float64 defines a float64 flag with specified name, default value, and usage string. The return value is the address of a float64 variable that stores the value of the flag.

func (*FlagSet) Float64Var

func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string)

Float64Var defines a float64 flag with specified name, default value, and usage string. The argument p points to a float64 variable in which to store the value of the flag.

func (*FlagSet) Func

func (f *FlagSet) Func(name, usage string, fn func(string) error)

Func defines a flag with the specified name and usage string. Each time the flag is seen, fn is called with the value of the flag. If fn returns a non-nil error, it will be treated as a flag value parsing error.

func (*FlagSet) Init

func (f *FlagSet) Init(name string, errorHandling flag.ErrorHandling)

Init sets the name and error handling proprety for a flag set.

func (*FlagSet) Int

func (f *FlagSet) Int(name string, value int, usage string) *int

Int defines an int flag with specified name, default value, and usage string. The return value is the address of an int variable that stores the value of the flag.

func (*FlagSet) Int64

func (f *FlagSet) Int64(name string, value int64, usage string) *int64

Int64 defines an int64 flag with specified name, default value, and usage string. The return value is the address of an int64 variable that stores the value of the flag.

func (*FlagSet) Int64Var

func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string)

Int64Var defines an int64 flag with specified name, default value, and usage string. The argument p points to an int64 variable in which to store the value of the flag.

func (*FlagSet) IntVar

func (f *FlagSet) IntVar(p *int, name string, value int, usage string)

IntVar defines an int flag with specified name, default value, and usage string. The argument p points to an int variable in which to store the value of the flag.

func (*FlagSet) Lookup

func (f *FlagSet) Lookup(name string) *flag.Flag

Lookup returns the Flag structure of the named flag, returning nil if none exists. If name is a defined alias for a defined flag, Lookup returns the original flag; in this case the Name field in the result will differ from the name passed to Lookup.

func (*FlagSet) Parse

func (f *FlagSet) Parse(args []string) error

Parse parses flag definitions from the argument list, which should not include the command name. Parse must be called after all flags and aliases in the FlagSet are defined and before flags are accessed by the program. The return value will be flag.ErrHelp if -h or --help were used but not defined.

func (*FlagSet) PrintDefaults

func (f *FlagSet) PrintDefaults()

PrintDefaults is like flag.PrintDefaults but includes information about short/long alias pairs and prints the correct syntax for long flags.

func (*FlagSet) SetOutput

func (f *FlagSet) SetOutput(output io.Writer)

SetOutput sets the destination for usage and error messages. If output is nil, os.Stderr is used.

func (*FlagSet) SortFlags

func (f *FlagSet) SortFlags()

SortFlags makes Visit, VisitAll, and PrintDefaults use lexicographical order, matching package flag. Insertion order is the default.

func (*FlagSet) String

func (f *FlagSet) String(name string, value string, usage string) *string

String defines a string flag with specified name, default value, and usage string. The return value is the address of a string variable that stores the value of the flag.

func (*FlagSet) StringVar

func (f *FlagSet) StringVar(p *string, name string, value string, usage string)

StringVar defines a string flag with specified name, default value, and usage string. The argument p points to a string variable in which to store the value of the flag.

func (*FlagSet) TextVar

func (f *FlagSet) TextVar(p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string)

TextVar defines a flag with a specified name, default value, and usage string. The argument p must be a pointer to a variable that will hold the value of the flag, and p must implement encoding.TextUnmarshaler. If the flag is used, the flag value will be passed to p's UnmarshalText method. The type of the default value must be the same as the type of p.

func (*FlagSet) Uint

func (f *FlagSet) Uint(name string, value uint, usage string) *uint

Uint defines a uint flag with specified name, default value, and usage string. The return value is the address of a uint variable that stores the value of the flag.

func (*FlagSet) Uint64

func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64

Uint64 defines a uint64 flag with specified name, default value, and usage string. The return value is the address of a uint64 variable that stores the value of the flag.

func (*FlagSet) Uint64Var

func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string)

Uint64Var defines a uint64 flag with specified name, default value, and usage string. The argument p points to a uint64 variable in which to store the value of the flag.

func (*FlagSet) UintVar

func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string)

UintVar defines a uint flag with specified name, default value, and usage string. The argument p points to a uint variable in which to store the value of the flag.

func (*FlagSet) Var

func (f *FlagSet) Var(value flag.Value, name string, usage string)

Var defines a flag with the specified name and usage string. The type and value of the flag are represented by the first argument, of type [Value], which typically holds a user-defined implementation of [Value]. For instance, the caller could create a flag that turns a comma-separated string into a slice of strings by giving the slice the methods of [Value]; in particular, [Set] would decompose the comma-separated string into the slice.

func (*FlagSet) Visit

func (f *FlagSet) Visit(fn func(*flag.Flag))

Visit visits the flags, calling fn for each. It visits only those flags that have been set. Order is controlled by SortFlags (insertion order by default).

Note: This only works correctly if flags were set through the underlying FlagSet.Set() method. The getopt.Parse() method calls Value.Set() directly which bypasses FlagSet's tracking, so Visit may not work as expected after getopt-style parsing. Use VisitAll instead if you need to iterate over all defined flags.

func (*FlagSet) VisitAll

func (f *FlagSet) VisitAll(fn func(*flag.Flag))

VisitAll visits the flags, calling fn for each. It visits all flags, even those not set. Order is controlled by SortFlags (insertion order by default).

type FlagType

type FlagType interface {
	bool | int | int64 | uint | uint64 | float64 | string | time.Duration
}

FlagType is the set of value types Define handles. Terms are exact rather than approximate, since dispatch is by dynamic type.

Directories

Path Synopsis
cmd
gen_flagfuncs command
cmd/gen_flagfuncs/main.go
cmd/gen_flagfuncs/main.go

Jump to

Keyboard shortcuts

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