add arg option
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing

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
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)
}

View File

@ -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)
}
})

View File

@ -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 {