diff --git a/argparse.go b/argparse.go index 1ecac29..d035ca4 100644 --- a/argparse.go +++ b/argparse.go @@ -191,12 +191,13 @@ func (o *Command) Flag(short string, long string, opts *Options) *bool { var result bool a := &arg{ - result: &result, - sname: short, - lname: long, - size: 1, - opts: opts, - unique: true, + result: &result, + sname: short, + lname: long, + size: 1, + opts: opts, + unique: true, + argType: Flag, } if err := o.addArg(a); err != nil { @@ -217,12 +218,13 @@ func (o *Command) FlagCounter(short string, long string, opts *Options) *int { var result int a := &arg{ - result: &result, - sname: short, - lname: long, - size: 1, - opts: opts, - unique: false, + result: &result, + sname: short, + lname: long, + size: 1, + opts: opts, + unique: false, + argType: FlagCounter, } if err := o.addArg(a); err != nil { @@ -239,12 +241,13 @@ func (o *Command) String(short string, long string, opts *Options) *string { var result string a := &arg{ - result: &result, - sname: short, - lname: long, - size: 2, - opts: opts, - unique: true, + result: &result, + sname: short, + lname: long, + size: 2, + opts: opts, + unique: true, + argType: String, } if err := o.addArg(a); err != nil { @@ -262,12 +265,13 @@ func (o *Command) Int(short string, long string, opts *Options) *int { var result int a := &arg{ - result: &result, - sname: short, - lname: long, - size: 2, - opts: opts, - unique: true, + result: &result, + sname: short, + lname: long, + size: 2, + opts: opts, + unique: true, + argType: Int, } if err := o.addArg(a); err != nil { @@ -285,12 +289,13 @@ func (o *Command) Float(short string, long string, opts *Options) *float64 { var result float64 a := &arg{ - result: &result, - sname: short, - lname: long, - size: 2, - opts: opts, - unique: true, + result: &result, + sname: short, + lname: long, + size: 2, + opts: opts, + unique: true, + argType: Float, } if err := o.addArg(a); err != nil { @@ -319,6 +324,7 @@ func (o *Command) File(short string, long string, flag int, perm os.FileMode, op unique: true, fileFlag: flag, filePerm: perm, + argType: File, } if err := o.addArg(a); err != nil { @@ -345,12 +351,13 @@ func (o *Command) StringList(short string, long string, opts *Options) *[]string result := make([]string, 0) a := &arg{ - result: &result, - sname: short, - lname: long, - size: 2, - opts: opts, - unique: false, + result: &result, + sname: short, + lname: long, + size: 2, + opts: opts, + unique: false, + argType: StringList, } if err := o.addArg(a); err != nil { @@ -368,12 +375,13 @@ func (o *Command) IntList(short string, long string, opts *Options) *[]int { result := make([]int, 0) a := &arg{ - result: &result, - sname: short, - lname: long, - size: 2, - opts: opts, - unique: false, + result: &result, + sname: short, + lname: long, + size: 2, + opts: opts, + unique: false, + argType: IntList, } if err := o.addArg(a); err != nil { @@ -391,12 +399,13 @@ func (o *Command) FloatList(short string, long string, opts *Options) *[]float64 result := make([]float64, 0) a := &arg{ - result: &result, - sname: short, - lname: long, - size: 2, - opts: opts, - unique: false, + result: &result, + sname: short, + lname: long, + size: 2, + opts: opts, + unique: false, + argType: FloatList, } if err := o.addArg(a); err != nil { @@ -422,6 +431,7 @@ func (o *Command) FileList(short string, long string, flag int, perm os.FileMode unique: false, fileFlag: flag, filePerm: perm, + argType: FileList, } if err := o.addArg(a); err != nil { @@ -448,6 +458,7 @@ func (o *Command) Selector(short string, long string, options []string, opts *Op opts: opts, unique: true, selector: &options, + argType: Selector, } if err := o.addArg(a); err != nil { diff --git a/argparse_test.go b/argparse_test.go index b247044..138517a 100644 --- a/argparse_test.go +++ b/argparse_test.go @@ -1986,7 +1986,7 @@ func TestFlagDefaultValuePass(t *testing.T) { p := NewParser("progname", "Prog description") - f := p.Flag("f", "flag", &Options{Default: true}) + f := p.Flag("f", "flag", &Options{Default: false}) err := p.Parse(testArgs) @@ -1995,24 +1995,29 @@ func TestFlagDefaultValuePass(t *testing.T) { t.Error(err.Error()) } - // Should fail if not true - if *f != true { - t.Errorf("expected [true], got [%t]", *f) + // Should fail if not false + if *f != false { + t.Errorf("expected [false] but found [%t]", *f) } } -func TestFlagDefaultValueFail(t *testing.T) { +func TestFlagDefaultValueShouldIgnoreTrue(t *testing.T) { testArgs := []string{"progname"} p := NewParser("progname", "Prog description") - _ = p.Flag("f", "flag", &Options{Default: "string"}) + f := p.Flag("f", "flag", &Options{Default: true}) err := p.Parse(testArgs) - // Should pass on failure - if err == nil || err.Error() != "cannot use default type [string] as value of pointer with type [*bool]" { - t.Errorf("Test %s failed: expected error [%s], got error [%+v]", t.Name(), "cannot use default type [string] as value of pointer with type [*bool]", err) + // Should fail on failure + if err != nil { + t.Error(err.Error()) + } + + // Should fail if not false + if *f != false { + t.Errorf("expected [false] but found [%t]", *f) } } @@ -2042,7 +2047,7 @@ func TestStringDefaultValueFail(t *testing.T) { p := NewParser("progname", "Prog description") - _ = p.String("s", "string", &Options{Default: false}) + _ = p.String("s", "string", &Options{Default: true}) err := p.Parse(testArgs) diff --git a/argument.go b/argument.go index 3bd7a74..2688839 100644 --- a/argument.go +++ b/argument.go @@ -9,20 +9,38 @@ import ( ) type arg struct { - result interface{} // Pointer to the resulting value - opts *Options // Options - sname string // Short name (in Parser will start with "-" - lname string // Long name (in Parser will start with "--" - size int // Size defines how many args after match will need to be consumed - unique bool // Specifies whether flag should be present only ones - parsed bool // Specifies whether flag has been parsed already - fileFlag int // File mode to open file with - filePerm os.FileMode // File permissions to set a file - selector *[]string // Used in Selector type to allow to choose only one from list of options - parent *Command // Used to get access to specific Command - eqChar bool // This is used if the command is passed in with an equals char as a seperator + result interface{} // Pointer to the resulting value + opts *Options // Options + sname string // Short name (in Parser will start with "-" + lname string // Long name (in Parser will start with "--" + size int // Size defines how many args after match will need to be consumed + unique bool // Specifies whether flag should be present only ones + parsed bool // Specifies whether flag has been parsed already + fileFlag int // File mode to open file with + filePerm os.FileMode // File permissions to set a file + selector *[]string // Used in Selector type to allow to choose only one from list of options + parent *Command // Used to get access to specific Command + eqChar bool // This is used if the command is passed in with an equals char as a seperator + argType ArgumentType // Used to determine which argument type this is } +// enum used to determine the argument type +type ArgumentType int + +const ( + Flag ArgumentType = 0 + FlagCounter = 1 + String = 2 + Int = 3 + Float = 4 + File = 5 + StringList = 6 + IntList = 7 + FloatList = 8 + FileList = 9 + Selector = 10 +) + // Arg interface provides exporting of arg structure, while exposing it type Arg interface { GetOpts() *Options @@ -506,7 +524,11 @@ func (o *arg) setDefault() error { if reflect.TypeOf(o.result) != reflect.PtrTo(reflect.TypeOf(o.opts.Default)) { return fmt.Errorf("cannot use default type [%T] as value of pointer with type [%T]", o.opts.Default, o.result) } - reflect.ValueOf(o.result).Elem().Set(reflect.ValueOf(o.opts.Default)) + defaultValue := o.opts.Default + if o.argType == Flag && defaultValue == true { + defaultValue = false + } + reflect.ValueOf(o.result).Elem().Set(reflect.ValueOf(defaultValue)) case *os.File: if err := o.setDefaultFile(); err != nil {