pflags
with generic types.
OK so this is yet another CLI flags library...
We do not reinvent the wheel: this module reuses the great package
github.com/spf13/pflag
, with an interface built on go generics.The main idea is to simplify the
pflag
interface, with less things to remember about flag types.So this is not a fork or drop-in replacement, but rather an extension of the
pflag
functionality.
This package is designed to be used together with github.com/spf13/pflag
.
All types created by gflag
implement the pflag.Value
interface.
Use-case: build idiomatic cobra
CLIs with a simpler declaration of flags.
See how go-cli achieves this.
import (
"fmt"
"github.com/fredbi/gflag"
"github.com/spf13/pflag"
)
var flagVal int
fs := pflag.NewFlagSet("", pflag.ContinueOnError)
intFlag := gflag.NewFlagValue(&flagVal, 1) // infer flag from underlying type int, with a default value
fs.Var(intFlag, "integer", "integer value") // register the flag in pflag flagset
_ = fs.Parse([]string{"--integer", 10}) // parse command line arguments
fmt.Println(intFlag.GetValue()) // the flag knows the type of the value
With pflag
this piece of code would look very much similar.
import (
"fmt"
"github.com/spf13/pflag"
)
var flagVal int
fs := pflag.NewFlagSet("", pflag.ContinueOnError)
fs.IntVar(&flagVal, "integer", "integer value") // register the flag in pflag flagset
_ = fs.Parse([]string{"--integer", 10}) // parse command line arguments
fmt.Println(fs.GetInt("integer")) // has to know an integer type is expected
You may take a look at more examples, with slices and maps.
This package provides a unified approach to strongly typed flags, using go generics.
This way, we no longer have to register CLI flags using dozen of type-specific methods, just three:
NewFlagValue()
: for scalar valuesNewFlagSliceValue()
: for flags as listsNewFlagMapValue()
: for flags as map (e.g. key=value pairs)
The flag building logic is consistent for single values, slices and maps of all types.
Differences in semantics are handled with a set of Option
s.
- All primitive types (yes, complex too!) are supported.
- All common types handled by
pflag
(time.Duration
,net.IP
, etc..) are also supported. - I have also added
time.Time
- Support any extension built for
pflag
(arbitrary types with thepflag.Value
interface)
Variations in the semantics for a flag with a given underlying type may be fine-tuned with options.
There is an extensions
sub-package to contribute some custom extra flag types.
It is now populated with a byte-size
flag. See the example.