mirror of
https://github.com/spf13/viper
synced 2025-05-07 20:57:18 +00:00
Add registered map and implement the Local watch function.
This commit is contained in:
parent
3970ad177e
commit
4bb20e2c5a
3 changed files with 83 additions and 1 deletions
19
register.go
Normal file
19
register.go
Normal file
|
@ -0,0 +1,19 @@
|
|||
package viper
|
||||
|
||||
type RegisteredConfig struct {
|
||||
Key string
|
||||
CanBeNil bool
|
||||
OnUpdate func(e *Event)
|
||||
OnUpdateFailed func(e *Event)
|
||||
Schema *interface{}
|
||||
Validator func(interface{}) bool
|
||||
}
|
||||
|
||||
func (v *Viper) Register(r []RegisteredConfig) {
|
||||
if v.registered == nil {
|
||||
v.registered = make(map[string]RegisteredConfig)
|
||||
}
|
||||
for _, config := range r {
|
||||
v.registered[config.Key] = config
|
||||
}
|
||||
}
|
52
viper.go
52
viper.go
|
@ -22,6 +22,7 @@ package viper
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/csv"
|
||||
js "encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -223,6 +224,8 @@ type Viper struct {
|
|||
// TODO: should probably be protected with a mutex
|
||||
encoderRegistry *encoding.EncoderRegistry
|
||||
decoderRegistry *encoding.DecoderRegistry
|
||||
|
||||
registered map[string]RegisteredConfig
|
||||
}
|
||||
|
||||
// New returns an initialized Viper instance.
|
||||
|
@ -474,10 +477,57 @@ func (v *Viper) WatchConfig() {
|
|||
(event.Has(fsnotify.Write) || event.Has(fsnotify.Create))) ||
|
||||
(currentConfigFile != "" && currentConfigFile != realConfigFile) {
|
||||
realConfigFile = currentConfigFile
|
||||
err := v.ReadInConfig()
|
||||
tempViper := New()
|
||||
tempViper.AddConfigPath(realConfigFile)
|
||||
err := tempViper.ReadInConfig()
|
||||
if err != nil {
|
||||
log.Printf("error reading config file: %v\n", err)
|
||||
}
|
||||
|
||||
for key, config := range v.registered {
|
||||
oldValue := v.Get(key)
|
||||
newValue := tempViper.Get(key)
|
||||
// Check exist
|
||||
if newValue == nil && !config.CanBeNil {
|
||||
if config.OnUpdateFailed != nil {
|
||||
config.OnUpdateFailed(&Event{
|
||||
old: oldValue,
|
||||
new: nil,
|
||||
})
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Type check & convert
|
||||
newValueJson, _ := js.Marshal(newValue)
|
||||
err = js.Unmarshal(newValueJson, config.Schema)
|
||||
if err != nil {
|
||||
config.OnUpdateFailed(&Event{
|
||||
old: oldValue,
|
||||
new: nil,
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
// Validation
|
||||
if !config.Validator(config.Schema) {
|
||||
config.OnUpdateFailed(&Event{
|
||||
old: oldValue,
|
||||
new: nil,
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
// Success
|
||||
v.Set(key, config.Schema)
|
||||
if config.OnUpdate != nil {
|
||||
config.OnUpdate(&Event{
|
||||
new: config.Schema,
|
||||
old: oldValue,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if v.onConfigChange != nil {
|
||||
v.onConfigChange(event)
|
||||
}
|
||||
|
|
13
watch.go
13
watch.go
|
@ -10,3 +10,16 @@ type watcher = fsnotify.Watcher
|
|||
func newWatcher() (*watcher, error) {
|
||||
return fsnotify.NewWatcher()
|
||||
}
|
||||
|
||||
type Event struct {
|
||||
new interface{}
|
||||
old interface{}
|
||||
}
|
||||
|
||||
func (s *Event) New() interface{} {
|
||||
return s.new
|
||||
}
|
||||
|
||||
func (s *Event) Old() interface{} {
|
||||
return s.old
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue