add arg option
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details

1. add default value
2. add description
This commit is contained in:
Jay 2020-02-19 09:19:49 +00:00
parent ccfa5d3cb0
commit a1eec53484
3 changed files with 155 additions and 110 deletions

View File

@ -22,11 +22,13 @@ type arg struct {
sname string sname string
lname string lname string
// value item count // value item count
size int size int
value interface{} value interface{}
unique bool defaultValue interface{}
parsed bool description string
opts *Option unique bool
parsed bool
opts *Option
} }
func New() *Parser { func New() *Parser {
@ -46,7 +48,7 @@ func (p *Parser) addArg(a *arg) error {
return nil 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) t := reflect.ValueOf(i)
if t.Kind() != reflect.Ptr { if t.Kind() != reflect.Ptr {
panic(errors.New("var type not 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{ a := &arg{
sname: short, sname: short,
lname: long, lname: long,
value: i, value: i,
size: size, defaultValue: defVal,
unique: unique, description: description,
opts: opts, size: size,
unique: unique,
opts: opts,
} }
if err := p.addArg(a); err != nil { 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) { 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() { func (p *Parser) printHelp() {
sb := &strings.Builder{} sb := &strings.Builder{}
sb.WriteString("Usage:\n") sb.WriteString("Usage:\n")
for _, v := range p.args { 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) panic(err)
} }
} }
@ -118,9 +122,19 @@ func (p *Parser) parse(args *[]string) error {
p.printHelp() p.printHelp()
} }
p.setDefaultValue()
return p.checkRequired() 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) { func (p *Parser) checkRequired() (err error) {
for _, v := range p.args { for _, v := range p.args {
if v.opts != nil && v.opts.Require && !v.parsed { if v.opts != nil && v.opts.Require && !v.parsed {
@ -169,79 +183,79 @@ func (p *Parser) parseArguemtns(args *[]string) error {
return nil 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 var result string
p.typeVar(&result, short, long, 1, true, opts) p.typeVar(&result, defaultValue, short, long, description, 1, true, opts)
return &result return &result
} }
func (p *Parser) StringVar(i *string, short, long string, opts *Option) { func (p *Parser) StringVar(i *string, defaultValue, short, long, description string, opts *Option) {
p.typeVar(i, short, long, 1, true, opts) 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 var result int
p.typeVar(&result, short, long, 1, true, opts) p.typeVar(&result, defaultValue, short, long, description, 1, true, opts)
return &result return &result
} }
func (p *Parser) IntVar(i *int, short, long string, opts *Option) { func (p *Parser) IntVar(i *int, defaultValue int, short, long, description string, opts *Option) {
p.typeVar(i, short, long, 1, true, opts) 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 var result bool
p.typeVar(&result, short, long, 0, true, opts) p.typeVar(&result, defaultValue, short, long, description, 0, true, opts)
return &result return &result
} }
func (p *Parser) BoolVar(i *bool, short, long string, opts *Option) { func (p *Parser) BoolVar(i *bool, defaultValue bool, short, long, description string, opts *Option) {
p.typeVar(i, short, long, 0, true, opts) 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 var result float64
p.typeVar(&result, short, long, 1, true, opts) p.typeVar(&result, defaultValue, short, long, description, 1, true, opts)
return &result return &result
} }
func (p *Parser) FloatVar(i *float64, short, long string, opts *Option) { func (p *Parser) FloatVar(i *float64, defaultValue float64, short, long, description string, opts *Option) {
p.typeVar(i, short, long, 1, true, opts) 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 var result []string
p.typeVar(&result, short, long, 1, false, opts) p.typeVar(&result, defaultValue, short, long, description, 1, false, opts)
return &result return &result
} }
func (p *Parser) StringSliceVar(i *[]string, short, long string, opts *Option) { func (p *Parser) StringSliceVar(i *[]string, defaultValue []string, short, long, description string, opts *Option) {
p.typeVar(i, short, long, 1, false, opts) 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 var result []int
p.typeVar(&result, short, long, 1, false, opts) p.typeVar(&result, defaultValue, short, long, description, 1, false, opts)
return &result return &result
} }
func (p *Parser) IntSliceVar(i *[]int, short, long string, opts *Option) { func (p *Parser) IntSliceVar(i *[]int, defaultValue []int, short, long, description string, opts *Option) {
p.typeVar(i, short, long, 1, false, opts) 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 var result []float64
p.typeVar(&result, short, long, 1, false, opts) p.typeVar(&result, defaultValue, short, long, description, 1, false, opts)
return &result return &result
} }
func (p *Parser) FloatSliceVar(i *[]float64, short, long string, opts *Option) { func (p *Parser) FloatSliceVar(i *[]float64, defaultValue []float64, short, long, description string, opts *Option) {
p.typeVar(i, short, long, 1, false, opts) p.typeVar(i, defaultValue, short, long, description, 1, false, opts)
} }

View File

@ -70,11 +70,13 @@ func TestParser_typeVar(t *testing.T) {
parsed bool parsed bool
} }
type args struct { type args struct {
i interface{} i interface{}
short string defVal interface{}
long string short string
size int long string
unique bool description string
size int
unique bool
} }
tests := []struct { tests := []struct {
name string name string
@ -86,6 +88,7 @@ func TestParser_typeVar(t *testing.T) {
fields: fields{}, fields: fields{},
args: args{ args: args{
i: &s, i: &s,
defVal: "",
short: "s", short: "s",
long: "string", long: "string",
size: 1, size: 1,
@ -99,7 +102,7 @@ func TestParser_typeVar(t *testing.T) {
args: tt.fields.args, args: tt.fields.args,
parsed: tt.fields.parsed, 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 parsed bool
} }
type args struct { type args struct {
short string defValue string
long string short string
long string
desc string
} }
tests := []struct { tests := []struct {
name string name string
@ -277,7 +282,7 @@ func TestParser_String(t *testing.T) {
args: tt.fields.args, args: tt.fields.args,
parsed: tt.fields.parsed, 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) t.Errorf("Parser.String() = %v", got)
} }
}) })
@ -291,9 +296,11 @@ func TestParser_StringVar(t *testing.T) {
parsed bool parsed bool
} }
type args struct { type args struct {
i *string i *string
short string defVal string
long string short string
long string
desc string
} }
tests := []struct { tests := []struct {
name string name string
@ -316,7 +323,7 @@ func TestParser_StringVar(t *testing.T) {
args: tt.fields.args, args: tt.fields.args,
parsed: tt.fields.parsed, 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 parsed bool
} }
type args struct { type args struct {
short string defVal int
long string short string
long string
desc string
} }
tests := []struct { tests := []struct {
name string name string
@ -350,7 +359,7 @@ func TestParser_Int(t *testing.T) {
args: tt.fields.args, args: tt.fields.args,
parsed: tt.fields.parsed, 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) t.Errorf("Parser.Int() = %v", got)
} }
}) })
@ -364,9 +373,11 @@ func TestParser_IntVar(t *testing.T) {
parsed bool parsed bool
} }
type args struct { type args struct {
i *int i *int
short string defVal int
long string short string
long string
desc string
} }
tests := []struct { tests := []struct {
name string name string
@ -389,7 +400,7 @@ func TestParser_IntVar(t *testing.T) {
args: tt.fields.args, args: tt.fields.args,
parsed: tt.fields.parsed, 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 parsed bool
} }
type args struct { type args struct {
short string defVal bool
long string short string
long string
desc string
} }
tests := []struct { tests := []struct {
name string name string
@ -423,7 +436,7 @@ func TestParser_Bool(t *testing.T) {
args: tt.fields.args, args: tt.fields.args,
parsed: tt.fields.parsed, 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) t.Errorf("Parser.Bool() = %v", got)
} }
}) })
@ -437,9 +450,11 @@ func TestParser_BoolVar(t *testing.T) {
parsed bool parsed bool
} }
type args struct { type args struct {
i *bool i *bool
short string defVal bool
long string short string
long string
desc string
} }
tests := []struct { tests := []struct {
name string name string
@ -462,7 +477,7 @@ func TestParser_BoolVar(t *testing.T) {
args: tt.fields.args, args: tt.fields.args,
parsed: tt.fields.parsed, 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 parsed bool
} }
type args struct { type args struct {
short string defVal float64
long string short string
long string
desc string
} }
tests := []struct { tests := []struct {
name string name string
@ -496,7 +513,7 @@ func TestParser_Float(t *testing.T) {
args: tt.fields.args, args: tt.fields.args,
parsed: tt.fields.parsed, 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) t.Errorf("Parser.Float() = %v", got)
} }
}) })
@ -510,9 +527,11 @@ func TestParser_FloatVar(t *testing.T) {
parsed bool parsed bool
} }
type args struct { type args struct {
i *float64 i *float64
short string defVal float64
long string short string
long string
desc string
} }
tests := []struct { tests := []struct {
name string name string
@ -535,7 +554,7 @@ func TestParser_FloatVar(t *testing.T) {
args: tt.fields.args, args: tt.fields.args,
parsed: tt.fields.parsed, 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 parsed bool
} }
type args struct { type args struct {
short string defVal []string
long string short string
opts *Option long string
desc string
opts *Option
} }
tests := []struct { tests := []struct {
name string name string
@ -571,7 +592,7 @@ func TestParser_StringSlice(t *testing.T) {
args: tt.fields.args, args: tt.fields.args,
parsed: tt.fields.parsed, 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) t.Errorf("Parser.StringSlice() = %v", got)
} }
}) })
@ -585,10 +606,12 @@ func TestParser_StringSliceVar(t *testing.T) {
parsed bool parsed bool
} }
type args struct { type args struct {
i *[]string i *[]string
short string defVal []string
long string short string
opts *Option long string
desc string
opts *Option
} }
tests := []struct { tests := []struct {
name string name string
@ -612,7 +635,7 @@ func TestParser_StringSliceVar(t *testing.T) {
args: tt.fields.args, args: tt.fields.args,
parsed: tt.fields.parsed, 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 parsed bool
} }
type args struct { type args struct {
short string defVal []int
long string short string
opts *Option long string
desc string
opts *Option
} }
tests := []struct { tests := []struct {
name string name string
@ -648,7 +673,7 @@ func TestParser_IntSlice(t *testing.T) {
args: tt.fields.args, args: tt.fields.args,
parsed: tt.fields.parsed, 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) t.Errorf("Parser.IntSlice() = %v", got)
} }
}) })
@ -662,10 +687,12 @@ func TestParser_IntSliceVar(t *testing.T) {
parsed bool parsed bool
} }
type args struct { type args struct {
i *[]int i *[]int
short string defVal []int
long string short string
opts *Option long string
desc string
opts *Option
} }
tests := []struct { tests := []struct {
name string name string
@ -689,7 +716,7 @@ func TestParser_IntSliceVar(t *testing.T) {
args: tt.fields.args, args: tt.fields.args,
parsed: tt.fields.parsed, 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 parsed bool
} }
type args struct { type args struct {
i *[]float64 i *[]float64
short string defVal []float64
long string short string
opts *Option long string
desc string
opts *Option
} }
tests := []struct { tests := []struct {
name string name string
@ -728,7 +757,7 @@ func TestParser_FloatSliceVar(t *testing.T) {
args: tt.fields.args, args: tt.fields.args,
parsed: tt.fields.parsed, 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 parsed bool
} }
type args struct { type args struct {
short string defVal []float64
long string short string
opts *Option long string
desc string
opts *Option
} }
tests := []struct { tests := []struct {
name string name string
@ -764,7 +795,7 @@ func TestParser_FloatSlice(t *testing.T) {
args: tt.fields.args, args: tt.fields.args,
parsed: tt.fields.parsed, 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) t.Errorf("Parser.FloatSlice() = %v", got)
} }
}) })

View File

@ -31,16 +31,16 @@ func main() {
var missReq int var missReq int
_ = missReq _ = missReq
p.BoolVar(&versionFlag, "v", "version", nil) p.BoolVar(&versionFlag, false, "v", "version", "show version", nil)
p.StringVar(&configPath, "f", "config", nil) p.StringVar(&configPath, "", "f", "config", "", nil)
p.IntVar(&port, "p", "port", nil) p.IntVar(&port, 0, "p", "port", "http listen port", nil)
p.FloatVar(&floatVal, "ff", "float", nil) p.FloatVar(&floatVal, 1.2, "ff", "float", "float value", nil)
p.StringSliceVar(&sarr, "i", "item", nil) p.StringSliceVar(&sarr, []string{}, "i", "item", "item list", nil)
// uncomment to test required arg missing // 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") p.Help("h", "help")
name = p.String("n", "name", nil) name = p.String("", "n", "name", "show name", nil)
err := p.Parse(opts) err := p.Parse(opts)
if err != nil { if err != nil {