1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package viper
21
22 import (
23 "bytes"
24 "encoding/csv"
25 "encoding/json"
26 "errors"
27 "fmt"
28 "io"
29 "log"
30 "os"
31 "path/filepath"
32 "reflect"
33 "strings"
34 "sync"
35 "time"
36
37 "github.com/dgraph-io/ristretto"
38
39 "github.com/fsnotify/fsnotify"
40 "github.com/hashicorp/hcl"
41 "github.com/hashicorp/hcl/hcl/printer"
42 "github.com/magiconair/properties"
43 "github.com/mitchellh/mapstructure"
44 "github.com/pelletier/go-toml"
45 "github.com/spf13/afero"
46 "github.com/spf13/cast"
47 jww "github.com/spf13/jwalterweatherman"
48 "github.com/spf13/pflag"
49 "github.com/subosito/gotenv"
50 "gopkg.in/ini.v1"
51 "gopkg.in/yaml.v2"
52 )
53
54
55 type ConfigMarshalError struct {
56 err error
57 }
58
59
60 func (e ConfigMarshalError) Error() string {
61 return fmt.Sprintf("While marshaling config: %s", e.err.Error())
62 }
63
64 var v *Viper
65
66 type RemoteResponse struct {
67 Value []byte
68 Error error
69 }
70
71 func init() {
72 v = New()
73 }
74
75 type remoteConfigFactory interface {
76 Get(rp RemoteProvider) (io.Reader, error)
77 Watch(rp RemoteProvider) (io.Reader, error)
78 WatchChannel(rp RemoteProvider) (<-chan *RemoteResponse, chan bool)
79 }
80
81
82 var RemoteConfig remoteConfigFactory
83
84
85
86 type UnsupportedConfigError string
87
88
89 func (str UnsupportedConfigError) Error() string {
90 return fmt.Sprintf("Unsupported Config Type %q", string(str))
91 }
92
93
94
95 type UnsupportedRemoteProviderError string
96
97
98 func (str UnsupportedRemoteProviderError) Error() string {
99 return fmt.Sprintf("Unsupported Remote Provider Type %q", string(str))
100 }
101
102
103
104 type RemoteConfigError string
105
106
107 func (rce RemoteConfigError) Error() string {
108 return fmt.Sprintf("Remote Configurations Error: %s", string(rce))
109 }
110
111
112 type ConfigFileNotFoundError struct {
113 name, locations string
114 }
115
116
117 func (fnfe ConfigFileNotFoundError) Error() string {
118 return fmt.Sprintf("Config File %q Not Found in %q", fnfe.name, fnfe.locations)
119 }
120
121
122 type ConfigFileAlreadyExistsError string
123
124
125 func (faee ConfigFileAlreadyExistsError) Error() string {
126 return fmt.Sprintf("Config File %q Already Exists", string(faee))
127 }
128
129
130
131 type DecoderConfigOption func(*mapstructure.DecoderConfig)
132
133
134
135
136
137
138
139
140 func DecodeHook(hook mapstructure.DecodeHookFunc) DecoderConfigOption {
141 return func(c *mapstructure.DecoderConfig) {
142 c.DecodeHook = hook
143 }
144 }
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180 type Viper struct {
181
182
183 keyDelim string
184
185
186 configPaths []string
187
188
189 fs afero.Fs
190
191
192 remoteProviders []*defaultRemoteProvider
193
194
195 configName string
196 configFile string
197 configType string
198 configPermissions os.FileMode
199 configChangedAt time.Time
200 envPrefix string
201
202 automaticEnvApplied bool
203 envKeyReplacer StringReplacer
204 allowEmptyEnv bool
205
206 config map[string]interface{}
207 override map[string]interface{}
208 defaults map[string]interface{}
209 types map[string]interface{}
210 kvstore map[string]interface{}
211 pflags map[string]FlagValue
212 env map[string]string
213 aliases map[string]string
214 typeByDefValue bool
215
216 previousValues map[string]interface{}
217
218
219
220 properties *properties.Properties
221
222 onConfigChange func(fsnotify.Event)
223
224 cache *ristretto.Cache
225 cacheMaxCost int64
226
227 lock *sync.RWMutex
228 }
229
230
231 func New() *Viper {
232 v := new(Viper)
233 v.keyDelim = "."
234 v.configName = "config"
235 v.configChangedAt = time.Now()
236 v.configPermissions = os.FileMode(0644)
237 v.fs = afero.NewOsFs()
238 v.config = make(map[string]interface{})
239 v.override = make(map[string]interface{})
240 v.defaults = make(map[string]interface{})
241 v.types = make(map[string]interface{})
242 v.kvstore = make(map[string]interface{})
243 v.previousValues = make(map[string]interface{})
244 v.pflags = make(map[string]FlagValue)
245 v.env = make(map[string]string)
246 v.aliases = make(map[string]string)
247 v.typeByDefValue = false
248
249 v.lock = new(sync.RWMutex)
250
251 var err error
252 v.cacheMaxCost = 1 << 20
253 v.cache, err = ristretto.NewCache(&ristretto.Config{
254 NumCounters: 1000,
255 MaxCost: 1 << 20,
256 BufferItems: 64,
257 })
258 if err != nil {
259
260
261
262
263
264 panic(fmt.Sprintf("cache options are invalid because: %s", err))
265 }
266
267 return v
268 }
269
270
271
272
273
274 type Option interface {
275 apply(v *Viper)
276 }
277
278 type optionFunc func(v *Viper)
279
280 func (fn optionFunc) apply(v *Viper) {
281 fn(v)
282 }
283
284
285
286 func KeyDelimiter(d string) Option {
287 return optionFunc(func(v *Viper) {
288 v.keyDelim = d
289 })
290 }
291
292
293 type StringReplacer interface {
294
295 Replace(s string) string
296 }
297
298
299 func EnvKeyReplacer(r StringReplacer) Option {
300 return optionFunc(func(v *Viper) {
301 v.envKeyReplacer = r
302 })
303 }
304
305
306
307 func Cache(c *ristretto.Cache, cf *ristretto.Config) Option {
308 return optionFunc(func(v *Viper) {
309 v.cache = c
310 v.cacheMaxCost = cf.MaxCost
311 })
312 }
313
314
315 func NewWithOptions(opts ...Option) *Viper {
316 v := New()
317
318 for _, opt := range opts {
319 opt.apply(v)
320 }
321
322 return v
323 }
324
325
326
327
328 func Reset() {
329 v = New()
330 SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "dotenv", "env", "ini"}
331 SupportedRemoteProviders = []string{"etcd", "consul", "firestore"}
332 }
333
334 type defaultRemoteProvider struct {
335 provider string
336 endpoint string
337 path string
338 secretKeyring string
339 }
340
341 func (rp defaultRemoteProvider) Provider() string {
342 return rp.provider
343 }
344
345 func (rp defaultRemoteProvider) Endpoint() string {
346 return rp.endpoint
347 }
348
349 func (rp defaultRemoteProvider) Path() string {
350 return rp.path
351 }
352
353 func (rp defaultRemoteProvider) SecretKeyring() string {
354 return rp.secretKeyring
355 }
356
357
358
359
360
361 type RemoteProvider interface {
362 Provider() string
363 Endpoint() string
364 Path() string
365 SecretKeyring() string
366 }
367
368
369 var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "dotenv", "env", "ini"}
370
371
372 var SupportedRemoteProviders = []string{"etcd", "consul", "firestore"}
373
374 func OnConfigChange(run func(in fsnotify.Event)) { v.OnConfigChange(run) }
375 func (v *Viper) OnConfigChange(run func(in fsnotify.Event)) {
376 v.onConfigChange = run
377 }
378
379 func WatchConfig() { v.WatchConfig() }
380
381 func (v *Viper) WatchConfig() {
382 initWG := sync.WaitGroup{}
383 initWG.Add(1)
384 go func() {
385 watcher, err := fsnotify.NewWatcher()
386 if err != nil {
387 log.Fatal(err)
388 }
389 defer watcher.Close()
390
391 filename, err := v.getConfigFile()
392 if err != nil {
393 log.Printf("error: %v\n", err)
394 initWG.Done()
395 return
396 }
397
398 configFile := filepath.Clean(filename)
399 configDir, _ := filepath.Split(configFile)
400 realConfigFile, _ := filepath.EvalSymlinks(filename)
401
402 eventsWG := sync.WaitGroup{}
403 eventsWG.Add(1)
404 go func() {
405 for {
406 select {
407 case event, ok := <-watcher.Events:
408 if !ok {
409 eventsWG.Done()
410 return
411 }
412 currentConfigFile, _ := filepath.EvalSymlinks(filename)
413
414
415
416 const writeOrCreateMask = fsnotify.Write | fsnotify.Create
417 if (filepath.Clean(event.Name) == configFile &&
418 event.Op&writeOrCreateMask != 0) ||
419 (currentConfigFile != "" && currentConfigFile != realConfigFile) {
420 realConfigFile = currentConfigFile
421 err := v.ReadInConfig()
422 if err != nil {
423 log.Printf("error reading config file: %v\n", err)
424 }
425 if v.onConfigChange != nil {
426 v.onConfigChange(event)
427 }
428 } else if filepath.Clean(event.Name) == configFile &&
429 event.Op&fsnotify.Remove&fsnotify.Remove != 0 {
430 eventsWG.Done()
431 return
432 }
433
434 case err, ok := <-watcher.Errors:
435 if ok {
436 log.Printf("watcher error: %v\n", err)
437 }
438 eventsWG.Done()
439 return
440 }
441 }
442 }()
443 watcher.Add(configDir)
444 initWG.Done()
445 eventsWG.Wait()
446 }()
447 initWG.Wait()
448 }
449
450
451
452 func SetConfigFile(in string) { v.SetConfigFile(in) }
453 func (v *Viper) SetConfigFile(in string) {
454 if in != "" {
455 v.lock.Lock()
456 v.configFile = in
457 v.lock.Unlock()
458 }
459 }
460
461
462
463
464 func SetEnvPrefix(in string) { v.SetEnvPrefix(in) }
465 func (v *Viper) SetEnvPrefix(in string) {
466 if in != "" {
467 v.lock.Lock()
468 v.cache.Clear()
469 v.envPrefix = in
470 v.lock.Unlock()
471 }
472 }
473
474 func (v *Viper) mergeWithEnvPrefix(in string) string {
475 if v.envPrefix != "" {
476 return strings.ToUpper(v.envPrefix + "_" + in)
477 }
478
479 return strings.ToUpper(in)
480 }
481
482
483
484
485 func AllowEmptyEnv(allowEmptyEnv bool) { v.AllowEmptyEnv(allowEmptyEnv) }
486 func (v *Viper) AllowEmptyEnv(allowEmptyEnv bool) {
487 v.lock.Lock()
488 v.cache.Clear()
489 v.allowEmptyEnv = allowEmptyEnv
490 v.lock.Unlock()
491 }
492
493
494
495
496
497
498
499
500 func (v *Viper) getEnv(key string) (string, bool) {
501 if v.envKeyReplacer != nil {
502 key = v.envKeyReplacer.Replace(key)
503 }
504
505 val, ok := os.LookupEnv(key)
506
507 return val, ok && (v.allowEmptyEnv || val != "")
508 }
509
510
511 func ConfigFileUsed() string { return v.ConfigFileUsed() }
512 func (v *Viper) ConfigFileUsed() string {
513 v.lock.RLock()
514 defer v.lock.RUnlock()
515
516 return v.configFile
517 }
518
519
520 func ConfigChangeAt() time.Time { return v.ConfigChangeAt() }
521 func (v *Viper) ConfigChangeAt() time.Time {
522 v.lock.RLock()
523 defer v.lock.RUnlock()
524
525 return v.configChangedAt
526 }
527
528
529
530 func AddConfigPath(in string) { v.AddConfigPath(in) }
531 func (v *Viper) AddConfigPath(in string) {
532 if in != "" {
533 absin := absPathify(in)
534 jww.INFO.Println("adding", absin, "to paths to search")
535 v.lock.Lock()
536 if !stringInSlice(absin, v.configPaths) {
537 v.cache.Clear()
538 v.configPaths = append(v.configPaths, absin)
539 }
540 v.lock.Unlock()
541 }
542 }
543
544
545
546
547
548
549
550
551
552 func AddRemoteProvider(provider, endpoint, path string) error {
553 return v.AddRemoteProvider(provider, endpoint, path)
554 }
555 func (v *Viper) AddRemoteProvider(provider, endpoint, path string) error {
556 if !stringInSlice(provider, SupportedRemoteProviders) {
557 return UnsupportedRemoteProviderError(provider)
558 }
559 if provider != "" && endpoint != "" {
560 jww.INFO.Printf("adding %s:%s to remote provider list", provider, endpoint)
561 rp := &defaultRemoteProvider{
562 endpoint: endpoint,
563 provider: provider,
564 path: path,
565 }
566 if !v.providerPathExists(rp) {
567 v.lock.Lock()
568 v.cache.Clear()
569 v.remoteProviders = append(v.remoteProviders, rp)
570 v.lock.Unlock()
571 }
572 }
573 return nil
574 }
575
576
577
578
579
580
581
582
583
584
585
586 func AddSecureRemoteProvider(provider, endpoint, path, secretkeyring string) error {
587 return v.AddSecureRemoteProvider(provider, endpoint, path, secretkeyring)
588 }
589
590 func (v *Viper) AddSecureRemoteProvider(provider, endpoint, path, secretkeyring string) error {
591 if !stringInSlice(provider, SupportedRemoteProviders) {
592 return UnsupportedRemoteProviderError(provider)
593 }
594 if provider != "" && endpoint != "" {
595 jww.INFO.Printf("adding %s:%s to remote provider list", provider, endpoint)
596 rp := &defaultRemoteProvider{
597 endpoint: endpoint,
598 provider: provider,
599 path: path,
600 secretKeyring: secretkeyring,
601 }
602 if !v.providerPathExists(rp) {
603 v.lock.Lock()
604 v.cache.Clear()
605 v.remoteProviders = append(v.remoteProviders, rp)
606 v.lock.Unlock()
607 }
608 }
609 return nil
610 }
611
612 func (v *Viper) providerPathExists(p *defaultRemoteProvider) bool {
613 v.lock.RLock()
614 defer v.lock.RUnlock()
615 for _, y := range v.remoteProviders {
616 if reflect.DeepEqual(y, p) {
617 return true
618 }
619 }
620 return false
621 }
622
623
624
625
626 func (v *Viper) searchMap(source map[string]interface{}, path []string) interface{} {
627 if len(path) == 0 {
628 return source
629 }
630
631 next, ok := source[path[0]]
632 if ok {
633
634 if len(path) == 1 {
635 return next
636 }
637
638
639 switch next.(type) {
640 case map[interface{}]interface{}:
641 return v.searchMap(cast.ToStringMap(next), path[1:])
642 case map[string]interface{}:
643
644
645 return v.searchMap(next.(map[string]interface{}), path[1:])
646 default:
647
648 return nil
649 }
650 }
651 return nil
652 }
653
654
655
656
657
658
659
660
661
662
663
664
665 func (v *Viper) searchMapWithPathPrefixes(source map[string]interface{}, path []string) interface{} {
666 if len(path) == 0 {
667 return source
668 }
669
670
671 for i := len(path); i > 0; i-- {
672 prefixKey := strings.ToLower(strings.Join(path[0:i], v.keyDelim))
673
674 next, ok := source[prefixKey]
675 if ok {
676
677 if i == len(path) {
678 return next
679 }
680
681
682 var val interface{}
683 switch next.(type) {
684 case map[interface{}]interface{}:
685 val = v.searchMapWithPathPrefixes(cast.ToStringMap(next), path[i:])
686 case map[string]interface{}:
687
688
689 val = v.searchMapWithPathPrefixes(next.(map[string]interface{}), path[i:])
690 default:
691
692 }
693 if val != nil {
694 return val
695 }
696 }
697 }
698
699
700 return nil
701 }
702
703
704
705
706
707 func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{}) string {
708 var parentVal interface{}
709 for i := 1; i < len(path); i++ {
710 parentVal = v.searchMap(m, path[0:i])
711 if parentVal == nil {
712
713 return ""
714 }
715 switch parentVal.(type) {
716 case map[interface{}]interface{}:
717 continue
718 case map[string]interface{}:
719 continue
720 default:
721
722 return strings.Join(path[0:i], v.keyDelim)
723 }
724 }
725 return ""
726 }
727
728
729
730
731
732 func (v *Viper) isPathShadowedInFlatMap(path []string, mi interface{}) string {
733
734 var m map[string]interface{}
735 switch mi.(type) {
736 case map[string]string, map[string]FlagValue:
737 m = cast.ToStringMap(mi)
738 default:
739 return ""
740 }
741
742
743 var parentKey string
744 for i := 1; i < len(path); i++ {
745 parentKey = strings.Join(path[0:i], v.keyDelim)
746 if _, ok := m[parentKey]; ok {
747 return parentKey
748 }
749 }
750 return ""
751 }
752
753
754
755
756
757 func (v *Viper) isPathShadowedInAutoEnv(path []string) string {
758 var parentKey string
759 for i := 1; i < len(path); i++ {
760 parentKey = strings.Join(path[0:i], v.keyDelim)
761 if _, ok := v.getEnv(v.mergeWithEnvPrefix(parentKey)); ok {
762 return parentKey
763 }
764 }
765 return ""
766 }
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782 func SetTypeByDefaultValue(enable bool) { v.SetTypeByDefaultValue(enable) }
783 func (v *Viper) SetTypeByDefaultValue(enable bool) {
784 v.lock.Lock()
785 v.cache.Clear()
786 v.typeByDefValue = enable
787 v.lock.Unlock()
788 }
789
790
791 func GetViper() *Viper {
792 return v
793 }
794
795
796
797
798
799 func HasChanged(key string) bool { return v.HasChanged(key) }
800 func (v *Viper) HasChanged(key string) bool {
801 lcaseKey := strings.ToLower(key)
802
803 v.lock.RLock()
804 value, ok := v.previousValues[lcaseKey]
805 v.lock.RUnlock()
806 if !ok {
807 return IsSet(key)
808 }
809
810
811 return !reflect.DeepEqual(value, v.find(lcaseKey, true))
812 }
813
814
815
816
817
818 func HasChangedSinceInit(key string) bool { return v.HasChangedSinceInit(key) }
819 func (v *Viper) HasChangedSinceInit(key string) bool {
820 lcaseKey := strings.ToLower(key)
821
822 v.lock.RLock()
823 value, ok := v.previousValues[lcaseKey]
824 v.lock.RUnlock()
825 if !ok {
826 return false
827 }
828
829
830 return !reflect.DeepEqual(value, v.find(lcaseKey, true))
831 }
832
833 func castAllSourcesE(t, val interface{}) (interface{}, error) {
834 switch t.(type) {
835 case time.Time:
836 return cast.ToTimeE(val)
837 case time.Duration:
838 return cast.ToDurationE(val)
839 }
840
841 return val, nil
842 }
843
844 func castStringSourcesE(t interface{}, val string) (interface{}, error) {
845 switch t.(type) {
846 case bool:
847 return cast.ToBoolE(val)
848 case string:
849 return val, nil
850 case int32, int16, int8, int:
851 return cast.ToIntE(val)
852 case uint:
853 return cast.ToUintE(val)
854 case uint32:
855 return cast.ToUint32E(val)
856 case uint64:
857 return cast.ToUint64E(val)
858 case int64:
859 return cast.ToInt64E(val)
860 case float64, float32:
861 return cast.ToFloat64E(val)
862 case []string:
863 s := strings.TrimPrefix(val, "[")
864 s = strings.TrimSuffix(s, "]")
865 res, err := readAsCSV(s)
866 if err != nil {
867 return []string{}, err
868 }
869 return res, nil
870 case []int:
871 s := strings.TrimPrefix(val, "[")
872 s = strings.TrimSuffix(s, "]")
873 res, err := readAsCSV(s)
874 if err != nil {
875 return []int{}, err
876 }
877 return cast.ToIntSliceE(res)
878 }
879
880 return castAllSourcesE(t, val)
881 }
882
883 func (v *Viper) getType(lcaseKey string) interface{} {
884 v.lock.RLock()
885 defer v.lock.RUnlock()
886
887 path := strings.Split(lcaseKey, v.keyDelim)
888
889 if typeVal := v.searchMap(v.types, path); typeVal != nil {
890 return typeVal
891 } else if v.typeByDefValue {
892 return v.searchMap(v.defaults, path)
893 }
894 return nil
895 }
896
897
898
899
900
901
902
903
904 func GetE(key string) (interface{}, error) { return v.GetE(key) }
905 func (v *Viper) GetE(key string) (interface{}, error) {
906 lcaseKey := strings.ToLower(key)
907
908 val, err := v.cachedFindE(lcaseKey, true)
909 if err != nil {
910 return val, err
911 }
912
913 v.lock.Lock()
914 v.previousValues[lcaseKey] = val
915 v.lock.Unlock()
916
917 return val, nil
918 }
919 func Get(key string) interface{} { return v.Get(key) }
920 func (v *Viper) Get(key string) interface{} {
921 val, _ := v.GetE(key)
922 return val
923 }
924
925
926
927 func Sub(key string) *Viper { return v.Sub(key) }
928 func (v *Viper) Sub(key string) *Viper {
929 subv := New()
930 data := v.Get(key)
931 if data == nil {
932 return nil
933 }
934
935 if reflect.TypeOf(data).Kind() == reflect.Map {
936 subv.config = cast.ToStringMap(data)
937 return subv
938 }
939 return nil
940 }
941
942
943 func GetString(key string) string { return v.GetString(key) }
944 func (v *Viper) GetString(key string) string {
945 return cast.ToString(v.Get(key))
946 }
947
948
949 func GetBool(key string) bool { return v.GetBool(key) }
950 func (v *Viper) GetBool(key string) bool {
951 return cast.ToBool(v.Get(key))
952 }
953
954
955 func GetInt(key string) int { return v.GetInt(key) }
956 func (v *Viper) GetInt(key string) int {
957 return cast.ToInt(v.Get(key))
958 }
959
960
961 func GetInt32(key string) int32 { return v.GetInt32(key) }
962 func (v *Viper) GetInt32(key string) int32 {
963 return cast.ToInt32(v.Get(key))
964 }
965
966
967 func GetInt64(key string) int64 { return v.GetInt64(key) }
968 func (v *Viper) GetInt64(key string) int64 {
969 return cast.ToInt64(v.Get(key))
970 }
971
972
973 func GetUint(key string) uint { return v.GetUint(key) }
974 func (v *Viper) GetUint(key string) uint {
975 return cast.ToUint(v.Get(key))
976 }
977
978
979 func GetUint32(key string) uint32 { return v.GetUint32(key) }
980 func (v *Viper) GetUint32(key string) uint32 {
981 return cast.ToUint32(v.Get(key))
982 }
983
984
985 func GetUint64(key string) uint64 { return v.GetUint64(key) }
986 func (v *Viper) GetUint64(key string) uint64 {
987 return cast.ToUint64(v.Get(key))
988 }
989
990
991 func GetFloat64(key string) float64 { return v.GetFloat64(key) }
992 func (v *Viper) GetFloat64(key string) float64 {
993 return cast.ToFloat64(v.Get(key))
994 }
995
996
997 func GetTime(key string) time.Time { return v.GetTime(key) }
998 func (v *Viper) GetTime(key string) time.Time {
999 return cast.ToTime(v.Get(key))
1000 }
1001
1002
1003 func GetDuration(key string) time.Duration { return v.GetDuration(key) }
1004 func (v *Viper) GetDuration(key string) time.Duration {
1005 return cast.ToDuration(v.Get(key))
1006 }
1007
1008
1009 func GetIntSlice(key string) []int { return v.GetIntSlice(key) }
1010 func (v *Viper) GetIntSlice(key string) []int {
1011 return cast.ToIntSlice(v.Get(key))
1012 }
1013
1014
1015 func GetStringSlice(key string) []string { return v.GetStringSlice(key) }
1016 func (v *Viper) GetStringSlice(key string) []string {
1017 return cast.ToStringSlice(v.Get(key))
1018 }
1019
1020
1021 func GetStringMap(key string) map[string]interface{} { return v.GetStringMap(key) }
1022 func (v *Viper) GetStringMap(key string) map[string]interface{} {
1023 return cast.ToStringMap(v.Get(key))
1024 }
1025
1026
1027 func GetStringMapString(key string) map[string]string { return v.GetStringMapString(key) }
1028 func (v *Viper) GetStringMapString(key string) map[string]string {
1029 return cast.ToStringMapString(v.Get(key))
1030 }
1031
1032
1033 func GetStringMapStringSlice(key string) map[string][]string { return v.GetStringMapStringSlice(key) }
1034 func (v *Viper) GetStringMapStringSlice(key string) map[string][]string {
1035 return cast.ToStringMapStringSlice(v.Get(key))
1036 }
1037
1038
1039
1040 func GetSizeInBytes(key string) uint { return v.GetSizeInBytes(key) }
1041 func (v *Viper) GetSizeInBytes(key string) uint {
1042 sizeStr := cast.ToString(v.Get(key))
1043 return parseSizeInBytes(sizeStr)
1044 }
1045
1046
1047 func UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConfigOption) error {
1048 return v.UnmarshalKey(key, rawVal, opts...)
1049 }
1050 func (v *Viper) UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConfigOption) error {
1051 err := decode(v.Get(key), defaultDecoderConfig(rawVal, opts...))
1052
1053 if err != nil {
1054 return err
1055 }
1056
1057 return nil
1058 }
1059
1060
1061
1062 func Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error {
1063 return v.Unmarshal(rawVal, opts...)
1064 }
1065 func (v *Viper) Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error {
1066 err := decode(v.AllSettings(), defaultDecoderConfig(rawVal, opts...))
1067
1068 if err != nil {
1069 return err
1070 }
1071
1072 return nil
1073 }
1074
1075
1076
1077 func defaultDecoderConfig(output interface{}, opts ...DecoderConfigOption) *mapstructure.DecoderConfig {
1078 c := &mapstructure.DecoderConfig{
1079 Metadata: nil,
1080 Result: output,
1081 WeaklyTypedInput: true,
1082 DecodeHook: mapstructure.ComposeDecodeHookFunc(
1083 mapstructure.StringToTimeDurationHookFunc(),
1084 mapstructure.StringToSliceHookFunc(","),
1085 ),
1086 }
1087 for _, opt := range opts {
1088 opt(c)
1089 }
1090 return c
1091 }
1092
1093
1094 func decode(input interface{}, config *mapstructure.DecoderConfig) error {
1095 decoder, err := mapstructure.NewDecoder(config)
1096 if err != nil {
1097 return err
1098 }
1099 return decoder.Decode(input)
1100 }
1101
1102
1103
1104 func UnmarshalExact(rawVal interface{}, opts ...DecoderConfigOption) error {
1105 return v.UnmarshalExact(rawVal, opts...)
1106 }
1107 func (v *Viper) UnmarshalExact(rawVal interface{}, opts ...DecoderConfigOption) error {
1108 config := defaultDecoderConfig(rawVal, opts...)
1109 config.ErrorUnused = true
1110
1111 err := decode(v.AllSettings(), config)
1112
1113 if err != nil {
1114 return err
1115 }
1116
1117 return nil
1118 }
1119
1120
1121
1122 func BindPFlags(flags *pflag.FlagSet) error { return v.BindPFlags(flags) }
1123 func (v *Viper) BindPFlags(flags *pflag.FlagSet) error {
1124 return v.BindFlagValues(pflagValueSet{flags})
1125 }
1126
1127
1128
1129
1130
1131
1132
1133 func BindPFlag(key string, flag *pflag.Flag) error { return v.BindPFlag(key, flag) }
1134 func (v *Viper) BindPFlag(key string, flag *pflag.Flag) error {
1135 return v.BindFlagValue(key, pflagValue{flag})
1136 }
1137
1138
1139
1140 func BindFlagValues(flags FlagValueSet) error { return v.BindFlagValues(flags) }
1141 func (v *Viper) BindFlagValues(flags FlagValueSet) (err error) {
1142 flags.VisitAll(func(flag FlagValue) {
1143 if err = v.BindFlagValue(flag.Name(), flag); err != nil {
1144 return
1145 }
1146 })
1147 return nil
1148 }
1149
1150
1151 func BindFlagValue(key string, flag FlagValue) error { return v.BindFlagValue(key, flag) }
1152 func (v *Viper) BindFlagValue(key string, flag FlagValue) error {
1153 if flag == nil {
1154 return fmt.Errorf("flag for %q is nil", key)
1155 }
1156 lcaseKey := strings.ToLower(key)
1157 v.lock.Lock()
1158 v.cache.Clear()
1159 v.pflags[lcaseKey] = flag
1160 v.lock.Unlock()
1161
1162
1163
1164 v.lock.RLock()
1165 typ := v.searchMap(v.types, strings.Split(lcaseKey, v.keyDelim))
1166 v.lock.RUnlock()
1167
1168 if typ == nil {
1169 switch flag.ValueType() {
1170 case "int", "int8", "int16", "int32", "int64":
1171 v.SetType(key, 0)
1172 case "bool":
1173 v.SetType(key, false)
1174 case "stringSlice":
1175 v.SetType(key, []string{})
1176 case "intSlice":
1177 v.SetType(key, []int{})
1178 default:
1179
1180 }
1181 }
1182 return nil
1183 }
1184
1185
1186
1187
1188
1189 func BindEnv(input ...string) error { return v.BindEnv(input...) }
1190 func (v *Viper) BindEnv(input ...string) error {
1191 var key, envkey string
1192 if len(input) == 0 {
1193 return fmt.Errorf("missing key to bind to")
1194 }
1195
1196 key = strings.ToLower(input[0])
1197
1198 if len(input) == 1 {
1199 envkey = v.mergeWithEnvPrefix(key)
1200 } else {
1201 envkey = input[1]
1202 }
1203
1204 v.lock.Lock()
1205 v.cache.Clear()
1206 v.env[key] = envkey
1207 v.lock.Unlock()
1208
1209 return nil
1210 }
1211
1212
1213
1214 func (v *Viper) cachedFindE(lcaseKey string, flagDefault bool) (interface{}, error) {
1215 realKey := v.realKey(lcaseKey)
1216
1217 v.lock.RLock()
1218 value, found := v.cache.Get(realKey)
1219 v.lock.RUnlock()
1220 if found {
1221 return value, nil
1222 }
1223
1224 value, castErr := v.findE(realKey, flagDefault)
1225 if castErr != nil {
1226 return value, castErr
1227 }
1228
1229 v.lock.Lock()
1230 v.cache.Set(realKey, value, 0)
1231 v.lock.Unlock()
1232
1233 return value, nil
1234 }
1235
1236 func (v *Viper) cachedFind(lcaseKey string, flagDefault bool) interface{} {
1237 val, _ := v.cachedFindE(lcaseKey, flagDefault)
1238 return val
1239 }
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250 func (v *Viper) findE(lcaseKey string, flagDefault bool) (interface{}, error) {
1251 v.lock.RLock()
1252 var (
1253 val interface{}
1254 exists bool
1255 path = strings.Split(lcaseKey, v.keyDelim)
1256 nested = len(path) > 1
1257 )
1258
1259
1260 if nested && v.isPathShadowedInDeepMap(path, castMapStringToMapInterface(v.aliases)) != "" {
1261 v.lock.RUnlock()
1262 return nil, nil
1263 }
1264 v.lock.RUnlock()
1265
1266
1267 lcaseKey = v.realKey(lcaseKey)
1268 typ := v.getType(lcaseKey)
1269
1270 v.lock.RLock()
1271 defer v.lock.RUnlock()
1272 path = strings.Split(lcaseKey, v.keyDelim)
1273 nested = len(path) > 1
1274
1275
1276 val = v.searchMap(v.override, path)
1277 if val != nil {
1278 return castAllSourcesE(typ, val)
1279 }
1280 if nested && v.isPathShadowedInDeepMap(path, v.override) != "" {
1281 return nil, nil
1282 }
1283
1284
1285 flag, exists := v.pflags[lcaseKey]
1286 if exists && flag.HasChanged() {
1287 return castStringSourcesE(typ, flag.ValueString())
1288 }
1289 if nested && v.isPathShadowedInFlatMap(path, v.pflags) != "" {
1290 return nil, nil
1291 }
1292
1293
1294 if v.automaticEnvApplied {
1295
1296
1297 if val, ok := v.getEnv(v.mergeWithEnvPrefix(lcaseKey)); ok {
1298 return castStringSourcesE(typ, val)
1299 }
1300 if nested && v.isPathShadowedInAutoEnv(path) != "" {
1301 return nil, nil
1302 }
1303 }
1304 envkey, exists := v.env[lcaseKey]
1305 if exists {
1306 if val, ok := v.getEnv(envkey); ok {
1307 return castStringSourcesE(typ, val)
1308 }
1309 }
1310 if nested && v.isPathShadowedInFlatMap(path, v.env) != "" {
1311 return nil, nil
1312 }
1313
1314
1315 val = v.searchMapWithPathPrefixes(v.config, path)
1316 if val != nil {
1317 return castAllSourcesE(typ, val)
1318 }
1319 if nested && v.isPathShadowedInDeepMap(path, v.config) != "" {
1320 return nil, nil
1321 }
1322
1323
1324 val = v.searchMap(v.kvstore, path)
1325 if val != nil {
1326 return castAllSourcesE(typ, val)
1327 }
1328 if nested && v.isPathShadowedInDeepMap(path, v.kvstore) != "" {
1329 return nil, nil
1330 }
1331
1332
1333 val = v.searchMap(v.defaults, path)
1334 if val != nil {
1335 return castAllSourcesE(typ, val)
1336 }
1337 if nested && v.isPathShadowedInDeepMap(path, v.defaults) != "" {
1338 return nil, nil
1339 }
1340
1341 if flagDefault {
1342
1343
1344 if flag, exists := v.pflags[lcaseKey]; exists {
1345 return castStringSourcesE(typ, flag.ValueString())
1346 }
1347
1348 }
1349
1350 return nil, nil
1351 }
1352 func (v *Viper) find(lcaseKey string, flagDefault bool) interface{} {
1353 val, _ := v.findE(lcaseKey, flagDefault)
1354 return val
1355 }
1356
1357 func readAsCSV(val string) ([]string, error) {
1358 if val == "" {
1359 return []string{}, nil
1360 }
1361 stringReader := strings.NewReader(val)
1362 csvReader := csv.NewReader(stringReader)
1363 return csvReader.Read()
1364 }
1365
1366
1367
1368 func IsSet(key string) bool { return v.IsSet(key) }
1369 func (v *Viper) IsSet(key string) bool {
1370 lcaseKey := strings.ToLower(key)
1371 val := v.cachedFind(lcaseKey, false)
1372 return val != nil
1373 }
1374
1375
1376
1377 func AutomaticEnv() { v.AutomaticEnv() }
1378 func (v *Viper) AutomaticEnv() {
1379 v.lock.Lock()
1380 v.cache.Clear()
1381 v.automaticEnvApplied = true
1382 v.lock.Unlock()
1383 }
1384
1385
1386
1387
1388 func SetEnvKeyReplacer(r *strings.Replacer) { v.SetEnvKeyReplacer(r) }
1389 func (v *Viper) SetEnvKeyReplacer(r *strings.Replacer) {
1390 v.lock.Lock()
1391 v.cache.Clear()
1392 v.envKeyReplacer = r
1393 v.lock.Unlock()
1394 }
1395
1396
1397
1398 func RegisterAlias(alias string, key string) { v.RegisterAlias(alias, key) }
1399 func (v *Viper) RegisterAlias(alias string, key string) {
1400 v.registerAlias(alias, strings.ToLower(key))
1401 }
1402
1403 func (v *Viper) registerAlias(alias string, key string) {
1404 alias = strings.ToLower(alias)
1405 if alias != key && alias != v.realKey(key) {
1406 v.lock.RLock()
1407 _, exists := v.aliases[alias]
1408 v.lock.RUnlock()
1409
1410 if !exists {
1411 v.lock.Lock()
1412
1413
1414
1415 if val, ok := v.config[alias]; ok {
1416 delete(v.config, alias)
1417 v.config[key] = val
1418 }
1419 if val, ok := v.kvstore[alias]; ok {
1420 delete(v.kvstore, alias)
1421 v.kvstore[key] = val
1422 }
1423 if val, ok := v.defaults[alias]; ok {
1424 delete(v.defaults, alias)
1425 v.defaults[key] = val
1426 }
1427 if val, ok := v.override[alias]; ok {
1428 delete(v.override, alias)
1429 v.override[key] = val
1430 }
1431 v.aliases[alias] = key
1432 v.lock.Unlock()
1433 }
1434 } else {
1435 jww.WARN.Println("Creating circular reference alias", alias, key, v.realKey(key))
1436 }
1437 }
1438
1439 func (v *Viper) realKey(key string) string {
1440 v.lock.RLock()
1441 newkey, exists := v.aliases[key]
1442 v.lock.RUnlock()
1443
1444 if exists {
1445 jww.DEBUG.Println("Alias", key, "to", newkey)
1446 return v.realKey(newkey)
1447 }
1448 return key
1449 }
1450
1451
1452 func InConfig(key string) bool { return v.InConfig(key) }
1453 func (v *Viper) InConfig(key string) bool {
1454
1455 key = v.realKey(key)
1456 v.lock.RLock()
1457 _, exists := v.config[key]
1458 v.lock.RUnlock()
1459 return exists
1460 }
1461
1462 func (v *Viper) setInMap(key string, value interface{}, target map[string]interface{}) {
1463 key = v.realKey(strings.ToLower(key))
1464 value = toCaseInsensitiveValue(value)
1465
1466 v.lock.RLock()
1467 path := strings.Split(key, v.keyDelim)
1468 lastKey := strings.ToLower(path[len(path)-1])
1469 deepestMap := deepSearch(target, path[0:len(path)-1])
1470 v.lock.RUnlock()
1471
1472 v.lock.Lock()
1473 v.cache.Clear()
1474
1475 deepestMap[lastKey] = value
1476 v.lock.Unlock()
1477 }
1478
1479
1480
1481
1482 func SetDefault(key string, value interface{}) { v.SetDefault(key, value) }
1483 func (v *Viper) SetDefault(key string, value interface{}) {
1484 v.setInMap(key, value, v.defaults)
1485 }
1486
1487
1488
1489
1490
1491 func SetType(key string, t interface{}) { v.SetType(key, t) }
1492 func (v *Viper) SetType(key string, t interface{}) {
1493 v.setInMap(key, t, v.types)
1494 }
1495
1496
1497
1498
1499
1500 func Set(key string, value interface{}) { v.Set(key, value) }
1501 func (v *Viper) Set(key string, value interface{}) {
1502 v.setInMap(key, value, v.override)
1503 }
1504
1505
1506
1507 func ReadInConfig() error { return v.ReadInConfig() }
1508 func (v *Viper) ReadInConfig() error {
1509 jww.INFO.Println("Attempting to read in config file")
1510 filename, err := v.getConfigFile()
1511 if err != nil {
1512 return err
1513 }
1514
1515 if !stringInSlice(v.getConfigType(), SupportedExts) {
1516 return UnsupportedConfigError(v.getConfigType())
1517 }
1518
1519 jww.DEBUG.Println("Reading file: ", filename)
1520 file, err := afero.ReadFile(v.fs, filename)
1521 if err != nil {
1522 return err
1523 }
1524
1525 config := make(map[string]interface{})
1526
1527 err = v.unmarshalReader(bytes.NewReader(file), config)
1528 if err != nil {
1529 return err
1530 }
1531
1532 v.lock.Lock()
1533 v.cache.Clear()
1534 v.config = config
1535 v.configChangedAt = time.Now()
1536 v.lock.Unlock()
1537
1538 return nil
1539 }
1540
1541
1542 func SetRawConfig(config map[string]interface{}) { v.SetRawConfig(config) }
1543 func (v *Viper) SetRawConfig(config map[string]interface{}) {
1544 v.lock.Lock()
1545 defer v.lock.Unlock()
1546 insensitiviseMap(config)
1547 v.config = config
1548 v.configChangedAt = time.Now()
1549 v.cache.Clear()
1550 }
1551
1552
1553 func MergeInConfig() error { return v.MergeInConfig() }
1554 func (v *Viper) MergeInConfig() error {
1555 jww.INFO.Println("Attempting to merge in config file")
1556 filename, err := v.getConfigFile()
1557 if err != nil {
1558 return err
1559 }
1560
1561 if !stringInSlice(v.getConfigType(), SupportedExts) {
1562 return UnsupportedConfigError(v.getConfigType())
1563 }
1564
1565 file, err := afero.ReadFile(v.fs, filename)
1566 if err != nil {
1567 return err
1568 }
1569
1570 return v.MergeConfig(bytes.NewReader(file))
1571 }
1572
1573
1574
1575 func ReadConfig(in io.Reader) error { return v.ReadConfig(in) }
1576 func (v *Viper) ReadConfig(in io.Reader) error {
1577 v.lock.Lock()
1578 defer v.lock.Unlock()
1579 v.cache.Clear()
1580 v.config = make(map[string]interface{})
1581 v.configChangedAt = time.Now()
1582 return v.unmarshalReader(in, v.config)
1583 }
1584
1585
1586 func MergeConfig(in io.Reader) error { return v.MergeConfig(in) }
1587 func (v *Viper) MergeConfig(in io.Reader) error {
1588 cfg := make(map[string]interface{})
1589 if err := v.unmarshalReader(in, cfg); err != nil {
1590 return err
1591 }
1592 return v.MergeConfigMap(cfg)
1593 }
1594
1595
1596
1597 func MergeConfigMap(cfg map[string]interface{}) error { return v.MergeConfigMap(cfg) }
1598 func (v *Viper) MergeConfigMap(cfg map[string]interface{}) error {
1599 v.lock.Lock()
1600 v.cache.Clear()
1601 if v.config == nil {
1602 v.config = make(map[string]interface{})
1603 }
1604 insensitiviseMap(cfg)
1605 mergeMaps(cfg, v.config, nil)
1606 v.configChangedAt = time.Now()
1607 v.lock.Unlock()
1608 return nil
1609 }
1610
1611
1612 func WriteConfig() error { return v.WriteConfig() }
1613 func (v *Viper) WriteConfig() error {
1614 filename, err := v.getConfigFile()
1615 if err != nil {
1616 return err
1617 }
1618 return v.writeConfig(filename, true)
1619 }
1620
1621
1622 func SafeWriteConfig() error { return v.SafeWriteConfig() }
1623 func (v *Viper) SafeWriteConfig() error {
1624 if len(v.configPaths) < 1 {
1625 return errors.New("missing configuration for 'configPath'")
1626 }
1627 return v.SafeWriteConfigAs(filepath.Join(v.configPaths[0], v.configName+"."+v.configType))
1628 }
1629
1630
1631 func WriteConfigAs(filename string) error { return v.WriteConfigAs(filename) }
1632 func (v *Viper) WriteConfigAs(filename string) error {
1633 return v.writeConfig(filename, true)
1634 }
1635
1636
1637 func SafeWriteConfigAs(filename string) error { return v.SafeWriteConfigAs(filename) }
1638 func (v *Viper) SafeWriteConfigAs(filename string) error {
1639 alreadyExists, err := afero.Exists(v.fs, filename)
1640 if alreadyExists && err == nil {
1641 return ConfigFileAlreadyExistsError(filename)
1642 }
1643 return v.writeConfig(filename, false)
1644 }
1645
1646 func (v *Viper) writeConfig(filename string, force bool) error {
1647 jww.INFO.Println("Attempting to write configuration to file.")
1648 var configType string
1649
1650 ext := filepath.Ext(filename)
1651 if ext != "" {
1652 configType = ext[1:]
1653 } else {
1654 configType = v.configType
1655 }
1656 if configType == "" {
1657 return fmt.Errorf("config type could not be determined for %s", filename)
1658 }
1659
1660 if !stringInSlice(configType, SupportedExts) {
1661 return UnsupportedConfigError(configType)
1662 }
1663 if v.config == nil {
1664 v.config = make(map[string]interface{})
1665 }
1666 flags := os.O_CREATE | os.O_TRUNC | os.O_WRONLY
1667 if !force {
1668 flags |= os.O_EXCL
1669 }
1670 f, err := v.fs.OpenFile(filename, flags, v.configPermissions)
1671 if err != nil {
1672 return err
1673 }
1674 defer f.Close()
1675
1676 if err := v.marshalWriter(f, configType); err != nil {
1677 return err
1678 }
1679
1680 return f.Sync()
1681 }
1682
1683
1684
1685 func unmarshalReader(in io.Reader, c map[string]interface{}) error {
1686 return v.unmarshalReader(in, c)
1687 }
1688 func (v *Viper) unmarshalReader(in io.Reader, c map[string]interface{}) error {
1689 buf := new(bytes.Buffer)
1690 buf.ReadFrom(in)
1691
1692 switch strings.ToLower(v.getConfigType()) {
1693 case "yaml", "yml":
1694 if err := yaml.Unmarshal(buf.Bytes(), &c); err != nil {
1695 return ConfigParseError{err}
1696 }
1697
1698 case "json":
1699 if err := json.Unmarshal(buf.Bytes(), &c); err != nil {
1700 return ConfigParseError{err}
1701 }
1702
1703 case "hcl":
1704 obj, err := hcl.Parse(buf.String())
1705 if err != nil {
1706 return ConfigParseError{err}
1707 }
1708 if err = hcl.DecodeObject(&c, obj); err != nil {
1709 return ConfigParseError{err}
1710 }
1711
1712 case "toml":
1713 tree, err := toml.LoadReader(buf)
1714 if err != nil {
1715 return ConfigParseError{err}
1716 }
1717 tmap := tree.ToMap()
1718 for k, v := range tmap {
1719 c[k] = v
1720 }
1721
1722 case "dotenv", "env":
1723 env, err := gotenv.StrictParse(buf)
1724 if err != nil {
1725 return ConfigParseError{err}
1726 }
1727 for k, v := range env {
1728 c[k] = v
1729 }
1730
1731 case "properties", "props", "prop":
1732 v.properties = properties.NewProperties()
1733 var err error
1734 if v.properties, err = properties.Load(buf.Bytes(), properties.UTF8); err != nil {
1735 return ConfigParseError{err}
1736 }
1737 for _, key := range v.properties.Keys() {
1738 value, _ := v.properties.Get(key)
1739
1740 path := strings.Split(key, ".")
1741 lastKey := strings.ToLower(path[len(path)-1])
1742 deepestMap := deepSearch(c, path[0:len(path)-1])
1743
1744 deepestMap[lastKey] = value
1745 }
1746
1747 case "ini":
1748 cfg := ini.Empty()
1749 err := cfg.Append(buf.Bytes())
1750 if err != nil {
1751 return ConfigParseError{err}
1752 }
1753 sections := cfg.Sections()
1754 for i := 0; i < len(sections); i++ {
1755 section := sections[i]
1756 keys := section.Keys()
1757 for j := 0; j < len(keys); j++ {
1758 key := keys[j]
1759 value := cfg.Section(section.Name()).Key(key.Name()).String()
1760 c[section.Name()+"."+key.Name()] = value
1761 }
1762 }
1763 }
1764
1765 insensitiviseMap(c)
1766 return nil
1767 }
1768
1769 func (v *Viper) marshalWriter(f afero.File, configType string) error {
1770 c := v.AllSettings()
1771 switch configType {
1772 case "json":
1773 b, err := json.MarshalIndent(c, "", " ")
1774 if err != nil {
1775 return ConfigMarshalError{err}
1776 }
1777 _, err = f.WriteString(string(b))
1778 if err != nil {
1779 return ConfigMarshalError{err}
1780 }
1781
1782 case "hcl":
1783 b, err := json.Marshal(c)
1784 if err != nil {
1785 return ConfigMarshalError{err}
1786 }
1787 ast, err := hcl.Parse(string(b))
1788 if err != nil {
1789 return ConfigMarshalError{err}
1790 }
1791 err = printer.Fprint(f, ast.Node)
1792 if err != nil {
1793 return ConfigMarshalError{err}
1794 }
1795
1796 case "prop", "props", "properties":
1797 if v.properties == nil {
1798 v.properties = properties.NewProperties()
1799 }
1800 p := v.properties
1801 for _, key := range v.AllKeys() {
1802 _, _, err := p.Set(key, v.GetString(key))
1803 if err != nil {
1804 return ConfigMarshalError{err}
1805 }
1806 }
1807 _, err := p.WriteComment(f, "#", properties.UTF8)
1808 if err != nil {
1809 return ConfigMarshalError{err}
1810 }
1811
1812 case "dotenv", "env":
1813 lines := []string{}
1814 for _, key := range v.AllKeys() {
1815 envName := strings.ToUpper(strings.Replace(key, ".", "_", -1))
1816 val := v.Get(key)
1817 lines = append(lines, fmt.Sprintf("%v=%v", envName, val))
1818 }
1819 s := strings.Join(lines, "\n")
1820 if _, err := f.WriteString(s); err != nil {
1821 return ConfigMarshalError{err}
1822 }
1823
1824 case "toml":
1825 t, err := toml.TreeFromMap(c)
1826 if err != nil {
1827 return ConfigMarshalError{err}
1828 }
1829 s := t.String()
1830 if _, err := f.WriteString(s); err != nil {
1831 return ConfigMarshalError{err}
1832 }
1833
1834 case "yaml", "yml":
1835 b, err := yaml.Marshal(c)
1836 if err != nil {
1837 return ConfigMarshalError{err}
1838 }
1839 if _, err = f.WriteString(string(b)); err != nil {
1840 return ConfigMarshalError{err}
1841 }
1842
1843 case "ini":
1844 keys := v.AllKeys()
1845 cfg := ini.Empty()
1846 ini.PrettyFormat = false
1847 for i := 0; i < len(keys); i++ {
1848 key := keys[i]
1849 lastSep := strings.LastIndex(key, ".")
1850 sectionName := key[:(lastSep)]
1851 keyName := key[(lastSep + 1):]
1852 if sectionName == "default" {
1853 sectionName = ""
1854 }
1855 cfg.Section(sectionName).Key(keyName).SetValue(Get(key).(string))
1856 }
1857 cfg.WriteTo(f)
1858 }
1859 return nil
1860 }
1861
1862 func keyExists(k string, m map[string]interface{}) string {
1863 lk := strings.ToLower(k)
1864 for mk := range m {
1865 lmk := strings.ToLower(mk)
1866 if lmk == lk {
1867 return mk
1868 }
1869 }
1870 return ""
1871 }
1872
1873 func castToMapStringInterface(
1874 src map[interface{}]interface{}) map[string]interface{} {
1875 tgt := map[string]interface{}{}
1876 for k, v := range src {
1877 tgt[fmt.Sprintf("%v", k)] = v
1878 }
1879 return tgt
1880 }
1881
1882 func castMapStringToMapInterface(src map[string]string) map[string]interface{} {
1883 tgt := map[string]interface{}{}
1884 for k, v := range src {
1885 tgt[k] = v
1886 }
1887 return tgt
1888 }
1889
1890 func castMapFlagToMapInterface(src map[string]FlagValue) map[string]interface{} {
1891 tgt := map[string]interface{}{}
1892 for k, v := range src {
1893 tgt[k] = v
1894 }
1895 return tgt
1896 }
1897
1898
1899
1900
1901
1902
1903 func mergeMaps(
1904 src, tgt map[string]interface{}, itgt map[interface{}]interface{}) {
1905 for sk, sv := range src {
1906 tk := keyExists(sk, tgt)
1907 if tk == "" {
1908 jww.TRACE.Printf("tk=\"\", tgt[%s]=%v", sk, sv)
1909 tgt[sk] = sv
1910 if itgt != nil {
1911 itgt[sk] = sv
1912 }
1913 continue
1914 }
1915
1916 tv, ok := tgt[tk]
1917 if !ok {
1918 jww.TRACE.Printf("tgt[%s] != ok, tgt[%s]=%v", tk, sk, sv)
1919 tgt[sk] = sv
1920 if itgt != nil {
1921 itgt[sk] = sv
1922 }
1923 continue
1924 }
1925
1926 svType := reflect.TypeOf(sv)
1927 tvType := reflect.TypeOf(tv)
1928 if svType != tvType {
1929 jww.ERROR.Printf(
1930 "svType != tvType; key=%s, st=%v, tt=%v, sv=%v, tv=%v",
1931 sk, svType, tvType, sv, tv)
1932 continue
1933 }
1934
1935 jww.TRACE.Printf("processing key=%s, st=%v, tt=%v, sv=%v, tv=%v",
1936 sk, svType, tvType, sv, tv)
1937
1938 switch ttv := tv.(type) {
1939 case map[interface{}]interface{}:
1940 jww.TRACE.Printf("merging maps (must convert)")
1941 tsv := sv.(map[interface{}]interface{})
1942 ssv := castToMapStringInterface(tsv)
1943 stv := castToMapStringInterface(ttv)
1944 mergeMaps(ssv, stv, ttv)
1945 case map[string]interface{}:
1946 jww.TRACE.Printf("merging maps")
1947 mergeMaps(sv.(map[string]interface{}), ttv, nil)
1948 default:
1949 jww.TRACE.Printf("setting value")
1950 tgt[tk] = sv
1951 if itgt != nil {
1952 itgt[tk] = sv
1953 }
1954 }
1955 }
1956 }
1957
1958
1959
1960 func ReadRemoteConfig() error { return v.ReadRemoteConfig() }
1961 func (v *Viper) ReadRemoteConfig() error {
1962 return v.getKeyValueConfig()
1963 }
1964
1965 func WatchRemoteConfig() error { return v.WatchRemoteConfig() }
1966 func (v *Viper) WatchRemoteConfig() error {
1967 return v.watchKeyValueConfig()
1968 }
1969
1970 func (v *Viper) WatchRemoteConfigOnChannel() error {
1971 return v.watchKeyValueConfigOnChannel()
1972 }
1973
1974
1975 func (v *Viper) getKeyValueConfig() error {
1976 if RemoteConfig == nil {
1977 return RemoteConfigError("Enable the remote features by doing a blank import of the viper/remote package: '_ github.com/ory/viper/remote'")
1978 }
1979
1980 v.lock.RLock()
1981 for _, rp := range v.remoteProviders {
1982 val, err := v.getRemoteConfig(rp)
1983 if err != nil {
1984 continue
1985 }
1986 v.lock.RUnlock()
1987 v.lock.Lock()
1988 v.kvstore = val
1989 v.lock.Unlock()
1990 return nil
1991 }
1992 v.lock.RUnlock()
1993 return RemoteConfigError("No Files Found")
1994 }
1995
1996 func (v *Viper) getRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) {
1997 reader, err := RemoteConfig.Get(provider)
1998 if err != nil {
1999 return nil, err
2000 }
2001 v.lock.RLock()
2002 err = v.unmarshalReader(reader, v.kvstore)
2003 v.lock.RUnlock()
2004 return v.kvstore, err
2005 }
2006
2007
2008 func (v *Viper) watchKeyValueConfigOnChannel() error {
2009 for _, rp := range v.remoteProviders {
2010 respc, _ := RemoteConfig.WatchChannel(rp)
2011
2012 go func(rc <-chan *RemoteResponse) {
2013 for {
2014 b := <-rc
2015 reader := bytes.NewReader(b.Value)
2016 v.unmarshalReader(reader, v.kvstore)
2017 }
2018 }(respc)
2019 return nil
2020 }
2021 return RemoteConfigError("No Files Found")
2022 }
2023
2024
2025 func (v *Viper) watchKeyValueConfig() error {
2026 for _, rp := range v.remoteProviders {
2027 val, err := v.watchRemoteConfig(rp)
2028 if err != nil {
2029 continue
2030 }
2031 v.kvstore = val
2032 return nil
2033 }
2034 return RemoteConfigError("No Files Found")
2035 }
2036
2037 func (v *Viper) watchRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) {
2038 reader, err := RemoteConfig.Watch(provider)
2039 if err != nil {
2040 return nil, err
2041 }
2042 err = v.unmarshalReader(reader, v.kvstore)
2043 return v.kvstore, err
2044 }
2045
2046
2047
2048 func AllKeys() []string { return v.AllKeys() }
2049 func (v *Viper) AllKeys() []string {
2050 v.lock.RLock()
2051 defer v.lock.RUnlock()
2052
2053 m := map[string]bool{}
2054
2055 m = v.flattenAndMergeMap(m, castMapStringToMapInterface(v.aliases), "")
2056 m = v.flattenAndMergeMap(m, v.override, "")
2057 m = v.mergeFlatMap(m, castMapFlagToMapInterface(v.pflags))
2058 m = v.mergeFlatMap(m, castMapStringToMapInterface(v.env))
2059 m = v.flattenAndMergeMap(m, v.config, "")
2060 m = v.flattenAndMergeMap(m, v.kvstore, "")
2061 m = v.flattenAndMergeMap(m, v.defaults, "")
2062
2063
2064 a := make([]string, 0, len(m))
2065 for x := range m {
2066 a = append(a, x)
2067 }
2068 return a
2069 }
2070
2071
2072
2073
2074
2075
2076
2077 func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interface{}, prefix string) map[string]bool {
2078 if shadow != nil && prefix != "" && shadow[prefix] {
2079
2080 return shadow
2081 }
2082 if shadow == nil {
2083 shadow = make(map[string]bool)
2084 }
2085
2086 var m2 map[string]interface{}
2087 if prefix != "" {
2088 prefix += v.keyDelim
2089 }
2090 for k, val := range m {
2091 fullKey := prefix + k
2092 switch val.(type) {
2093 case map[string]interface{}:
2094 m2 = val.(map[string]interface{})
2095 case map[interface{}]interface{}:
2096 m2 = cast.ToStringMap(val)
2097 default:
2098
2099 shadow[strings.ToLower(fullKey)] = true
2100 continue
2101 }
2102
2103 shadow = v.flattenAndMergeMap(shadow, m2, fullKey)
2104 }
2105 return shadow
2106 }
2107
2108
2109
2110 func (v *Viper) mergeFlatMap(shadow map[string]bool, m map[string]interface{}) map[string]bool {
2111
2112 outer:
2113 for k := range m {
2114 path := strings.Split(k, v.keyDelim)
2115
2116 var parentKey string
2117 for i := 1; i < len(path); i++ {
2118 parentKey = strings.Join(path[0:i], v.keyDelim)
2119 if shadow[parentKey] {
2120
2121 continue outer
2122 }
2123 }
2124
2125 shadow[strings.ToLower(k)] = true
2126 }
2127 return shadow
2128 }
2129
2130
2131 func AllSettingsE() (map[string]interface{}, error) { return v.AllSettingsE() }
2132 func (v *Viper) AllSettingsE() (m map[string]interface{}, lastErr error) {
2133 m = map[string]interface{}{}
2134
2135 for _, k := range v.AllKeys() {
2136 value, err := v.GetE(k)
2137 if err != nil {
2138
2139 lastErr = err
2140 }
2141 if value == nil {
2142
2143
2144 continue
2145 }
2146 path := strings.Split(k, v.keyDelim)
2147 lastKey := strings.ToLower(path[len(path)-1])
2148 deepestMap := deepSearch(m, path[0:len(path)-1])
2149
2150 deepestMap[lastKey] = value
2151 }
2152 m = toMapStringInterface(m).(map[string]interface{})
2153 return
2154 }
2155
2156 func AllSettings() map[string]interface{} { return v.AllSettings() }
2157 func (v *Viper) AllSettings() map[string]interface{} {
2158 m, _ := v.AllSettingsE()
2159 return m
2160 }
2161
2162
2163 func SetFs(fs afero.Fs) { v.SetFs(fs) }
2164 func (v *Viper) SetFs(fs afero.Fs) {
2165 v.lock.Lock()
2166 v.fs = fs
2167 v.lock.Unlock()
2168 }
2169
2170
2171
2172 func SetConfigName(in string) { v.SetConfigName(in) }
2173 func (v *Viper) SetConfigName(in string) {
2174 if in != "" {
2175 v.lock.Lock()
2176 v.configName = in
2177 v.configFile = ""
2178 v.lock.Unlock()
2179 }
2180 }
2181
2182
2183
2184 func SetConfigType(in string) { v.SetConfigType(in) }
2185 func (v *Viper) SetConfigType(in string) {
2186 if in != "" {
2187 v.lock.Lock()
2188 v.configType = in
2189 v.lock.Unlock()
2190 }
2191 }
2192
2193
2194 func SetConfigPermissions(perm os.FileMode) { v.SetConfigPermissions(perm) }
2195 func (v *Viper) SetConfigPermissions(perm os.FileMode) {
2196 v.lock.Lock()
2197 v.configPermissions = perm.Perm()
2198 v.lock.Unlock()
2199 }
2200
2201 func (v *Viper) getConfigType() string {
2202 if v.configType != "" {
2203 return v.configType
2204 }
2205
2206 cf, err := v.getConfigFile()
2207 if err != nil {
2208 return ""
2209 }
2210
2211 ext := filepath.Ext(cf)
2212
2213 if len(ext) > 1 {
2214 return ext[1:]
2215 }
2216
2217 return ""
2218 }
2219
2220 func (v *Viper) getConfigFile() (string, error) {
2221 if v.configFile == "" {
2222 cf, err := v.findConfigFile()
2223 if err != nil {
2224 return "", err
2225 }
2226 v.configFile = cf
2227 }
2228 return v.configFile, nil
2229 }
2230
2231 func (v *Viper) searchInPath(in string) (filename string) {
2232 jww.DEBUG.Println("Searching for config in ", in)
2233 for _, ext := range SupportedExts {
2234 jww.DEBUG.Println("Checking for", filepath.Join(in, v.configName+"."+ext))
2235 if b, _ := exists(v.fs, filepath.Join(in, v.configName+"."+ext)); b {
2236 jww.DEBUG.Println("Found: ", filepath.Join(in, v.configName+"."+ext))
2237 return filepath.Join(in, v.configName+"."+ext)
2238 }
2239 }
2240
2241 if v.configType != "" {
2242 if b, _ := exists(v.fs, filepath.Join(in, v.configName)); b {
2243 return filepath.Join(in, v.configName)
2244 }
2245 }
2246
2247 return ""
2248 }
2249
2250
2251
2252 func (v *Viper) findConfigFile() (string, error) {
2253 jww.INFO.Println("Searching for config in ", v.configPaths)
2254
2255 for _, cp := range v.configPaths {
2256 file := v.searchInPath(cp)
2257 if file != "" {
2258 return file, nil
2259 }
2260 }
2261 return "", ConfigFileNotFoundError{v.configName, fmt.Sprintf("%s", v.configPaths)}
2262 }
2263
2264
2265
2266 func Debug() { v.Debug() }
2267 func (v *Viper) Debug() {
2268 v.lock.RLock()
2269 defer v.lock.RUnlock()
2270 fmt.Printf("Aliases:\n%#v\n", v.aliases)
2271 fmt.Printf("Override:\n%#v\n", v.override)
2272 fmt.Printf("PFlags:\n%#v\n", v.pflags)
2273 fmt.Printf("Env:\n%#v\n", v.env)
2274 fmt.Printf("Key/Value Store:\n%#v\n", v.kvstore)
2275 fmt.Printf("Config:\n%#v\n", v.config)
2276 fmt.Printf("Defaults:\n%#v\n", v.defaults)
2277 }
2278
View as plain text