77 lines
1.8 KiB
Go
77 lines
1.8 KiB
Go
package flags
|
||
|
||
import (
|
||
"flag"
|
||
"fmt"
|
||
"os"
|
||
"reflect"
|
||
"strconv"
|
||
"unsafe"
|
||
)
|
||
|
||
// ParseWithStructPointers 启动参数解析,如果启动参数没有指定,会去env里查找同名参数
|
||
// flagStructPointers为结构体指针数组
|
||
func ParseWithStructPointers(flagStructPointers ...interface{}) {
|
||
|
||
for _, st := range flagStructPointers {
|
||
flagParseStruct2Flags(st)
|
||
}
|
||
|
||
flag.Parse()
|
||
}
|
||
|
||
func flagParseStruct2Flags(st interface{}) {
|
||
if st == nil {
|
||
return
|
||
}
|
||
|
||
var stTo = reflect.TypeOf(st)
|
||
var stVo = reflect.ValueOf(st)
|
||
switch stTo.Kind() {
|
||
case reflect.Ptr:
|
||
stTo = stTo.Elem()
|
||
stVo = stVo.Elem()
|
||
// case reflect.Struct:
|
||
// break
|
||
default:
|
||
panic(fmt.Errorf("invalid flags parse struct(%+v), must be pointer or struct", st))
|
||
}
|
||
|
||
for i := 0; i < stTo.NumField(); i++ {
|
||
field := stTo.Field(i)
|
||
|
||
key, find := field.Tag.Lookup("env")
|
||
if !find {
|
||
continue
|
||
}
|
||
|
||
desc := field.Tag.Get("desc")
|
||
|
||
defaultValue, find := os.LookupEnv(key)
|
||
if !find {
|
||
defaultValue, find = field.Tag.Lookup("default")
|
||
if !find {
|
||
defaultValue = ""
|
||
}
|
||
}
|
||
|
||
var fieldValuePointer = unsafe.Pointer(stVo.Field(i).Addr().Pointer())
|
||
switch field.Type.Kind() {
|
||
case reflect.String:
|
||
flag.StringVar((*string)(fieldValuePointer), key, defaultValue, desc)
|
||
case reflect.Int:
|
||
defaultValue1, _ := strconv.Atoi(defaultValue)
|
||
flag.IntVar((*int)(fieldValuePointer), key, defaultValue1, desc)
|
||
case reflect.Int64:
|
||
defaultValue1, _ := strconv.ParseInt(defaultValue, 10, 64)
|
||
flag.Int64Var((*int64)(fieldValuePointer), key, defaultValue1, desc)
|
||
case reflect.Bool:
|
||
flag.BoolVar((*bool)(fieldValuePointer), key, defaultValue == "true", desc)
|
||
default:
|
||
panic(fmt.Errorf("parse flag kind invalid,must be string/int/int64/bool, not %+v", field.Type.Kind()))
|
||
}
|
||
}
|
||
|
||
return
|
||
}
|