github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/util/cfg/cfg.go (about) 1 package cfg 2 3 import ( 4 "flag" 5 "reflect" 6 7 "github.com/grafana/dskit/flagext" 8 "github.com/pkg/errors" 9 ) 10 11 // Source is a generic configuration source. This function may do whatever is 12 // required to obtain the configuration. It is passed a pointer to the 13 // destination, which will be something compatible to `json.Unmarshal`. The 14 // obtained configuration may be written to this object, it may also contain 15 // data from previous sources. 16 type Source func(Cloneable) error 17 18 // Cloneable is a config which can be cloned into a flagext.Registerer 19 // Contract: the cloned value must not mutate the original. 20 type Cloneable interface { 21 Clone() flagext.Registerer 22 } 23 24 var ( 25 ErrNotPointer = errors.New("dst is not a pointer") 26 ) 27 28 // Unmarshal merges the values of the various configuration sources and sets them on 29 // `dst`. The object must be compatible with `json.Unmarshal`. 30 func Unmarshal(dst Cloneable, sources ...Source) error { 31 if len(sources) == 0 { 32 panic("No sources supplied to cfg.Unmarshal(). This is most likely a programming issue and should never happen. Check the code!") 33 } 34 if reflect.ValueOf(dst).Kind() != reflect.Ptr { 35 return ErrNotPointer 36 } 37 38 for _, source := range sources { 39 if err := source(dst); err != nil { 40 return err 41 } 42 } 43 return nil 44 } 45 46 // DefaultUnmarshal is a higher level wrapper for Unmarshal that automatically parses flags and a .yaml file 47 func DefaultUnmarshal(dst Cloneable, args []string, fs *flag.FlagSet) error { 48 return Unmarshal(dst, 49 Defaults(fs), 50 ConfigFileLoader(args, "config.file"), 51 Flags(args, fs), 52 ) 53 }