mirror of
https://github.com/spf13/viper
synced 2025-05-06 12:17:18 +00:00
Merge aa295b144a
into 7538d73b4e
This commit is contained in:
commit
d41277840c
2 changed files with 129 additions and 2 deletions
53
util.go
53
util.go
|
@ -21,12 +21,14 @@ import (
|
|||
"strings"
|
||||
"unicode"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/hashicorp/hcl"
|
||||
"github.com/magiconair/properties"
|
||||
toml "github.com/pelletier/go-toml"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/spf13/cast"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// ConfigParseError denotes failing to parse configuration file.
|
||||
|
@ -39,6 +41,16 @@ func (pe ConfigParseError) Error() string {
|
|||
return fmt.Sprintf("While parsing config: %s", pe.err.Error())
|
||||
}
|
||||
|
||||
// ConfigMarshalError happens when failing to marshal the configuration.
|
||||
type ConfigMarshalError struct {
|
||||
err error
|
||||
}
|
||||
|
||||
// Error returns the formatted configuration error.
|
||||
func (e ConfigMarshalError) Error() string {
|
||||
return fmt.Sprintf("While marshaling config: %s", e.err.Error())
|
||||
}
|
||||
|
||||
// toCaseInsensitiveValue checks if the value is a map;
|
||||
// if so, create a copy and lower-case the keys recursively.
|
||||
func toCaseInsensitiveValue(value interface{}) interface{} {
|
||||
|
@ -152,6 +164,45 @@ func userHomeDir() string {
|
|||
return os.Getenv("HOME")
|
||||
}
|
||||
|
||||
func marshalConfigWriter(f afero.File, c map[string]interface{}, configType string) error {
|
||||
switch configType {
|
||||
case "json":
|
||||
b, err := json.MarshalIndent(v.AllSettings(), "", " ")
|
||||
if err != nil {
|
||||
return ConfigMarshalError{err}
|
||||
}
|
||||
_, err = f.WriteString(string(b))
|
||||
if err != nil {
|
||||
return ConfigMarshalError{err}
|
||||
}
|
||||
|
||||
case "hcl":
|
||||
// TODO: How to convert map to hcl???
|
||||
|
||||
case "prop", "props", "properties":
|
||||
|
||||
case "toml":
|
||||
t := toml.TreeFromMap(v.AllSettings())
|
||||
s := t.String()
|
||||
_, err := f.WriteString(s)
|
||||
if err != nil {
|
||||
return ConfigMarshalError{err}
|
||||
}
|
||||
|
||||
case "yaml", "yml":
|
||||
b, err := yaml.Marshal(v.AllSettings())
|
||||
if err != nil {
|
||||
return ConfigMarshalError{err}
|
||||
}
|
||||
_, err = f.WriteString(string(b))
|
||||
if err != nil {
|
||||
return ConfigMarshalError{err}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func unmarshallConfigReader(in io.Reader, c map[string]interface{}, configType string) error {
|
||||
buf := new(bytes.Buffer)
|
||||
buf.ReadFrom(in)
|
||||
|
|
78
viper.go
78
viper.go
|
@ -30,12 +30,12 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/spf13/cast"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
"github.com/spf13/pflag"
|
||||
"gopkg.in/fsnotify.v1"
|
||||
)
|
||||
|
||||
var v *Viper
|
||||
|
@ -1147,6 +1147,73 @@ func (v *Viper) MergeConfig(in io.Reader) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func writeConfig(filename string, force bool) error { return v.writeConfig(filename, force) }
|
||||
func (v *Viper) writeConfig(filename string, force bool) error {
|
||||
jww.INFO.Println("Attempting to write configuration to file.")
|
||||
ext := filepath.Ext(filename)
|
||||
if len(ext) <= 1 {
|
||||
return fmt.Errorf("Filename: %s requires valid extension.", filename)
|
||||
}
|
||||
configType := ext[1:]
|
||||
if !stringInSlice(configType, SupportedExts) {
|
||||
return UnsupportedConfigError(configType)
|
||||
}
|
||||
if v.config == nil {
|
||||
v.config = make(map[string]interface{})
|
||||
}
|
||||
var flags int
|
||||
if force == true {
|
||||
flags = os.O_CREATE | os.O_WRONLY
|
||||
} else {
|
||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
flags = os.O_WRONLY
|
||||
} else {
|
||||
return fmt.Errorf("File: %s exists. Use WriteConfig to overwrite.", filename)
|
||||
}
|
||||
}
|
||||
f, err := v.fs.OpenFile(filename, flags, os.FileMode(0644))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return v.marshalWriter(f, v.config, configType)
|
||||
}
|
||||
|
||||
// WriteConfig writes the current configuration to a file.
|
||||
func WriteConfig() error { return v.WriteConfig() }
|
||||
func (v *Viper) WriteConfig() error {
|
||||
filename, err := v.getConfigFile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return v.writeConfig(filename, true)
|
||||
}
|
||||
|
||||
// SafeWriteConfig writes current configuration to file only if the file does not exist.
|
||||
func SafeWriteConfig() error { return v.SafeWriteConfig() }
|
||||
func (v *Viper) SafeWriteConfig() error {
|
||||
filename, err := v.getConfigFile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return v.writeConfig(filename, false)
|
||||
}
|
||||
|
||||
// WriteConfigAs writes current configuration to a given filename.
|
||||
func WriteConfigAs(filename string) error { return v.WriteConfigAs(filename) }
|
||||
func (v *Viper) WriteConfigAs(filename string) error {
|
||||
return v.writeConfig(filename, true)
|
||||
}
|
||||
|
||||
// SafeWriteConfigAs writes current configuration to a given filename is it does not exist.
|
||||
func SafeWriteConfigAs(filename string) error { return v.SafeWriteConfigAs(filename) }
|
||||
func (v *Viper) SafeWriteConfigAs(filename string) error {
|
||||
return v.writeConfig(filename, false)
|
||||
}
|
||||
|
||||
// WriteConfigKey writes given key and value to file.
|
||||
|
||||
// WriteConfigKeyAs writes given key and value to a given filename.
|
||||
|
||||
func keyExists(k string, m map[string]interface{}) string {
|
||||
lk := strings.ToLower(k)
|
||||
for mk := range m {
|
||||
|
@ -1265,6 +1332,15 @@ func (v *Viper) unmarshalReader(in io.Reader, c map[string]interface{}) error {
|
|||
return unmarshallConfigReader(in, c, v.getConfigType())
|
||||
}
|
||||
|
||||
// Marshal a map into Writer.
|
||||
func marshalWriter(out afero.File, c map[string]interface{}, configType string) error {
|
||||
return v.marshalWriter(out, c, configType)
|
||||
}
|
||||
|
||||
func (v *Viper) marshalWriter(out afero.File, c map[string]interface{}, configType string) error {
|
||||
return marshalConfigWriter(out, c, configType)
|
||||
}
|
||||
|
||||
func (v *Viper) insensitiviseMaps() {
|
||||
insensitiviseMap(v.config)
|
||||
insensitiviseMap(v.defaults)
|
||||
|
|
Loading…
Add table
Reference in a new issue