github.com/micro/go-micro/v2@v2.9.1/config/source/flag/flag.go (about)

     1  package flag
     2  
     3  import (
     4  	"errors"
     5  	"flag"
     6  	"github.com/imdario/mergo"
     7  	"github.com/micro/go-micro/v2/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) Write(cs *source.ChangeSet) error {
    81  	return nil
    82  }
    83  
    84  func (fs *flagsrc) String() string {
    85  	return "flag"
    86  }
    87  
    88  // NewSource returns a config source for integrating parsed flags.
    89  // Hyphens are delimiters for nesting, and all keys are lowercased.
    90  //
    91  // Example:
    92  //      dbhost := flag.String("database-host", "localhost", "the db host name")
    93  //
    94  //      {
    95  //          "database": {
    96  //              "host": "localhost"
    97  //          }
    98  //      }
    99  func NewSource(opts ...source.Option) source.Source {
   100  	return &flagsrc{opts: source.NewOptions(opts...)}
   101  }