2017-08-30 09:24:22 +00:00
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
)
|
|
|
|
|
2017-09-19 05:44:45 +00:00
|
|
|
const (
|
|
|
|
ConfigEnvPrefix = "CONFIG_ENV_PREFIX"
|
|
|
|
ConfigTagEnv = "env"
|
|
|
|
)
|
2017-08-30 09:24:22 +00:00
|
|
|
|
|
|
|
type Configurator interface {
|
2017-09-19 05:44:45 +00:00
|
|
|
SetConfigPath(in string) error
|
|
|
|
Load(target interface{}, files ...string) error
|
|
|
|
LoadReader(target interface{}, ext string, in io.Reader) error
|
|
|
|
Save(target interface{}, file string, overWrite bool) error
|
|
|
|
|
2017-08-30 10:41:51 +00:00
|
|
|
SetEnvPrefix(in string)
|
2017-08-30 09:24:22 +00:00
|
|
|
}
|
|
|
|
|
2017-09-19 05:44:45 +00:00
|
|
|
type config struct {
|
|
|
|
configPath string
|
2017-08-30 09:24:22 +00:00
|
|
|
// Name of file to look for inside the path
|
2017-09-19 05:44:45 +00:00
|
|
|
envPrefix string
|
2017-08-30 09:24:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func New() Configurator {
|
2017-09-19 05:44:45 +00:00
|
|
|
return &config{}
|
2017-08-30 09:24:22 +00:00
|
|
|
}
|
|
|
|
|
2017-09-19 05:44:45 +00:00
|
|
|
var _c *config
|
2017-08-30 09:24:22 +00:00
|
|
|
|
2017-09-19 05:44:45 +00:00
|
|
|
// SetConfigPath set a path to search for the config file in.
|
|
|
|
func SetConfigPath(in string) error { return _c.SetConfigPath(in) }
|
|
|
|
func (c *config) SetConfigPath(in string) error {
|
2017-08-30 09:24:22 +00:00
|
|
|
if in != "" {
|
|
|
|
absin, err := absPathify(in)
|
|
|
|
if nil != err {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2017-09-19 05:44:45 +00:00
|
|
|
c.configPath = absin
|
2017-08-30 09:24:22 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-09-19 05:44:45 +00:00
|
|
|
// SetEnvPrefix set a prefix to search for the env variable.
|
|
|
|
func SetEnvPrefix(in string) { _c.SetEnvPrefix(in) }
|
|
|
|
func (c *config) SetEnvPrefix(in string) {
|
|
|
|
if in != "" {
|
|
|
|
c.envPrefix = in
|
2017-08-30 09:24:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-19 05:44:45 +00:00
|
|
|
// Load will unmarshal from configuration file from disk
|
|
|
|
func Load(target interface{}, files ...string) error {
|
|
|
|
return _c.Load(target, files...)
|
2017-08-30 09:24:22 +00:00
|
|
|
}
|
2017-09-19 05:44:45 +00:00
|
|
|
func (c *config) Load(target interface{}, files ...string) error {
|
|
|
|
filenames := c.getConfigFiles(files...)
|
2017-08-30 09:24:22 +00:00
|
|
|
|
2017-09-19 05:44:45 +00:00
|
|
|
for _, file := range filenames {
|
|
|
|
if err := unmarshalFile(target, file); err != nil {
|
|
|
|
return err
|
2017-08-30 09:24:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-19 05:44:45 +00:00
|
|
|
return unmarshalTags(target, c.getENVPrefix())
|
2017-08-30 11:28:19 +00:00
|
|
|
}
|
|
|
|
|
2017-09-19 05:44:45 +00:00
|
|
|
// LoadReader will unmarshal from configuration bytes
|
|
|
|
func LoadReader(target interface{}, ext string, in io.Reader) error {
|
|
|
|
return _c.LoadReader(target, ext, in)
|
2017-08-30 09:24:22 +00:00
|
|
|
}
|
2017-09-19 05:44:45 +00:00
|
|
|
func (c *config) LoadReader(target interface{}, ext string, in io.Reader) error {
|
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
buf.ReadFrom(in)
|
2017-08-30 09:24:22 +00:00
|
|
|
|
2017-09-19 05:44:45 +00:00
|
|
|
return unmarshalData(target, ext, buf.Bytes())
|
2017-08-30 09:24:22 +00:00
|
|
|
}
|
|
|
|
|
2017-09-19 05:44:45 +00:00
|
|
|
// Save store to configuration file from disk
|
|
|
|
func Save(target interface{}, file string, overWrite bool) error {
|
|
|
|
return _c.Save(target, file, overWrite)
|
2017-08-30 09:24:22 +00:00
|
|
|
}
|
2017-09-19 05:44:45 +00:00
|
|
|
func (c *config) Save(target interface{}, file string, overWrite bool) error {
|
|
|
|
return marshalFile(target, file, overWrite)
|
2017-08-30 09:24:22 +00:00
|
|
|
}
|
|
|
|
|
2017-09-19 05:44:45 +00:00
|
|
|
// 1. file
|
|
|
|
// 2. configPath/file
|
|
|
|
func (c *config) getConfigFiles(files ...string) []string {
|
|
|
|
var results []string
|
2017-08-30 09:24:22 +00:00
|
|
|
|
2017-09-19 05:44:45 +00:00
|
|
|
for _, file := range files {
|
|
|
|
// check configuration
|
|
|
|
if exists(file) {
|
|
|
|
results = append(results, file)
|
2017-08-30 09:24:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-19 05:44:45 +00:00
|
|
|
for _, file := range files {
|
|
|
|
// check configuration
|
2017-09-19 05:59:22 +00:00
|
|
|
if absin, err := absPathify(filepath.Join(c.configPath, file)); nil == err {
|
|
|
|
if exists(absin) {
|
|
|
|
results = append(results, absin)
|
|
|
|
}
|
2017-08-30 09:24:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-19 05:44:45 +00:00
|
|
|
return results
|
2017-08-30 09:24:22 +00:00
|
|
|
}
|
|
|
|
|
2017-09-19 05:44:45 +00:00
|
|
|
func (c *config) getENVPrefix() string {
|
|
|
|
if c.envPrefix == "" {
|
|
|
|
if prefix := os.Getenv(ConfigEnvPrefix); prefix != "" {
|
|
|
|
return prefix
|
2017-08-30 09:24:22 +00:00
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}
|
2017-09-19 05:44:45 +00:00
|
|
|
return c.envPrefix
|
2017-08-30 09:24:22 +00:00
|
|
|
}
|