A Go (golang) package for building frictionless command-line interfaces
MIT License
Creating command-line interfaces should be simple:
package main
import (
"log"
"github.com/jpillora/opts"
)
func main() {
type config struct {
File string `opts:"help=file to load"`
Lines int `opts:"help=number of lines to show"`
}
c := config{}
opts.Parse(&c)
log.Printf("%+v", c)
}
$ go build -o my-prog
$ ./my-prog --help
Usage: my-prog [options]
Options:
--file, -f file to load
--lines, -l number of lines to show
--help, -h display help
$ ./my-prog -f foo.txt -l 42
{File:foo.txt Lines:42}
Try it out https://play.golang.org/p/D0jWFwmxRgt
--help
text via struct tags (eg-help)Parse()
(eg-defaults)Opts
(eg-commands-main)opts.Setter
or flag.Value
(eg-custom-flag)Find these examples and more in the opts-examples
repository.
See https://godoc.org/github.com/jpillora/opts#Opts
opts tries to set sane defaults so, for the most part, you'll get the desired behaviour by simply providing a configuration struct.
However, you can customise this behaviour by providing the opts
struct
tag with a series of settings in the form of key=value
:
`opts:"key=value,key=value,..."`
Where key
must be one of:
-
(dash) - Like json:"-"
, the dash character will cause opts to ignore the struct field. Unexported fields are always ignored.
name
- Name is used to display the field in the help text. By default, the flag name is infered by converting the struct field name to lowercase and adding dashes between words.
help
- The help text used to summaryribe the field. It will be displayed next to the flag name in the help output.
Note: help
can also be set as a stand-alone struct tag (i.e. help:"my text goes here"
). You must use the stand-alone tag if you wish to use a comma ,
in your help string.
mode
- The opts mode assigned to the field. All fields will be given a mode
. Where the mode
value
must be one of:
flag
- The field will be treated as a flag: an optional, named, configurable field. Set using ./program --<flag-name> <flag-value>
. The struct field must be a flag-value type. flag
is the default mode
for any flag-value.
arg
- The field will be treated as an argument: a required, positional, unamed, configurable field. Set using ./program <argument-value>
. The struct field must be a flag-value type.
embedded
- A special mode which causes the fields of struct to be used in the current struct. Useful if you want to split your command-line options across multiple files (default for struct
fields). The struct field must be a struct
. embedded
is the default mode
for a struct
. Tip You can play group all fields together placing an group
tag on the struct field.
cmd
- A inline command, shorthand for .AddCommmand(opts.New(&field))
, which also implies the struct field must be a struct
.
cmdname
- A special mode which will assume the name of the selected command. The struct field must be a string
.
short
- One letter to be used a flag's "short" name. By default, the first letter of name
will be used. It will remain unset if there is a duplicate short name or if opts:"short=-"
. Only valid when mode
is flag
.
group
- The name of the flag group to store the field. Defining this field will create a new group of flags in the help text (will appear as "<group>
options"). The default flag group is the empty string (which will appear as "Options"). Only valid when mode
is flag
or embedded
.
env
- An environent variable to use as the field's default value. It can always be overridden by providing the appropriate flag. Only valid when mode
is flag
.
For example, opts:"env=FOO"
. It can also be infered using the field name with simply opts:"env"
. You can enable inference on all flags with the opts.Opts
method UseEnv()
.
min
max
- A minimum or maximum length of a slice. Only valid when mode
is arg
, and the struct field is a slice.
In general an opts flag-value type aims to be any type that can be get and set using a string
. Currently, opts supports the following types:
string
bool
int
, int8
, int16
, int32
, int64
uint
, uint8
, uint16
, uint32
, uint64
float32
, float64
opts.Setter
func Set(string) error
flag.Value
opts.Setter
time.Duration
encoding.TextUnmarshaler
time.Time
and net.IP
encoding.BinaryUnmarshaler
url.URL
In addition, flag
s and arg
s can also be a slice of any flag-value type. Slices allow multiple flags/args. For example, a struct field flag Foo []int
could be set with --foo 1 --foo 2
, and would result in []int{1,2}
.
By default, opts attempts to output well-formatted help text when the user provides the --help
(-h
) flag. The examples repositories shows various combinations of this default help text, resulting from using various features above.
Modifications be made by customising the underlying Go templates found here DefaultTemplates.
I gave a talk on opts at the Go Meetup Sydney (golang-syd) on the 23rd of May, 2019. You can find the slides here https://github.com/jpillora/opts-talk.
Other related projects which infer flags from struct tags but aren't as feature-complete:
Copyright © 2019 <[email protected]>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.