initial
This commit is contained in:
200
vendor/local/args/arg.go
vendored
Executable file
200
vendor/local/args/arg.go
vendored
Executable file
@@ -0,0 +1,200 @@
|
||||
package args
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Arg struct {
|
||||
Env string
|
||||
Flag string
|
||||
Help string
|
||||
Default interface{}
|
||||
Value interface{}
|
||||
ArgType Type
|
||||
}
|
||||
|
||||
func NewArg(argType Type, key, help string, def interface{}) *Arg {
|
||||
return &Arg{
|
||||
Env: strings.ToUpper(key),
|
||||
Flag: strings.ToLower(key),
|
||||
Help: help,
|
||||
Default: def,
|
||||
Value: def,
|
||||
ArgType: argType,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Arg) String() string {
|
||||
return fmt.Sprintf("[%s $%s/-%s, %v from %v, help %v]",
|
||||
a.ArgType,
|
||||
a.Env,
|
||||
a.Flag,
|
||||
a.Value,
|
||||
a.Default,
|
||||
a.Help,
|
||||
)
|
||||
}
|
||||
|
||||
func (a *Arg) GetInt() int {
|
||||
if a.ArgType != INT {
|
||||
return -1
|
||||
}
|
||||
if _, ok := a.Value.(int); !ok {
|
||||
return -1
|
||||
}
|
||||
return a.Value.(int)
|
||||
}
|
||||
|
||||
func (a *Arg) GetString() string {
|
||||
if a.ArgType != STRING {
|
||||
return ""
|
||||
}
|
||||
if _, ok := a.Value.(string); !ok {
|
||||
return ""
|
||||
}
|
||||
return a.Value.(string)
|
||||
}
|
||||
|
||||
func (a *Arg) GetBool() bool {
|
||||
if a.ArgType != BOOL {
|
||||
return false
|
||||
}
|
||||
if _, ok := a.Value.(bool); !ok {
|
||||
return false
|
||||
}
|
||||
return a.Value.(bool)
|
||||
}
|
||||
|
||||
func (a *Arg) GetDuration() time.Duration {
|
||||
if a.ArgType != DURATION {
|
||||
return time.Duration(-1)
|
||||
}
|
||||
if _, ok := a.Value.(time.Duration); !ok {
|
||||
return time.Duration(-1)
|
||||
}
|
||||
return a.Value.(time.Duration)
|
||||
}
|
||||
|
||||
func (a *Arg) GetTime() time.Time {
|
||||
if a.ArgType != TIME {
|
||||
return time.Date(1995, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
}
|
||||
if _, ok := a.Value.(time.Time); !ok {
|
||||
return time.Date(1995, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
}
|
||||
return a.Value.(time.Time)
|
||||
}
|
||||
|
||||
func (a *Arg) GetFloat() float32 {
|
||||
if a.ArgType != FLOAT {
|
||||
return float32(-1)
|
||||
}
|
||||
if _, ok := a.Value.(float32); !ok {
|
||||
return float32(-1)
|
||||
}
|
||||
return a.Value.(float32)
|
||||
}
|
||||
|
||||
func (a *Arg) Set(value interface{}) error {
|
||||
err := fmt.Errorf("incompatible set of type %T for arg $%v/-%v type %v", value, a.Env, a.Flag, a.ArgType)
|
||||
switch a.ArgType {
|
||||
case INT:
|
||||
switch value.(type) {
|
||||
case int:
|
||||
a.Value = value.(int)
|
||||
err = nil
|
||||
case string:
|
||||
s := value.(string)
|
||||
var i int
|
||||
if i, err = strconv.Atoi(s); err == nil {
|
||||
a.Value = i
|
||||
err = nil
|
||||
}
|
||||
case float64:
|
||||
f := value.(float64)
|
||||
if f-float64(int(f)) == 0 {
|
||||
a.Value = int(f)
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
case STRING:
|
||||
i, ok := value.(string)
|
||||
if ok {
|
||||
a.Value = i
|
||||
err = nil
|
||||
}
|
||||
case BOOL:
|
||||
i, ok := value.(bool)
|
||||
if ok {
|
||||
a.Value = i
|
||||
err = nil
|
||||
} else if s, ok := value.(string); !ok {
|
||||
} else if i, err = strconv.ParseBool(s); err == nil {
|
||||
a.Value = i
|
||||
err = nil
|
||||
}
|
||||
case DURATION:
|
||||
i, ok := value.(time.Duration)
|
||||
if ok {
|
||||
a.Value = i
|
||||
err = nil
|
||||
} else if s, ok := value.(string); !ok {
|
||||
} else if i, err = time.ParseDuration(s); err == nil {
|
||||
a.Value = i
|
||||
err = nil
|
||||
}
|
||||
case TIME:
|
||||
if i, ok := value.(time.Duration); ok {
|
||||
a.Value = time.Now().Add(i)
|
||||
err = nil
|
||||
} else if j, ok := value.(time.Time); ok {
|
||||
a.Value = j
|
||||
err = nil
|
||||
} else if s, ok := value.(string); !ok {
|
||||
} else if i, err = time.ParseDuration(s); err == nil {
|
||||
a.Value = time.Now().Add(i)
|
||||
err = nil
|
||||
} else {
|
||||
layouts := []string{
|
||||
"01-02-2006",
|
||||
"01/02/2006",
|
||||
"01-02-06",
|
||||
"01/02/06",
|
||||
"2006-01-02",
|
||||
"2006/01/02",
|
||||
"06-01-02",
|
||||
"06/01/02",
|
||||
"2006-01-02 15:04:05.999999999 -0700 MST",
|
||||
}
|
||||
for k := range layouts {
|
||||
if j, err = time.Parse(layouts[k], s); err == nil {
|
||||
a.Value = j
|
||||
err = nil
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
case FLOAT:
|
||||
if i, ok := value.(float32); ok {
|
||||
a.Value = i
|
||||
err = nil
|
||||
} else if j, ok := value.(float64); ok {
|
||||
a.Value = float32(j)
|
||||
err = nil
|
||||
} else if k, ok := value.(int); ok {
|
||||
a.Value = float32(k)
|
||||
err = nil
|
||||
} else if s, ok := value.(string); !ok {
|
||||
} else if j, err = strconv.ParseFloat(s, 32); err == nil {
|
||||
a.Value = float32(j)
|
||||
err = nil
|
||||
} else if k, err = strconv.Atoi(s); err == nil {
|
||||
a.Value = float32(k)
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
171
vendor/local/args/argset.go
vendored
Executable file
171
vendor/local/args/argset.go
vendored
Executable file
@@ -0,0 +1,171 @@
|
||||
package args
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type ArgSet struct {
|
||||
parsed bool
|
||||
args []*Arg
|
||||
configFiles []string
|
||||
}
|
||||
|
||||
func NewArgSet(configFiles ...string) *ArgSet {
|
||||
return &ArgSet{
|
||||
args: []*Arg{},
|
||||
configFiles: configFiles,
|
||||
}
|
||||
}
|
||||
|
||||
func (as *ArgSet) Append(argType Type, key, help string, def interface{}) {
|
||||
as.args = append(as.args, NewArg(argType, key, help, def))
|
||||
}
|
||||
|
||||
func (as *ArgSet) Get(key string) *Arg {
|
||||
if !as.parsed {
|
||||
return nil
|
||||
}
|
||||
for i := range as.args {
|
||||
if as.args[i].Env == key || as.args[i].Flag == key {
|
||||
return as.args[i]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (as *ArgSet) Parse() error {
|
||||
if as.parsed {
|
||||
return nil
|
||||
}
|
||||
defer func() {
|
||||
as.parsed = true
|
||||
}()
|
||||
|
||||
if err := as.setValueFromDefaults(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := as.setValueFromFiles(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := as.setValueFromEnv(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := as.setValueFromFlags(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (as *ArgSet) setValueFromDefaults() error {
|
||||
for i := range as.args {
|
||||
if err := as.args[i].Set(as.args[i].Default); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (as *ArgSet) setValueFromEnv() error {
|
||||
for i := range as.args {
|
||||
key := as.args[i].Env
|
||||
if v, ok := os.LookupEnv(key); ok {
|
||||
if err := as.args[i].Set(v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (as *ArgSet) setValueFromFlags() error {
|
||||
var err error
|
||||
fs := flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
|
||||
for i := range as.args {
|
||||
arg := as.args[i]
|
||||
switch arg.ArgType {
|
||||
case INT:
|
||||
arg.Default = fs.Int(arg.Flag, arg.Value.(int), arg.Help)
|
||||
case STRING:
|
||||
arg.Default = fs.String(arg.Flag, arg.Value.(string), arg.Help)
|
||||
case BOOL:
|
||||
arg.Default = fs.Bool(arg.Flag, arg.Value.(bool), arg.Help)
|
||||
case DURATION:
|
||||
arg.Default = fs.Duration(arg.Flag, arg.Value.(time.Duration), arg.Help)
|
||||
case TIME:
|
||||
arg.Default = fs.String(arg.Flag, arg.Value.(time.Time).Format("2006-01-02"), arg.Help)
|
||||
case FLOAT:
|
||||
arg.Default = fs.Float64(arg.Flag, float64(arg.Value.(float32)), arg.Help)
|
||||
default:
|
||||
return errors.New("unknown type, cannot set from flag")
|
||||
}
|
||||
}
|
||||
if err := fs.Parse(os.Args[1:]); err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range as.args {
|
||||
arg := as.args[i]
|
||||
switch arg.ArgType {
|
||||
case INT:
|
||||
arg.Value = *arg.Default.(*int)
|
||||
case STRING:
|
||||
arg.Value = *arg.Default.(*string)
|
||||
case BOOL:
|
||||
arg.Value = *arg.Default.(*bool)
|
||||
case DURATION:
|
||||
arg.Value = *arg.Default.(*time.Duration)
|
||||
case TIME:
|
||||
arg.Value = *arg.Default.(*string)
|
||||
err = arg.Set(arg.Value)
|
||||
case FLOAT:
|
||||
arg.Value = *arg.Default.(*float64)
|
||||
err = arg.Set(arg.Value)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (as *ArgSet) setValueFromFiles() error {
|
||||
for _, file := range as.configFiles {
|
||||
if err := as.setValueFromFile(file); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (as *ArgSet) setValueFromFile(path string) error {
|
||||
b, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var config map[string]interface{}
|
||||
if strings.HasSuffix(path, ".json") {
|
||||
err = json.Unmarshal(b, &config)
|
||||
} else if strings.HasSuffix(path, ".yaml") {
|
||||
err = yaml.Unmarshal(b, &config)
|
||||
} else {
|
||||
err = fmt.Errorf("unknown config file suffix: %s", path)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range as.args {
|
||||
key := as.args[i].Flag
|
||||
if v, ok := config[key]; ok {
|
||||
if err := as.args[i].Set(v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
36
vendor/local/args/type.go
vendored
Executable file
36
vendor/local/args/type.go
vendored
Executable file
@@ -0,0 +1,36 @@
|
||||
package args
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Type int
|
||||
|
||||
const (
|
||||
INT = Type(iota)
|
||||
STRING = Type(iota)
|
||||
BOOL = Type(iota)
|
||||
DURATION = Type(iota)
|
||||
TIME = Type(iota)
|
||||
FLOAT = Type(iota)
|
||||
)
|
||||
|
||||
func (t Type) String() string {
|
||||
var i interface{} = nil
|
||||
switch t {
|
||||
case INT:
|
||||
i = 1
|
||||
case STRING:
|
||||
i = ""
|
||||
case BOOL:
|
||||
i = false
|
||||
case DURATION:
|
||||
i = time.Duration(0)
|
||||
case TIME:
|
||||
i = time.Time{}
|
||||
case FLOAT:
|
||||
i = float32(0)
|
||||
}
|
||||
return fmt.Sprintf("%T", i)
|
||||
}
|
||||
Reference in New Issue
Block a user