mirror of
https://github.com/spf13/viper
synced 2025-05-10 22:27: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 (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
|
js "encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -223,6 +224,8 @@ type Viper struct {
|
||||||
// TODO: should probably be protected with a mutex
|
// TODO: should probably be protected with a mutex
|
||||||
encoderRegistry *encoding.EncoderRegistry
|
encoderRegistry *encoding.EncoderRegistry
|
||||||
decoderRegistry *encoding.DecoderRegistry
|
decoderRegistry *encoding.DecoderRegistry
|
||||||
|
|
||||||
|
registered map[string]RegisteredConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns an initialized Viper instance.
|
// New returns an initialized Viper instance.
|
||||||
|
@ -474,10 +477,57 @@ func (v *Viper) WatchConfig() {
|
||||||
(event.Has(fsnotify.Write) || event.Has(fsnotify.Create))) ||
|
(event.Has(fsnotify.Write) || event.Has(fsnotify.Create))) ||
|
||||||
(currentConfigFile != "" && currentConfigFile != realConfigFile) {
|
(currentConfigFile != "" && currentConfigFile != realConfigFile) {
|
||||||
realConfigFile = currentConfigFile
|
realConfigFile = currentConfigFile
|
||||||
err := v.ReadInConfig()
|
tempViper := New()
|
||||||
|
tempViper.AddConfigPath(realConfigFile)
|
||||||
|
err := tempViper.ReadInConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error reading config file: %v\n", err)
|
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 {
|
if v.onConfigChange != nil {
|
||||||
v.onConfigChange(event)
|
v.onConfigChange(event)
|
||||||
}
|
}
|
||||||
|
|
13
watch.go
13
watch.go
|
@ -10,3 +10,16 @@ type watcher = fsnotify.Watcher
|
||||||
func newWatcher() (*watcher, error) {
|
func newWatcher() (*watcher, error) {
|
||||||
return fsnotify.NewWatcher()
|
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