add arg option
1. add default value 2. add description
This commit is contained in:
parent
ccfa5d3cb0
commit
a1eec53484
76
argparse.go
76
argparse.go
@ -24,6 +24,8 @@ type arg struct {
|
||||
// value item count
|
||||
size int
|
||||
value interface{}
|
||||
defaultValue interface{}
|
||||
description string
|
||||
unique bool
|
||||
parsed bool
|
||||
opts *Option
|
||||
@ -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"))
|
||||
@ -59,6 +61,8 @@ func (p *Parser) typeVar(i interface{}, short, long string, size int, unique boo
|
||||
sname: short,
|
||||
lname: long,
|
||||
value: i,
|
||||
defaultValue: defVal,
|
||||
description: description,
|
||||
size: size,
|
||||
unique: unique,
|
||||
opts: opts,
|
||||
@ -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)
|
||||
}
|
||||
|
@ -71,8 +71,10 @@ func TestParser_typeVar(t *testing.T) {
|
||||
}
|
||||
type args struct {
|
||||
i interface{}
|
||||
defVal interface{}
|
||||
short string
|
||||
long string
|
||||
description string
|
||||
size int
|
||||
unique bool
|
||||
}
|
||||
@ -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 {
|
||||
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)
|
||||
}
|
||||
})
|
||||
@ -292,8 +297,10 @@ func TestParser_StringVar(t *testing.T) {
|
||||
}
|
||||
type args struct {
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
})
|
||||
@ -365,8 +374,10 @@ func TestParser_IntVar(t *testing.T) {
|
||||
}
|
||||
type args struct {
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
})
|
||||
@ -438,8 +451,10 @@ func TestParser_BoolVar(t *testing.T) {
|
||||
}
|
||||
type args struct {
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
})
|
||||
@ -511,8 +528,10 @@ func TestParser_FloatVar(t *testing.T) {
|
||||
}
|
||||
type args struct {
|
||||
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,8 +565,10 @@ func TestParser_StringSlice(t *testing.T) {
|
||||
parsed bool
|
||||
}
|
||||
type args struct {
|
||||
defVal []string
|
||||
short string
|
||||
long string
|
||||
desc string
|
||||
opts *Option
|
||||
}
|
||||
tests := []struct {
|
||||
@ -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)
|
||||
}
|
||||
})
|
||||
@ -586,8 +607,10 @@ func TestParser_StringSliceVar(t *testing.T) {
|
||||
}
|
||||
type args struct {
|
||||
i *[]string
|
||||
defVal []string
|
||||
short string
|
||||
long string
|
||||
desc string
|
||||
opts *Option
|
||||
}
|
||||
tests := []struct {
|
||||
@ -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,8 +646,10 @@ func TestParser_IntSlice(t *testing.T) {
|
||||
parsed bool
|
||||
}
|
||||
type args struct {
|
||||
defVal []int
|
||||
short string
|
||||
long string
|
||||
desc string
|
||||
opts *Option
|
||||
}
|
||||
tests := []struct {
|
||||
@ -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)
|
||||
}
|
||||
})
|
||||
@ -663,8 +688,10 @@ func TestParser_IntSliceVar(t *testing.T) {
|
||||
}
|
||||
type args struct {
|
||||
i *[]int
|
||||
defVal []int
|
||||
short string
|
||||
long string
|
||||
desc string
|
||||
opts *Option
|
||||
}
|
||||
tests := []struct {
|
||||
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -702,8 +729,10 @@ func TestParser_FloatSliceVar(t *testing.T) {
|
||||
}
|
||||
type args struct {
|
||||
i *[]float64
|
||||
defVal []float64
|
||||
short string
|
||||
long string
|
||||
desc string
|
||||
opts *Option
|
||||
}
|
||||
tests := []struct {
|
||||
@ -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,8 +768,10 @@ func TestParser_FloatSlice(t *testing.T) {
|
||||
parsed bool
|
||||
}
|
||||
type args struct {
|
||||
defVal []float64
|
||||
short string
|
||||
long string
|
||||
desc string
|
||||
opts *Option
|
||||
}
|
||||
tests := []struct {
|
||||
@ -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)
|
||||
}
|
||||
})
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user