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

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