From a1eec53484bf5c875cf68ac5177597c248597ff6 Mon Sep 17 00:00:00 2001 From: Jay Date: Wed, 19 Feb 2020 09:19:49 +0000 Subject: [PATCH] add arg option 1. add default value 2. add description --- argparse.go | 98 +++++++++++++++++------------- argparse_test.go | 153 ++++++++++++++++++++++++++++------------------- example/main.go | 14 ++--- 3 files changed, 155 insertions(+), 110 deletions(-) diff --git a/argparse.go b/argparse.go index bb203b1..d75474d 100644 --- a/argparse.go +++ b/argparse.go @@ -22,11 +22,13 @@ type arg struct { sname string lname string // value item count - size int - value interface{} - unique bool - parsed bool - opts *Option + size int + value interface{} + defaultValue interface{} + description string + unique bool + parsed bool + opts *Option } func New() *Parser { @@ -46,7 +48,7 @@ func (p *Parser) addArg(a *arg) error { return nil } -func (p *Parser) typeVar(i interface{}, short, long string, size int, unique bool, opts *Option) { +func (p *Parser) typeVar(i interface{}, defVal interface{}, short, long, description string, size int, unique bool, opts *Option) { t := reflect.ValueOf(i) if t.Kind() != reflect.Ptr { panic(errors.New("var type not ptr")) @@ -56,12 +58,14 @@ func (p *Parser) typeVar(i interface{}, short, long string, size int, unique boo } a := &arg{ - sname: short, - lname: long, - value: i, - size: size, - unique: unique, - opts: opts, + sname: short, + lname: long, + value: i, + defaultValue: defVal, + description: description, + size: size, + unique: unique, + opts: opts, } if err := p.addArg(a); err != nil { @@ -70,14 +74,14 @@ func (p *Parser) typeVar(i interface{}, short, long string, size int, unique boo } func (p *Parser) Help(short, long string) { - p.typeVar(&p.showHelp, short, long, 0, true, nil) + p.typeVar(&p.showHelp, false, short, long, "show usage help", 0, true, nil) } func (p *Parser) printHelp() { sb := &strings.Builder{} sb.WriteString("Usage:\n") for _, v := range p.args { - if _, err := sb.WriteString(fmt.Sprintf("\t%s\t%s\n", v.name(), v.getType())); err != nil { + if _, err := sb.WriteString(fmt.Sprintf("\t%s\t%s\t\t%s\n", v.name(), v.getType(), v.description)); err != nil { panic(err) } } @@ -118,9 +122,19 @@ func (p *Parser) parse(args *[]string) error { p.printHelp() } + p.setDefaultValue() + return p.checkRequired() } +func (p *Parser) setDefaultValue() { + for _, v := range p.args { + if !v.parsed { + v.value = v.defaultValue + } + } +} + func (p *Parser) checkRequired() (err error) { for _, v := range p.args { if v.opts != nil && v.opts.Require && !v.parsed { @@ -169,79 +183,79 @@ func (p *Parser) parseArguemtns(args *[]string) error { return nil } -func (p *Parser) String(short, long string, opts *Option) *string { +func (p *Parser) String(defaultValue, short, long, description string, opts *Option) *string { var result string - p.typeVar(&result, short, long, 1, true, opts) + p.typeVar(&result, defaultValue, short, long, description, 1, true, opts) return &result } -func (p *Parser) StringVar(i *string, short, long string, opts *Option) { - p.typeVar(i, short, long, 1, true, opts) +func (p *Parser) StringVar(i *string, defaultValue, short, long, description string, opts *Option) { + p.typeVar(i, defaultValue, short, long, description, 1, true, opts) } -func (p *Parser) Int(short, long string, opts *Option) *int { +func (p *Parser) Int(defaultValue int, short, long, description string, opts *Option) *int { var result int - p.typeVar(&result, short, long, 1, true, opts) + p.typeVar(&result, defaultValue, short, long, description, 1, true, opts) return &result } -func (p *Parser) IntVar(i *int, short, long string, opts *Option) { - p.typeVar(i, short, long, 1, true, opts) +func (p *Parser) IntVar(i *int, defaultValue int, short, long, description string, opts *Option) { + p.typeVar(i, defaultValue, short, long, description, 1, true, opts) } -func (p *Parser) Bool(short, long string, opts *Option) *bool { +func (p *Parser) Bool(defaultValue bool, short, long, description string, opts *Option) *bool { var result bool - p.typeVar(&result, short, long, 0, true, opts) + p.typeVar(&result, defaultValue, short, long, description, 0, true, opts) return &result } -func (p *Parser) BoolVar(i *bool, short, long string, opts *Option) { - p.typeVar(i, short, long, 0, true, opts) +func (p *Parser) BoolVar(i *bool, defaultValue bool, short, long, description string, opts *Option) { + p.typeVar(i, defaultValue, short, long, description, 0, true, opts) } -func (p *Parser) Float(short, long string, opts *Option) *float64 { +func (p *Parser) Float(defaultValue float64, short, long, description string, opts *Option) *float64 { var result float64 - p.typeVar(&result, short, long, 1, true, opts) + p.typeVar(&result, defaultValue, short, long, description, 1, true, opts) return &result } -func (p *Parser) FloatVar(i *float64, short, long string, opts *Option) { - p.typeVar(i, short, long, 1, true, opts) +func (p *Parser) FloatVar(i *float64, defaultValue float64, short, long, description string, opts *Option) { + p.typeVar(i, defaultValue, short, long, description, 1, true, opts) } -func (p *Parser) StringSlice(short, long string, opts *Option) *[]string { +func (p *Parser) StringSlice(defaultValue []string, short, long, description string, opts *Option) *[]string { var result []string - p.typeVar(&result, short, long, 1, false, opts) + p.typeVar(&result, defaultValue, short, long, description, 1, false, opts) return &result } -func (p *Parser) StringSliceVar(i *[]string, short, long string, opts *Option) { - p.typeVar(i, short, long, 1, false, opts) +func (p *Parser) StringSliceVar(i *[]string, defaultValue []string, short, long, description string, opts *Option) { + p.typeVar(i, defaultValue, short, long, description, 1, false, opts) } -func (p *Parser) IntSlice(short, long string, opts *Option) *[]int { +func (p *Parser) IntSlice(defaultValue []int, short, long, description string, opts *Option) *[]int { var result []int - p.typeVar(&result, short, long, 1, false, opts) + p.typeVar(&result, defaultValue, short, long, description, 1, false, opts) return &result } -func (p *Parser) IntSliceVar(i *[]int, short, long string, opts *Option) { - p.typeVar(i, short, long, 1, false, opts) +func (p *Parser) IntSliceVar(i *[]int, defaultValue []int, short, long, description string, opts *Option) { + p.typeVar(i, defaultValue, short, long, description, 1, false, opts) } -func (p *Parser) FloatSlice(short, long string, opts *Option) *[]float64 { +func (p *Parser) FloatSlice(defaultValue []float64, short, long, description string, opts *Option) *[]float64 { var result []float64 - p.typeVar(&result, short, long, 1, false, opts) + p.typeVar(&result, defaultValue, short, long, description, 1, false, opts) return &result } -func (p *Parser) FloatSliceVar(i *[]float64, short, long string, opts *Option) { - p.typeVar(i, short, long, 1, false, opts) +func (p *Parser) FloatSliceVar(i *[]float64, defaultValue []float64, short, long, description string, opts *Option) { + p.typeVar(i, defaultValue, short, long, description, 1, false, opts) } diff --git a/argparse_test.go b/argparse_test.go index 2d659d0..f8ccd80 100644 --- a/argparse_test.go +++ b/argparse_test.go @@ -70,11 +70,13 @@ func TestParser_typeVar(t *testing.T) { parsed bool } type args struct { - i interface{} - short string - long string - size int - unique bool + i interface{} + defVal interface{} + short string + long string + description string + size int + unique bool } tests := []struct { name string @@ -86,6 +88,7 @@ func TestParser_typeVar(t *testing.T) { fields: fields{}, args: args{ i: &s, + defVal: "", short: "s", long: "string", size: 1, @@ -99,7 +102,7 @@ func TestParser_typeVar(t *testing.T) { args: tt.fields.args, parsed: tt.fields.parsed, } - p.typeVar(tt.args.i, tt.args.short, tt.args.long, tt.args.size, tt.args.unique, nil) + p.typeVar(tt.args.i, tt.args.defVal, tt.args.short, tt.args.long, tt.args.description, tt.args.size, tt.args.unique, nil) }) } } @@ -254,8 +257,10 @@ func TestParser_String(t *testing.T) { parsed bool } type args struct { - short string - long string + defValue string + short string + long string + desc string } tests := []struct { name string @@ -277,7 +282,7 @@ func TestParser_String(t *testing.T) { args: tt.fields.args, parsed: tt.fields.parsed, } - if got := p.String(tt.args.short, tt.args.long, nil); got == nil { + if got := p.String(tt.args.defValue, tt.args.short, tt.args.long, tt.args.desc, nil); got == nil { t.Errorf("Parser.String() = %v", got) } }) @@ -291,9 +296,11 @@ func TestParser_StringVar(t *testing.T) { parsed bool } type args struct { - i *string - short string - long string + i *string + defVal string + short string + long string + desc string } tests := []struct { name string @@ -316,7 +323,7 @@ func TestParser_StringVar(t *testing.T) { args: tt.fields.args, parsed: tt.fields.parsed, } - p.StringVar(tt.args.i, tt.args.short, tt.args.long, nil) + p.StringVar(tt.args.i, tt.args.defVal, tt.args.short, tt.args.long, tt.args.desc, nil) }) } } @@ -327,8 +334,10 @@ func TestParser_Int(t *testing.T) { parsed bool } type args struct { - short string - long string + defVal int + short string + long string + desc string } tests := []struct { name string @@ -350,7 +359,7 @@ func TestParser_Int(t *testing.T) { args: tt.fields.args, parsed: tt.fields.parsed, } - if got := p.Int(tt.args.short, tt.args.long, nil); got == nil { + if got := p.Int(tt.args.defVal, tt.args.short, tt.args.long, tt.args.desc, nil); got == nil { t.Errorf("Parser.Int() = %v", got) } }) @@ -364,9 +373,11 @@ func TestParser_IntVar(t *testing.T) { parsed bool } type args struct { - i *int - short string - long string + i *int + defVal int + short string + long string + desc string } tests := []struct { name string @@ -389,7 +400,7 @@ func TestParser_IntVar(t *testing.T) { args: tt.fields.args, parsed: tt.fields.parsed, } - p.IntVar(tt.args.i, tt.args.short, tt.args.long, nil) + p.IntVar(tt.args.i, tt.args.defVal, tt.args.short, tt.args.long, tt.args.desc, nil) }) } } @@ -400,8 +411,10 @@ func TestParser_Bool(t *testing.T) { parsed bool } type args struct { - short string - long string + defVal bool + short string + long string + desc string } tests := []struct { name string @@ -423,7 +436,7 @@ func TestParser_Bool(t *testing.T) { args: tt.fields.args, parsed: tt.fields.parsed, } - if got := p.Bool(tt.args.short, tt.args.long, nil); got == nil { + if got := p.Bool(tt.args.defVal, tt.args.short, tt.args.long, tt.args.desc, nil); got == nil { t.Errorf("Parser.Bool() = %v", got) } }) @@ -437,9 +450,11 @@ func TestParser_BoolVar(t *testing.T) { parsed bool } type args struct { - i *bool - short string - long string + i *bool + defVal bool + short string + long string + desc string } tests := []struct { name string @@ -462,7 +477,7 @@ func TestParser_BoolVar(t *testing.T) { args: tt.fields.args, parsed: tt.fields.parsed, } - p.BoolVar(tt.args.i, tt.args.short, tt.args.long, nil) + p.BoolVar(tt.args.i, tt.args.defVal, tt.args.short, tt.args.long, tt.args.desc, nil) }) } } @@ -473,8 +488,10 @@ func TestParser_Float(t *testing.T) { parsed bool } type args struct { - short string - long string + defVal float64 + short string + long string + desc string } tests := []struct { name string @@ -496,7 +513,7 @@ func TestParser_Float(t *testing.T) { args: tt.fields.args, parsed: tt.fields.parsed, } - if got := p.Float(tt.args.short, tt.args.long, nil); got == nil { + if got := p.Float(tt.args.defVal, tt.args.short, tt.args.long, tt.args.desc, nil); got == nil { t.Errorf("Parser.Float() = %v", got) } }) @@ -510,9 +527,11 @@ func TestParser_FloatVar(t *testing.T) { parsed bool } type args struct { - i *float64 - short string - long string + i *float64 + defVal float64 + short string + long string + desc string } tests := []struct { name string @@ -535,7 +554,7 @@ func TestParser_FloatVar(t *testing.T) { args: tt.fields.args, parsed: tt.fields.parsed, } - p.FloatVar(tt.args.i, tt.args.short, tt.args.long, nil) + p.FloatVar(tt.args.i, tt.args.defVal, tt.args.short, tt.args.long, tt.args.desc, nil) }) } } @@ -546,9 +565,11 @@ func TestParser_StringSlice(t *testing.T) { parsed bool } type args struct { - short string - long string - opts *Option + defVal []string + short string + long string + desc string + opts *Option } tests := []struct { name string @@ -571,7 +592,7 @@ func TestParser_StringSlice(t *testing.T) { args: tt.fields.args, parsed: tt.fields.parsed, } - if got := p.StringSlice(tt.args.short, tt.args.long, tt.args.opts); got == nil { + if got := p.StringSlice(tt.args.defVal, tt.args.short, tt.args.long, tt.args.desc, tt.args.opts); got == nil { t.Errorf("Parser.StringSlice() = %v", got) } }) @@ -585,10 +606,12 @@ func TestParser_StringSliceVar(t *testing.T) { parsed bool } type args struct { - i *[]string - short string - long string - opts *Option + i *[]string + defVal []string + short string + long string + desc string + opts *Option } tests := []struct { name string @@ -612,7 +635,7 @@ func TestParser_StringSliceVar(t *testing.T) { args: tt.fields.args, parsed: tt.fields.parsed, } - p.StringSliceVar(tt.args.i, tt.args.short, tt.args.long, tt.args.opts) + p.StringSliceVar(tt.args.i, tt.args.defVal, tt.args.short, tt.args.long, tt.args.desc, tt.args.opts) }) } } @@ -623,9 +646,11 @@ func TestParser_IntSlice(t *testing.T) { parsed bool } type args struct { - short string - long string - opts *Option + defVal []int + short string + long string + desc string + opts *Option } tests := []struct { name string @@ -648,7 +673,7 @@ func TestParser_IntSlice(t *testing.T) { args: tt.fields.args, parsed: tt.fields.parsed, } - if got := p.IntSlice(tt.args.short, tt.args.long, tt.args.opts); got == nil { + if got := p.IntSlice(tt.args.defVal, tt.args.short, tt.args.long, tt.args.desc, tt.args.opts); got == nil { t.Errorf("Parser.IntSlice() = %v", got) } }) @@ -662,10 +687,12 @@ func TestParser_IntSliceVar(t *testing.T) { parsed bool } type args struct { - i *[]int - short string - long string - opts *Option + i *[]int + defVal []int + short string + long string + desc string + opts *Option } tests := []struct { name string @@ -689,7 +716,7 @@ func TestParser_IntSliceVar(t *testing.T) { args: tt.fields.args, parsed: tt.fields.parsed, } - p.IntSliceVar(tt.args.i, tt.args.short, tt.args.long, tt.args.opts) + p.IntSliceVar(tt.args.i, tt.args.defVal, tt.args.short, tt.args.long, tt.args.desc, tt.args.opts) }) } } @@ -701,10 +728,12 @@ func TestParser_FloatSliceVar(t *testing.T) { parsed bool } type args struct { - i *[]float64 - short string - long string - opts *Option + i *[]float64 + defVal []float64 + short string + long string + desc string + opts *Option } tests := []struct { name string @@ -728,7 +757,7 @@ func TestParser_FloatSliceVar(t *testing.T) { args: tt.fields.args, parsed: tt.fields.parsed, } - p.FloatSliceVar(tt.args.i, tt.args.short, tt.args.long, tt.args.opts) + p.FloatSliceVar(tt.args.i, tt.args.defVal, tt.args.short, tt.args.long, tt.args.desc, tt.args.opts) }) } } @@ -739,9 +768,11 @@ func TestParser_FloatSlice(t *testing.T) { parsed bool } type args struct { - short string - long string - opts *Option + defVal []float64 + short string + long string + desc string + opts *Option } tests := []struct { name string @@ -764,7 +795,7 @@ func TestParser_FloatSlice(t *testing.T) { args: tt.fields.args, parsed: tt.fields.parsed, } - if got := p.FloatSlice(tt.args.short, tt.args.long, tt.args.opts); got == nil { + if got := p.FloatSlice(tt.args.defVal, tt.args.short, tt.args.long, tt.args.desc, tt.args.opts); got == nil { t.Errorf("Parser.FloatSlice() = %v", got) } }) diff --git a/example/main.go b/example/main.go index 5ccbda4..642dad6 100644 --- a/example/main.go +++ b/example/main.go @@ -31,16 +31,16 @@ func main() { var missReq int _ = missReq - p.BoolVar(&versionFlag, "v", "version", nil) - p.StringVar(&configPath, "f", "config", nil) - p.IntVar(&port, "p", "port", nil) - p.FloatVar(&floatVal, "ff", "float", nil) - p.StringSliceVar(&sarr, "i", "item", nil) + p.BoolVar(&versionFlag, false, "v", "version", "show version", nil) + p.StringVar(&configPath, "", "f", "config", "", nil) + p.IntVar(&port, 0, "p", "port", "http listen port", nil) + p.FloatVar(&floatVal, 1.2, "ff", "float", "float value", nil) + p.StringSliceVar(&sarr, []string{}, "i", "item", "item list", nil) // uncomment to test required arg missing - p.IntVar(&missReq, "m", "miss", &argparse.Option{Require: true}) + p.IntVar(&missReq, -1, "m", "miss", "require value", &argparse.Option{Require: true}) p.Help("h", "help") - name = p.String("n", "name", nil) + name = p.String("", "n", "name", "show name", nil) err := p.Parse(opts) if err != nil {