allow to pass additional options

Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
Василий Толстов 2022-04-01 15:24:56 +03:00
parent bac916794d
commit 4b7541ebaa
3 changed files with 69 additions and 3 deletions

39
flag.go
View File

@ -28,6 +28,7 @@ var (
*/ */
type flagConfig struct { type flagConfig struct {
fset *flag.FlagSet
opts config.Options opts config.Options
} }
@ -45,7 +46,7 @@ func (c *flagConfig) Init(opts ...config.Option) error {
return err return err
} }
flag.CommandLine.Init(os.Args[0], flag.ContinueOnError) // flag.CommandLine.Init(os.Args[0], flag.ContinueOnError)
for _, sf := range fields { for _, sf := range fields {
tf, ok := sf.Field.Tag.Lookup(c.opts.StructTag) tf, ok := sf.Field.Tag.Lookup(c.opts.StructTag)
if !ok { if !ok {
@ -65,6 +66,8 @@ func (c *flagConfig) Init(opts ...config.Option) error {
if f := flag.Lookup(fn); f != nil { if f := flag.Lookup(fn); f != nil {
return nil return nil
} }
fmt.Printf("register %s flag\n", fn)
switch vi.(type) { switch vi.(type) {
case time.Duration: case time.Duration:
err = c.flagDuration(sf.Value, fn, fv, fd) err = c.flagDuration(sf.Value, fn, fv, fd)
@ -151,5 +154,37 @@ func NewConfig(opts ...config.Option) config.Config {
if len(options.StructTag) == 0 { if len(options.StructTag) == 0 {
options.StructTag = DefaultStructTag options.StructTag = DefaultStructTag
} }
return &flagConfig{opts: options} flagSet := flag.CommandLine
flagSetName := os.Args[0]
flagSetErrorHandling := flag.ExitOnError
var flagUsage func()
var isSet bool
if options.Context != nil {
if v, ok := options.Context.Value(flagSetNameKey{}).(string); ok {
isSet = true
flagSetName = v
}
if v, ok := options.Context.Value(flagSetErrorHandlingKey{}).(flag.ErrorHandling); ok {
isSet = true
flagSetErrorHandling = v
}
if v, ok := options.Context.Value(flagSetKey{}).(*flag.FlagSet); ok {
flagSet = v
}
if v, ok := options.Context.Value(flagSetUsageKey{}).(func()); ok {
flagUsage = v
}
}
if isSet {
flagSet.Init(flagSetName, flagSetErrorHandling)
}
if flagUsage != nil {
flagSet.Usage = flagUsage
}
c := &flagConfig{opts: options, fset: flagSet}
return c
} }

View File

@ -2,6 +2,7 @@ package flag
import ( import (
"context" "context"
"flag"
"os" "os"
"testing" "testing"
"time" "time"
@ -40,7 +41,7 @@ func TestLoad(t *testing.T) {
ctx := context.Background() ctx := context.Background()
cfg := &Config{Nested: &NestedConfig{}} cfg := &Config{Nested: &NestedConfig{}}
c := NewConfig(config.Struct(cfg), TimeFormat(time.RFC822)) c := NewConfig(config.Struct(cfg), TimeFormat(time.RFC822), FlagErrorHandling(flag.ContinueOnError))
if err := c.Init(); err != nil { if err := c.Init(); err != nil {
t.Fatalf("init failed: %v", err) t.Fatalf("init failed: %v", err)
} }

View File

@ -1,6 +1,8 @@
package flag package flag
import ( import (
"flag"
"go.unistack.org/micro/v3/config" "go.unistack.org/micro/v3/config"
) )
@ -24,3 +26,31 @@ type timeFormatKey struct{}
func TimeFormat(s string) config.Option { func TimeFormat(s string) config.Option {
return config.SetOption(timeFormatKey{}, s) return config.SetOption(timeFormatKey{}, s)
} }
type flagSetKey struct{}
// FlagSet set flag set name
func FlagSet(f *flag.FlagSet) config.Option {
return config.SetOption(flagSetKey{}, f)
}
type flagSetNameKey struct{}
// FlagSetName set flag set name
func FlagSetName(n string) config.Option {
return config.SetOption(flagSetNameKey{}, n)
}
type flagSetErrorHandlingKey struct{}
// FlagErrorHandling set flag set error handling
func FlagErrorHandling(eh flag.ErrorHandling) config.Option {
return config.SetOption(flagSetErrorHandlingKey{}, eh)
}
type flagSetUsageKey struct{}
// FlagUsage set flag set usage func
func FlagUsage(fn func()) config.Option {
return config.SetOption(flagSetUsageKey{}, fn)
}