config-go/config.go
2018-08-22 16:09:43 +09:00

139 lines
2.9 KiB
Go

package config
import (
"bytes"
"fmt"
"io"
"os"
"path/filepath"
)
const (
ConfigEnvPrefix = "CONFIG_ENV_PREFIX"
ConfigTagEnv = "env"
)
type Config interface {
SetConfigPath(in string) error
Load(target interface{}, files ...string) error
LoadReader(target interface{}, ext string, in io.Reader) error
SetEnvPrefix(in string)
}
type configuration struct {
configPath string
// Name of file to look for inside the path
envPrefix string
}
func New() Config {
return &configuration{}
}
var _c *configuration
func init() {
_c = New().(*configuration)
}
// SetConfigPath set a path to search for the config file in.
func SetConfigPath(in string) error { return _c.SetConfigPath(in) }
func (c *configuration) SetConfigPath(in string) error {
if in != "" {
absin, err := ABSPathify(in)
if nil != err {
return err
}
c.configPath = absin
}
return nil
}
// SetEnvPrefix set a prefix to search for the env variable.
func SetEnvPrefix(in string) { _c.SetEnvPrefix(in) }
func (c *configuration) SetEnvPrefix(in string) {
if in != "" {
c.envPrefix = in
}
}
// Load will unmarshal from configuration file from disk
func Load(target interface{}, files ...string) error {
return _c.Load(target, files...)
}
func (c *configuration) Load(target interface{}, files ...string) error {
filenames := c.getConfigFiles(files...)
if 0 == len(filenames) {
return fmt.Errorf("Config: have no config files in [%v]", files)
}
for _, file := range filenames {
if err := unmarshalFile(target, file); err != nil {
return err
}
}
return unmarshalTags(target, c.getENVPrefix())
}
// LoadReader will unmarshal from configuration bytes
func LoadReader(target interface{}, ext string, in io.Reader) error {
return _c.LoadReader(target, ext, in)
}
func (c *configuration) LoadReader(target interface{}, ext string, in io.Reader) error {
buf := new(bytes.Buffer)
buf.ReadFrom(in)
return unmarshalData(target, ext, buf.Bytes())
}
// Save store to configuration file from disk
func Save(target interface{}, file string, overWrite bool) error {
var absPath string
var err error
if absPath, err = ABSPathify(file); nil != err {
return err
}
return marshalFile(target, absPath, overWrite)
}
// 1. file
// 2. configPath/file
func (c *configuration) getConfigFiles(files ...string) []string {
var results []string
for _, file := range files {
// check configuration
if absin, err := ABSPathify(file); nil == err {
if Exists(absin) {
results = append(results, absin)
}
}
}
for _, file := range files {
// check configuration
if absin, err := ABSPathify(filepath.Join(c.configPath, file)); nil == err {
if Exists(absin) {
results = append(results, absin)
}
}
}
return results
}
func (c *configuration) getENVPrefix() string {
if c.envPrefix == "" {
if prefix := os.Getenv(ConfigEnvPrefix); prefix != "" {
return prefix
}
return ""
}
return c.envPrefix
}