Documentation
¶
Overview ¶
Package bflags implements binding for command flags or command line
arguments to an object.
Binding happens through tags annotations on struct types using the `cmd` tag
Syntax
Tag are specified using 'cmd' followed by either 'flag', 'arg' or 'args':
flag, name, usage, shorthand, persistent, required, hidden
arg, name, usage, order
The args tag is identical to 'arg' but may be specified only for the last
argument of the command and is useful for slice argument (variadic arguments)
When used, value are set without CSV parsing.
sample:
flag `cmd:"flag,id,content id,i,true,true,false"`
arg `cmd:"arg,id,content id,0"`
Assuming a string value, the above flag tag is read as (using cobra):
cmd.PersistentFlags().StringP("id", "i", "", "content id")
cmd.MarkPersistentFlagRequired("id")
In case the flag is not persistent and not required, it reads as:
cmd.Flags().StringP("id", "i", "", "content id")
Note that flag names are case-sensitive
The default value is the value of the tagged field. In the example below the
field Ip of myInput is initialized with net.IPv4(127, 0, 0, 1) before being
bound. This makes the flag --ip having a default value of 127.0.0.1.
For `arg` tags, the order (starting at 0) must be specified for all or none
of the fields in the struct.
The library also supports specifying a 'meta' tag, followed by a comma separated
list of values that are attached as a slice of strings to the 'Annotations' field
of the resulting FlagBond:
`meta:"value1,value2"`
Even though not a frequent usage, the bound flags can be retrieved after binding:
var c *cobra.Command
_ = Bind(c, &MyStruct{})
flags, _ := GetCmdFlagSet(c)
args, _ := GetCmdArgSet(c)
Example
type SimpleTaggedStruct struct {
Stringval string `cmd:"flag"`
Ids id.ID `cmd:"flag,ids,content ids,i,true,true"`
Id id.ID `cmd:"arg,id,content id,0"`
QId id.ID
Ignore string
}
Complete Usage Sample using go generics.
This example takes advantage of go generics to bind the input to the command
flags and sets the RunE function of the command.
type myInput struct {
Ip net.IP `cmd:"flag,ip,node ip,q"`
Path string `cmd:"arg"`
}
func Execute() error {
cmd, err := bflags.BindRunE(
&myInput{
Ip: net.IPv4(127, 0, 0, 1),
Path: "/tmp",
},
&cobra.Command{
Use: "sample /path",
Short: "run sample",
},
func(in *myInput) error {
bb, err := json.Marshal(in)
if err != nil {
return err
}
fmt.Printf("sample - input %s\n", string(bb))
return nil
},
nil)
if err != nil {
return err
}
err = cmd.Execute()
return err
}
func main() {
if err := Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
Complete Usage Sample.
Same example as above but not using go generics.
type myInput struct {
Ip net.IP `cmd:"flag,ip,node ip,q"`
Path string `cmd:"arg"`
}
func InitFlagsSample() (*cobra.Command, error) {
var cmdFlagsSample = &cobra.Command{
Use: "sample /path",
Short: "run sample",
RunE: runSample,
}
// &myInput instance 'my' here represents the default values of all
// flags bound to it
my := &myInput{
Ip: net.IPv4(127, 0, 0, 1),
Path: "/tmp",
}
err := bflags.Bind(cmdFlagsSample, my)
// this is equivalent to
// cmdFlagsSample.Flags().IPVarP(&my.Ip, "ip", "q", my.Ip, "node ip")
// additionally if the flag was required
// _ = cmdFlagsSample.MarkFlagRequired("ip")
// or hidden:
// cmdFlagsSample.Flag("ip").Hidden = true
if err != nil {
return nil, err
}
return cmdFlagsSample, nil
}
func runSample(cmd *cobra.Command, args []string) error {
// this is required to bind args parameters to the 'arg' fields of the input
m, err := bflags.SetArgs(cmd, args)
if err != nil {
return err
}
my, ok := m.(*myInput)
if !ok {
return errors.E("runSample", "wrong input", m)
}
bb, err := json.Marshal(my)
if err != nil {
return err
}
fmt.Printf("sample - input %s\n", string(string(bb)))
return nil
}
func Execute() error {
cmd, err := InitFlagsSample()
if err != nil {
return err
}
err = cmd.Execute()
return err
}
func main() {
if err := Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
Binding to specific 'custom' types
Binding to specific types is supported through the Flagger interface.
With an instance fl of Flagger, call bflags.BindCustom(cmd, fl, v)
See `TestCustomFlag` for a sample implementation.
Struct implementing flag.Value
**Pointer** values to those structs can be used as flags.
Example:
// workersConfig implements pflag.Value
type workersConfig struct {
QueueSize int
Workers int
}
func (u *workersConfig) String() string {
bb, err := json.Marshal(u)
if err != nil {
return err.Error()
}
return string(bb)
}
func (u *workersConfig) Set(s string) error {
return json.Unmarshal([]byte(s), u)
}
func (u *workersConfig) Type() string {
return "workers"
}
type TestFlagValueStruct struct {
// **pointer** !
Workers *workersConfig `cmd:"flag"`
}
func TestEncodeFlagValue(t *testing.T) {
c := &cobra.Command{
Use: "dontUse",
}
sts := &TestFlagValueStruct{
Workers: &workersConfig{},
}
err := Bind(c, sts)
require.NoError(t, err)
pf := assertFlag(t, c, "Workers")
require.Equal(t, &workersConfig{}, sts.Workers)
err = pf.Value.Set(`{"QueueSize":50,"Workers":5}`)
require.NoError(t, err)
wc := &workersConfig{
QueueSize: 50,
Workers: 5,
}
require.Equal(t, wc, sts.Workers)
}
NOTES
* inner structs - even anonymous - can be used for bindings BUT the
inner struct needs to be initialized otherwise an error is raised
since no binding would occur for its fields.
Index ¶
- func AddTemplateFunc(name string, tmplFunc interface{})
- func AddToCmdCtx(cmd *cobra.Command, name string, v interface{}) bool
- func Bind(c *cobra.Command, v interface{}) error
- func BindCustom(c *cobra.Command, f Flagger, v interface{}) error
- func BindRunE[T any](input *T, cmd *cobra.Command, runE func(*T) error, f Flagger) (*cobra.Command, error)
- func ConfigureCommandHelp(c *cobra.Command)
- func ConfigureHelpFuncs()
- func GetCmdCtx(cmd *cobra.Command) (interface{}, bool)
- func GetCmdInput(cmd *cobra.Command) (interface{}, bool)
- func GetFlagArgSet(c *cobra.Command) map[string]string
- func GetFromCmdCtx(cmd *cobra.Command, name string) (interface{}, bool)
- func SetArgs(c *cobra.Command, args []string) (interface{}, error)
- func SetCmdCtx(cmd *cobra.Command, v interface{})
- func SetupCmdArgs(cmd *cobra.Command, args []string, typ reflect.Type) (interface{}, error)
- type ArgSet
- type Binder
- type CmdFlags
- func (s CmdFlags) ConfigureCmd(cmd *cobra.Command, custom Flagger) error
- func (s CmdFlags) Flagset(cmd *cobra.Command, name string) (*flag.FlagSet, error)
- func (s CmdFlags) Get(name string) (*FlagBond, bool)
- func (s CmdFlags) GetBool(cmd *cobra.Command, name cmdFlag) (bool, error)
- func (s CmdFlags) GetDuration(cmd *cobra.Command, name cmdFlag) (time.Duration, error)
- func (s CmdFlags) GetFloat32(cmd *cobra.Command, name cmdFlag) (float32, error)
- func (s CmdFlags) GetFloat64(cmd *cobra.Command, name cmdFlag) (float64, error)
- func (s CmdFlags) GetIP(cmd *cobra.Command, name cmdFlag) (net.IP, error)
- func (s CmdFlags) GetInt(cmd *cobra.Command, name cmdFlag) (int, error)
- func (s CmdFlags) GetInt64(cmd *cobra.Command, name cmdFlag) (int64, error)
- func (s CmdFlags) GetString(cmd *cobra.Command, name cmdFlag) (string, error)
- func (s CmdFlags) GetUint(cmd *cobra.Command, name cmdFlag) (uint, error)
- func (s CmdFlags) GetUint64(cmd *cobra.Command, name cmdFlag) (uint64, error)
- func (s CmdFlags) Set(string) error
- func (s CmdFlags) String() string
- func (s CmdFlags) Type() string
- func (s CmdFlags) Validate() error
- type ErrorSilencer
- type ErrorTraceRemover
- type FlagBond
- type Flagged
- type Flagger
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AddTemplateFunc ¶ added in v1.0.3
func AddTemplateFunc(name string, tmplFunc interface{})
AddTemplateFunc adds a template function that's available to Usage and Help template generation. Also adds the function to the cobra template functions.
func Bind ¶
Bind binds the flags retrieved in tags of the given struct v as flags or args of the given command. c the command
v expected to be a struct.
Tag are specified using 'cmd' followed by either 'flag' or 'arg':
`cmd:"flag,id,content id, i,true,true,true"` `cmd:"arg,id,content id,0"`
are read as:
flag: name, usage, shorthand, persistent, required, hidden arg: name, usage, order
Attributes with default value on the right side of the expression can be omitted:
`cmd:"flag,id,content id, i"`
A 'meta' tag can be added to convey annotations with the bound tag:
`cmd:"flag,config,file name,c" meta:"file,non-empty"`
func BindCustom ¶
BindCustom is like Bind and allows a custom Flagger
func BindRunE ¶ added in v1.0.3
func BindRunE[T any](input *T, cmd *cobra.Command, runE func(*T) error, f Flagger) (*cobra.Command, error)
BindRunE binds the input parameter to the given command and sets the runE parameter function as the function invoked by the RunE function of the cobra command. _Example_
type testOpts struct {
Password string `cmd:"flag,password,password for the user's key,x"`
NoCert bool `cmd:"flag,no-cert,don't add certificate to the ssh-agent"`
Domains []string `cmd:"arg,domains,name of the ssh domains,0"`
done bool
}
cmd, err := BindRunE(
&testOpts{},
&cobra.Command{
Use: "test <domains>",
Short: "explanation short",
Args: cobra.MinimumNArgs(1),
Example: "test a b",
},
func(opts *testOpts) error {
return opts.run()
},
nil)
if err != nil {
panic(err)
}
... use cmd
func ConfigureCommandHelp ¶ added in v1.0.3
func ConfigureHelpFuncs ¶ added in v1.0.3
func ConfigureHelpFuncs()
func GetCmdInput ¶
func GetFlagArgSet ¶ added in v1.0.3
GetFlagArgSet returns a map[string]string of flags and args that were set for the given command. This function has to be called after SetArgs.
func SetArgs ¶
SetArgs sets the args to the 'arg' fields of the value previously bound as the input of the command. The input must have previously been bound to the command like so:
input := &MyStruct{}
err := bflags.BindCustom(cmd, elvflags.Flags, input)
The input is returned if no error occurred.
func SetupCmdArgs ¶
SetupCmdArgs configures and returns the input struct bound to the provided command with the given arguments. * If the typ parameter is not nil the type of the input is verified * if the input has a function 'Validate() error', the function is called The input must have previously been bound to the command like so:
input := &MyStruct{}
err := bflags.BindCustom(cmd, elvflags.Flags, input)
The input is returned if no error occurred.
Types ¶
type ArgSet ¶
type ArgSet struct {
Flags []*FlagBond
}
func (*ArgSet) ArgUsages ¶
ArgUsages returns a string containing the usage information for all flags in the ArgSet
type Binder ¶ added in v1.0.3
Binder is a utility for fluently building trees of commands with bindings. Example:
root := NewBinderC(
&cobra.Command{
Use: "test",
Short: "root command",
}).
AddCommand(
NewBinder(
&testOpts{},
&cobra.Command{
Use: "a <domains>",
Example: "test a x",
},
func(opts *testOpts) error {
return opts.run()
},
nil),
NewBinder(
&testOpts{},
&cobra.Command{
Use: "b <domains>",
Example: "test b y",
},
func(opts *testOpts) error {
return opts.run()
},
nil))
if root.Error != nil {
panic(root.Error)
}
... use root.Command
func NewBinder ¶ added in v1.0.3
NewBinder returns a Binder initialized by running BindRunE with the given parameters
func NewBinderC ¶ added in v1.0.3
NewBinderC constructs a new Binder with just a Command. This is useful for commands that are only parents of other commands, like the root command.
func (*Binder) AddCommand ¶ added in v1.0.3
AddCommand adds the commands of the given Binder instances to the command of this Binder or append their error to the Error of this Binder if they have errors.
type CmdFlags ¶
type CmdFlags map[cmdFlag]*FlagBond
func (CmdFlags) ConfigureCmd ¶
func (CmdFlags) GetDuration ¶
func (CmdFlags) GetFloat32 ¶
func (CmdFlags) GetFloat64 ¶
type ErrorSilencer ¶ added in v1.0.4
type ErrorSilencer interface {
// SilenceErrors returns true to set cobra.Command.SilenceErrors to true
SilenceErrors() bool
}
ErrorSilencer may be implemented by an input type bound to a command in BindRunE for requesting to silence errors.
type ErrorTraceRemover ¶ added in v1.0.4
type ErrorTraceRemover interface {
// NoTrace returns true to tell BindRunE to remove error stack trace. Note
// that this applies only to the execution of the RunE function and not to
// the setup of the command.
NoTrace() bool
}
ErrorTraceRemover may be implemented by an input type bound to a command in BindRunE for requesting that errors returned by the RunE function have their stack trace removed.
type FlagBond ¶
type FlagBond struct {
Name cmdFlag // name of the flag
Shorthand string // one letter shorthand or the empty string for none
Value interface{} // the default value (use zero value for no default)
Usage string // usage string : must not be empty
Required bool // true if the flag is required
Persistent bool // true: the flag is available to the command as well as every command under the command
Hidden bool // true to set the flag as hidden
ArgOrder int // for flags used to bind args
ArgsSlice bool // for flags used to bind slice args
CsvSlice bool // true for flags with comma separated string representation
Annotations []string // annotations found as 'meta' tag
// contains filtered or unexported fields
}
func (*FlagBond) HasAnnotation ¶ added in v1.0.3
func (*FlagBond) MarshalJSON ¶
func (*FlagBond) SetPersistent ¶
func (*FlagBond) SetRequired ¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package main provides an example of using bflags.BindRunE and how to silence errors or remove stack traces in error returned from the runE function.
|
Package main provides an example of using bflags.BindRunE and how to silence errors or remove stack traces in error returned from the runE function. |
|
Package main provides an example in how to use bflags.BindRunE
|
Package main provides an example in how to use bflags.BindRunE |