Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding custom validation for any type of flag's value #374

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,25 @@ independent sets of flags, such as to implement subcommands
in a command-line interface. The methods of FlagSet are
analogous to the top-level functions for the command-line
flag set.
## Adding custom validation for flags

You can also add custom validation for validating the flag's value.

It is optional and for this operation, you should define a function and pass it as the last parameter to the flag definition function.

```go
var flagvar int
func init() {
validation := func(value int) error {
if value <= 4 {
return errors.New("int value should be greater than 4")
}
}
flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname", validation)
}
````

In the above example if you pass an integer value greater than 4, it returned an error and the value of the flag doesn't set.

## Setting no option default values for flags

Expand Down
44 changes: 29 additions & 15 deletions bool.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package pflag

import "strconv"
import (
"strconv"
)

// optional interface to indicate boolean flags that can be
// supplied without "=value" text
Expand Down Expand Up @@ -46,49 +48,61 @@ func (f *FlagSet) GetBool(name string) (bool, error) {

// 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 (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
f.BoolVarP(p, name, "", value, usage)
func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string, validation ...func(value bool) error) {
f.BoolVarP(p, name, "", value, usage, validation...)
}

// BoolVarP is like BoolVar, but accepts a shorthand letter that can be used after a single dash.
func (f *FlagSet) BoolVarP(p *bool, name, shorthand string, value bool, usage string) {
func (f *FlagSet) BoolVarP(p *bool, name, shorthand string, value bool, usage string, validation ...func(value bool) error) {
if len(validation) > 0 {
validationFunc := (interface{})(validation[0])
flag := f.VarPF(newBoolValue(value, p), name, shorthand, usage, validationFunc)
flag.NoOptDefVal = "true"
return
}
flag := f.VarPF(newBoolValue(value, p), name, shorthand, usage)
flag.NoOptDefVal = "true"
}

// 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 BoolVar(p *bool, name string, value bool, usage string) {
BoolVarP(p, name, "", value, usage)
func BoolVar(p *bool, name string, value bool, usage string, validation ...func(value bool) error) {
BoolVarP(p, name, "", value, usage, validation...)
}

// BoolVarP is like BoolVar, but accepts a shorthand letter that can be used after a single dash.
func BoolVarP(p *bool, name, shorthand string, value bool, usage string) {
func BoolVarP(p *bool, name, shorthand string, value bool, usage string, validation ...func(value bool) error) {
if len(validation) > 0 {
validationFunc := interface{}(validation[0]).(func(value interface{}) error)
flag := CommandLine.VarPF(newBoolValue(value, p), name, shorthand, usage, validationFunc)
flag.NoOptDefVal = "true"
return
}
flag := CommandLine.VarPF(newBoolValue(value, p), name, shorthand, usage)
flag.NoOptDefVal = "true"
}

// 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 (f *FlagSet) Bool(name string, value bool, usage string) *bool {
return f.BoolP(name, "", value, usage)
func (f *FlagSet) Bool(name string, value bool, usage string, validation ...func(value bool) error) *bool {
return f.BoolP(name, "", value, usage, validation...)
}

// BoolP is like Bool, but accepts a shorthand letter that can be used after a single dash.
func (f *FlagSet) BoolP(name, shorthand string, value bool, usage string) *bool {
func (f *FlagSet) BoolP(name, shorthand string, value bool, usage string, validation ...func(value bool) error) *bool {
p := new(bool)
f.BoolVarP(p, name, shorthand, value, usage)
f.BoolVarP(p, name, shorthand, value, usage, validation...)
return p
}

// 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 Bool(name string, value bool, usage string) *bool {
return BoolP(name, "", value, usage)
func Bool(name string, value bool, usage string, validation ...func(value bool) error) *bool {
return BoolP(name, "", value, usage, validation...)
}

// BoolP is like Bool, but accepts a shorthand letter that can be used after a single dash.
func BoolP(name, shorthand string, value bool, usage string) *bool {
b := CommandLine.BoolP(name, shorthand, value, usage)
func BoolP(name, shorthand string, value bool, usage string, validation ...func(value bool) error) *bool {
b := CommandLine.BoolP(name, shorthand, value, usage, validation...)
return b
}
44 changes: 32 additions & 12 deletions bool_slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,48 +138,68 @@ func (f *FlagSet) GetBoolSlice(name string) ([]bool, error) {

// BoolSliceVar defines a boolSlice 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 (f *FlagSet) BoolSliceVar(p *[]bool, name string, value []bool, usage string) {
func (f *FlagSet) BoolSliceVar(p *[]bool, name string, value []bool, usage string, validation ...func(value []bool) error) {
if len(validation) > 0 {
validationFunc := interface{}(validation[0])
f.VarP(newBoolSliceValue(value, p), name, "", usage, validationFunc)
return
}
f.VarP(newBoolSliceValue(value, p), name, "", usage)
}

// BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash.
func (f *FlagSet) BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) {
func (f *FlagSet) BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string, validation ...func(value []bool) error) {
if len(validation) > 0 {
validationFunc := interface{}(validation[0])
f.VarP(newBoolSliceValue(value, p), name, shorthand, usage, validationFunc)
return
}
f.VarP(newBoolSliceValue(value, p), name, shorthand, usage)
}

// BoolSliceVar 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 BoolSliceVar(p *[]bool, name string, value []bool, usage string) {
func BoolSliceVar(p *[]bool, name string, value []bool, usage string, validation ...func(value []bool) error) {
if len(validation) > 0 {
validationFunc := interface{}(validation[0])
CommandLine.VarP(newBoolSliceValue(value, p), name, "", usage, validationFunc)
return
}
CommandLine.VarP(newBoolSliceValue(value, p), name, "", usage)
}

// BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash.
func BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) {
func BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string, validation ...func(value []bool) error) {
if len(validation) > 0 {
validationFunc := interface{}(validation[0])
CommandLine.VarP(newBoolSliceValue(value, p), name, shorthand, usage, validationFunc)
return
}
CommandLine.VarP(newBoolSliceValue(value, p), name, shorthand, usage)
}

// BoolSlice 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 (f *FlagSet) BoolSlice(name string, value []bool, usage string) *[]bool {
func (f *FlagSet) BoolSlice(name string, value []bool, usage string, validation ...func(value []bool) error) *[]bool {
p := []bool{}
f.BoolSliceVarP(&p, name, "", value, usage)
f.BoolSliceVarP(&p, name, "", value, usage, validation...)
return &p
}

// BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash.
func (f *FlagSet) BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool {
func (f *FlagSet) BoolSliceP(name, shorthand string, value []bool, usage string, validation ...func(value []bool) error) *[]bool {
p := []bool{}
f.BoolSliceVarP(&p, name, shorthand, value, usage)
f.BoolSliceVarP(&p, name, shorthand, value, usage, validation...)
return &p
}

// BoolSlice 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 BoolSlice(name string, value []bool, usage string) *[]bool {
return CommandLine.BoolSliceP(name, "", value, usage)
func BoolSlice(name string, value []bool, usage string, validation ...func(value []bool) error) *[]bool {
return CommandLine.BoolSliceP(name, "", value, usage, validation...)
}

// BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash.
func BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool {
return CommandLine.BoolSliceP(name, shorthand, value, usage)
func BoolSliceP(name, shorthand string, value []bool, usage string, validation ...func(value []bool) error) *[]bool {
return CommandLine.BoolSliceP(name, shorthand, value, usage, validation...)
}
84 changes: 60 additions & 24 deletions bytes.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,50 +62,70 @@ func (f *FlagSet) GetBytesHex(name string) ([]byte, error) {

// BytesHexVar defines an []byte flag with specified name, default value, and usage string.
// The argument p points to an []byte variable in which to store the value of the flag.
func (f *FlagSet) BytesHexVar(p *[]byte, name string, value []byte, usage string) {
func (f *FlagSet) BytesHexVar(p *[]byte, name string, value []byte, usage string, validation ...func(value []byte) error) {
if len(validation) > 0 {
validationFunc := interface{}(validation[0])
f.VarP(newBytesHexValue(value, p), name, "", usage, validationFunc)
return
}
f.VarP(newBytesHexValue(value, p), name, "", usage)
}

// BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash.
func (f *FlagSet) BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) {
func (f *FlagSet) BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string, validation ...func(value []byte) error) {
if len(validation) > 0 {
validationFunc := interface{}(validation[0])
f.VarP(newBytesHexValue(value, p), name, shorthand, usage, validationFunc)
return
}
f.VarP(newBytesHexValue(value, p), name, shorthand, usage)
}

// BytesHexVar defines an []byte flag with specified name, default value, and usage string.
// The argument p points to an []byte variable in which to store the value of the flag.
func BytesHexVar(p *[]byte, name string, value []byte, usage string) {
func BytesHexVar(p *[]byte, name string, value []byte, usage string, validation ...func(value []byte) error) {
if len(validation) > 0 {
validationFunc := interface{}(validation[0])
CommandLine.VarP(newBytesHexValue(value, p), name, "", usage, validationFunc)
return
}
CommandLine.VarP(newBytesHexValue(value, p), name, "", usage)
}

// BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash.
func BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) {
func BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string, validation ...func(value []byte) error) {
if len(validation) > 0 {
validationFunc := interface{}(validation[0])
CommandLine.VarP(newBytesHexValue(value, p), name, shorthand, usage, validationFunc)
return
}
CommandLine.VarP(newBytesHexValue(value, p), name, shorthand, usage)
}

// BytesHex defines an []byte flag with specified name, default value, and usage string.
// The return value is the address of an []byte variable that stores the value of the flag.
func (f *FlagSet) BytesHex(name string, value []byte, usage string) *[]byte {
func (f *FlagSet) BytesHex(name string, value []byte, usage string, validation ...func(value []byte) error) *[]byte {
p := new([]byte)
f.BytesHexVarP(p, name, "", value, usage)
f.BytesHexVarP(p, name, "", value, usage, validation...)
return p
}

// BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash.
func (f *FlagSet) BytesHexP(name, shorthand string, value []byte, usage string) *[]byte {
func (f *FlagSet) BytesHexP(name, shorthand string, value []byte, usage string, validation ...func(value []byte) error) *[]byte {
p := new([]byte)
f.BytesHexVarP(p, name, shorthand, value, usage)
f.BytesHexVarP(p, name, shorthand, value, usage, validation...)
return p
}

// BytesHex defines an []byte flag with specified name, default value, and usage string.
// The return value is the address of an []byte variable that stores the value of the flag.
func BytesHex(name string, value []byte, usage string) *[]byte {
return CommandLine.BytesHexP(name, "", value, usage)
func BytesHex(name string, value []byte, usage string, validation ...func(value []byte) error) *[]byte {
return CommandLine.BytesHexP(name, "", value, usage, validation...)
}

// BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash.
func BytesHexP(name, shorthand string, value []byte, usage string) *[]byte {
return CommandLine.BytesHexP(name, shorthand, value, usage)
func BytesHexP(name, shorthand string, value []byte, usage string, validation ...func(value []byte) error) *[]byte {
return CommandLine.BytesHexP(name, shorthand, value, usage, validation...)
}

// BytesBase64 adapts []byte for use as a flag. Value of flag is Base64 encoded
Expand Down Expand Up @@ -162,48 +182,64 @@ func (f *FlagSet) GetBytesBase64(name string) ([]byte, error) {

// BytesBase64Var defines an []byte flag with specified name, default value, and usage string.
// The argument p points to an []byte variable in which to store the value of the flag.
func (f *FlagSet) BytesBase64Var(p *[]byte, name string, value []byte, usage string) {
func (f *FlagSet) BytesBase64Var(p *[]byte, name string, value []byte, usage string, validation ...func(value []byte) error) {
if len(validation) > 0 {
validationFunc := interface{}(validation[0]).(func(value interface{}) error)
f.VarP(newBytesBase64Value(value, p), name, "", usage, validationFunc)
}
f.VarP(newBytesBase64Value(value, p), name, "", usage)
}

// BytesBase64VarP is like BytesBase64Var, but accepts a shorthand letter that can be used after a single dash.
func (f *FlagSet) BytesBase64VarP(p *[]byte, name, shorthand string, value []byte, usage string) {
func (f *FlagSet) BytesBase64VarP(p *[]byte, name, shorthand string, value []byte, usage string, validation ...func(value []byte) error) {
if len(validation) > 0 {
validationFunc := interface{}(validation[0]).(func(value interface{}) error)
f.VarP(newBytesBase64Value(value, p), name, shorthand, usage, validationFunc)
}
f.VarP(newBytesBase64Value(value, p), name, shorthand, usage)
}

// BytesBase64Var defines an []byte flag with specified name, default value, and usage string.
// The argument p points to an []byte variable in which to store the value of the flag.
func BytesBase64Var(p *[]byte, name string, value []byte, usage string) {
func BytesBase64Var(p *[]byte, name string, value []byte, usage string, validation ...func(value []byte) error) {
if len(validation) > 0 {
validationFunc := interface{}(validation[0]).(func(value interface{}) error)
CommandLine.VarP(newBytesBase64Value(value, p), name, "", usage, validationFunc)
}
CommandLine.VarP(newBytesBase64Value(value, p), name, "", usage)
}

// BytesBase64VarP is like BytesBase64Var, but accepts a shorthand letter that can be used after a single dash.
func BytesBase64VarP(p *[]byte, name, shorthand string, value []byte, usage string) {
func BytesBase64VarP(p *[]byte, name, shorthand string, value []byte, usage string, validation ...func(value []byte) error) {
if len(validation) > 0 {
validationFunc := interface{}(validation[0]).(func(value interface{}) error)
CommandLine.VarP(newBytesBase64Value(value, p), name, shorthand, usage, validationFunc)
}
CommandLine.VarP(newBytesBase64Value(value, p), name, shorthand, usage)
}

// BytesBase64 defines an []byte flag with specified name, default value, and usage string.
// The return value is the address of an []byte variable that stores the value of the flag.
func (f *FlagSet) BytesBase64(name string, value []byte, usage string) *[]byte {
func (f *FlagSet) BytesBase64(name string, value []byte, usage string, validation ...func(value []byte) error) *[]byte {
p := new([]byte)
f.BytesBase64VarP(p, name, "", value, usage)
f.BytesBase64VarP(p, name, "", value, usage, validation...)
return p
}

// BytesBase64P is like BytesBase64, but accepts a shorthand letter that can be used after a single dash.
func (f *FlagSet) BytesBase64P(name, shorthand string, value []byte, usage string) *[]byte {
func (f *FlagSet) BytesBase64P(name, shorthand string, value []byte, usage string, validation ...func(value []byte) error) *[]byte {
p := new([]byte)
f.BytesBase64VarP(p, name, shorthand, value, usage)
f.BytesBase64VarP(p, name, shorthand, value, usage, validation...)
return p
}

// BytesBase64 defines an []byte flag with specified name, default value, and usage string.
// The return value is the address of an []byte variable that stores the value of the flag.
func BytesBase64(name string, value []byte, usage string) *[]byte {
return CommandLine.BytesBase64P(name, "", value, usage)
func BytesBase64(name string, value []byte, usage string, validation ...func(value []byte) error) *[]byte {
return CommandLine.BytesBase64P(name, "", value, usage, validation...)
}

// BytesBase64P is like BytesBase64, but accepts a shorthand letter that can be used after a single dash.
func BytesBase64P(name, shorthand string, value []byte, usage string) *[]byte {
return CommandLine.BytesBase64P(name, shorthand, value, usage)
func BytesBase64P(name, shorthand string, value []byte, usage string, validation ...func(value []byte) error) *[]byte {
return CommandLine.BytesBase64P(name, shorthand, value, usage, validation...)
}
Loading