gitee.com/liuxuezhan/go-micro-v1.18.0@v1.0.0/config/source/flag/flag.go (about) 1 package flag 2 3 import ( 4 "errors" 5 "flag" 6 "github.com/imdario/mergo" 7 "gitee.com/liuxuezhan/go-micro-v1.18.0/config/source" 8 "strings" 9 "time" 10 ) 11 12 type flagsrc struct { 13 opts source.Options 14 } 15 16 func (fs *flagsrc) Read() (*source.ChangeSet, error) { 17 if !flag.Parsed() { 18 return nil, errors.New("flags not parsed") 19 } 20 21 var changes map[string]interface{} 22 23 visitFn := func(f *flag.Flag) { 24 n := strings.ToLower(f.Name) 25 keys := strings.FieldsFunc(n, split) 26 reverse(keys) 27 28 tmp := make(map[string]interface{}) 29 for i, k := range keys { 30 if i == 0 { 31 tmp[k] = f.Value 32 continue 33 } 34 35 tmp = map[string]interface{}{k: tmp} 36 } 37 38 mergo.Map(&changes, tmp) // need to sort error handling 39 return 40 } 41 42 unset, ok := fs.opts.Context.Value(includeUnsetKey{}).(bool) 43 if ok && unset { 44 flag.VisitAll(visitFn) 45 } else { 46 flag.Visit(visitFn) 47 } 48 49 b, err := fs.opts.Encoder.Encode(changes) 50 if err != nil { 51 return nil, err 52 } 53 54 cs := &source.ChangeSet{ 55 Format: fs.opts.Encoder.String(), 56 Data: b, 57 Timestamp: time.Now(), 58 Source: fs.String(), 59 } 60 cs.Checksum = cs.Sum() 61 62 return cs, nil 63 } 64 65 func split(r rune) bool { 66 return r == '-' || r == '_' 67 } 68 69 func reverse(ss []string) { 70 for i := len(ss)/2 - 1; i >= 0; i-- { 71 opp := len(ss) - 1 - i 72 ss[i], ss[opp] = ss[opp], ss[i] 73 } 74 } 75 76 func (fs *flagsrc) Watch() (source.Watcher, error) { 77 return source.NewNoopWatcher() 78 } 79 80 func (fs *flagsrc) String() string { 81 return "flag" 82 } 83 84 // NewSource returns a config source for integrating parsed flags. 85 // Hyphens are delimiters for nesting, and all keys are lowercased. 86 // 87 // Example: 88 // dbhost := flag.String("database-host", "localhost", "the db host name") 89 // 90 // { 91 // "database": { 92 // "host": "localhost" 93 // } 94 // } 95 func NewSource(opts ...source.Option) source.Source { 96 return &flagsrc{opts: source.NewOptions(opts...)} 97 }