Commit b2a06c5f authored by ysqi's avatar ysqi

Update config suport environment variable logic

parent 86c7f1db
...@@ -12,11 +12,10 @@ ...@@ -12,11 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package config is used to parse config // Package config is used to parse config.
// Usage: // Usage:
// import( // import "github.com/astaxie/beego/config"
// "github.com/astaxie/beego/config" //Examples.
// )
// //
// cnf, err := config.NewConfig("ini", "config.conf") // cnf, err := config.NewConfig("ini", "config.conf")
// //
...@@ -38,8 +37,7 @@ ...@@ -38,8 +37,7 @@
// cnf.DIY(key string) (interface{}, error) // cnf.DIY(key string) (interface{}, error)
// cnf.GetSection(section string) (map[string]string, error) // cnf.GetSection(section string) (map[string]string, error)
// cnf.SaveConfigFile(filename string) error // cnf.SaveConfigFile(filename string) error
// //More docs http://beego.me/docs/module/config.md
// more docs http://beego.me/docs/module/config.md
package config package config
import ( import (
...@@ -109,52 +107,61 @@ func NewConfigData(adapterName string, data []byte) (Configer, error) { ...@@ -109,52 +107,61 @@ func NewConfigData(adapterName string, data []byte) (Configer, error) {
return adapter.ParseData(data) return adapter.ParseData(data)
} }
const envKeySign = "$ENV_" // ChooseRealValueForMap convert all string value with environment variable.
func ChooseRealValueForMap(m map[string]interface{}) map[string]interface{} {
// Getenv return environment variable if env has prefix "$ENV_". for k, v := range m {
func Getenv(env interface{}) (string, bool) { switch value := v.(type) {
if env == nil { case string:
return "", false m[k] = ChooseRealValue(value)
} case map[string]interface{}:
m[k] = ChooseRealValueForMap(value)
// Onley support string key. case map[string]string:
if key, ok := env.(string); ok { for k2, v2 := range value {
value[k2] = ChooseRealValue(v2)
if envKey := strings.TrimPrefix(key, envKeySign); envKey != key { }
return os.Getenv(envKey), true m[k] = value
} }
} }
return "", false return m
} }
// ConvertToStringMap convert interface to string config value only for map[string]interface{} config info. // ChooseRealValue returns value of convert with environment variable.
func ConvertToStringMap(m map[string]interface{}) map[string]string { //
items := make(map[string]string, len(m)) // Return environment variable if value start with "$$".
if m == nil || len(m) == 0 { // Return default value if environment variable is empty or not exist.
return items //
// It accept value formats "$$env" , "$$env||" , "$$env||defaultValue" , "defaultvalue".
// Examples:
// v1 := config.ChooseRealValue("$$GOROOT") // return the GOROOT environment variable.
// v2 := config.ChooseRealValue("$$GOAsta||/usr/local/go/") // return the default value "/usr/local/go/".
// v3 := config.ChooseRealValue("Astaxie") // return the value "Astaxie".
func ChooseRealValue(value string) (realValue string) {
realValue = value
if value == "" {
return
} }
var s string sign := "$$" // Environment variable identifier.
for k, v := range m { sep := "||" // Environment variable and default value separator.
s = ""
if v == nil {
s = ""
} else if str, ok := v.(string); ok {
s = str
} else if m, ok := v.(map[string]interface{}); ok {
s = fmt.Sprintf("%+v", ConvertToStringMap(m))
} else {
s = fmt.Sprintf("%+v", v)
}
if len(s) > 0 { // Not use environment variable.
if env, ok := Getenv(s); ok { if strings.HasPrefix(value, sign) == false {
s = env return
} }
sepIndex := strings.Index(value, sep)
if sepIndex == -1 {
realValue = os.Getenv(string(value[len(sign):]))
} else {
realValue = os.Getenv(string(value[len(sign):sepIndex]))
// Find defalut value.
if realValue == "" {
realValue = string(value[sepIndex+len(sep):])
} }
items[k] = s
} }
return items
return
} }
// ParseBool returns the boolean value represented by the string. // ParseBool returns the boolean value represented by the string.
......
...@@ -25,15 +25,7 @@ type fakeConfigContainer struct { ...@@ -25,15 +25,7 @@ type fakeConfigContainer struct {
} }
func (c *fakeConfigContainer) getData(key string) string { func (c *fakeConfigContainer) getData(key string) string {
if len(key) == 0 { return c.data[strings.ToLower(key)]
return ""
}
v := c.data[strings.ToLower(key)]
if env, ok := Getenv(v); ok {
return env
}
return v
} }
func (c *fakeConfigContainer) Set(key, val string) error { func (c *fakeConfigContainer) Set(key, val string) error {
......
...@@ -162,7 +162,7 @@ func (ini *IniConfig) parseFile(name string) (*IniConfigContainer, error) { ...@@ -162,7 +162,7 @@ func (ini *IniConfig) parseFile(name string) (*IniConfigContainer, error) {
val = bytes.Trim(val, `"`) val = bytes.Trim(val, `"`)
} }
cfg.data[section][key] = string(val) cfg.data[section][key] = ChooseRealValue(string(val))
if comment.Len() > 0 { if comment.Len() > 0 {
cfg.keyComment[section+"."+key] = comment.String() cfg.keyComment[section+"."+key] = comment.String()
comment.Reset() comment.Reset()
...@@ -291,17 +291,14 @@ func (c *IniConfigContainer) DefaultStrings(key string, defaultval []string) []s ...@@ -291,17 +291,14 @@ func (c *IniConfigContainer) DefaultStrings(key string, defaultval []string) []s
// GetSection returns map for the given section // GetSection returns map for the given section
func (c *IniConfigContainer) GetSection(section string) (map[string]string, error) { func (c *IniConfigContainer) GetSection(section string) (map[string]string, error) {
if v, ok := c.data[section]; ok { if v, ok := c.data[section]; ok {
for k, vv := range v {
if env, ok := Getenv(vv); ok {
v[k] = env
}
}
return v, nil return v, nil
} }
return nil, errors.New("not exist setction") return nil, errors.New("not exist setction")
} }
// SaveConfigFile save the config into file // SaveConfigFile save the config into file.
//
// BUG(env): The environment variable config item will be saved with real value in SaveConfigFile Funcation.
func (c *IniConfigContainer) SaveConfigFile(filename string) (err error) { func (c *IniConfigContainer) SaveConfigFile(filename string) (err error) {
// Write configuration file by filename. // Write configuration file by filename.
f, err := os.Create(filename) f, err := os.Create(filename)
...@@ -458,9 +455,6 @@ func (c *IniConfigContainer) getdata(key string) string { ...@@ -458,9 +455,6 @@ func (c *IniConfigContainer) getdata(key string) string {
} }
if v, ok := c.data[section]; ok { if v, ok := c.data[section]; ok {
if vv, ok := v[k]; ok { if vv, ok := v[k]; ok {
if env, ok := Getenv(vv); ok {
return env
}
return vv return vv
} }
} }
......
...@@ -42,13 +42,20 @@ needlogin = ON ...@@ -42,13 +42,20 @@ needlogin = ON
enableSession = Y enableSession = Y
enableCookie = N enableCookie = N
flag = 1 flag = 1
path = $ENV_GOROOT path1 = $$GOROOT
path2 = $$GOROOT||/home/go
path3 = $$GOROOT$$GOPATH2||/home/go
token1 = $$TOKEN
token2 = $$TOKEN||
token3 = $$TOKEN||astaxie
token4 = token$$TOKEN
token5 = $$TOKEN$$TOKEN||TOKEN
[demo] [demo]
key1="asta" key1="asta"
key2 = "xie" key2 = "xie"
CaseInsensitive = true CaseInsensitive = true
peers = one;two;three peers = one;two;three
password = $ENV_GOROOT password = $$GOROOT
` `
keyValue = map[string]interface{}{ keyValue = map[string]interface{}{
...@@ -66,7 +73,14 @@ password = $ENV_GOROOT ...@@ -66,7 +73,14 @@ password = $ENV_GOROOT
"enableSession": true, "enableSession": true,
"enableCookie": false, "enableCookie": false,
"flag": true, "flag": true,
"path": os.Getenv("GOROOT"), "path1": os.Getenv("GOROOT"),
"path2": os.Getenv("GOROOT"),
"path3": "/home/go",
"token1": "",
"token2": "",
"token3": "astaxie",
"token4": "token$$TOKEN",
"token5": "TOKEN",
"demo::key1": "asta", "demo::key1": "asta",
"demo::key2": "xie", "demo::key2": "xie",
"demo::CaseInsensitive": true, "demo::CaseInsensitive": true,
...@@ -145,7 +159,6 @@ httpport = 8080 ...@@ -145,7 +159,6 @@ httpport = 8080
# db type name # db type name
# suport mysql,sqlserver # suport mysql,sqlserver
name = mysql name = mysql
path = $ENV_GOROOT
` `
saveResult = ` saveResult = `
...@@ -162,7 +175,6 @@ httpport=8080 ...@@ -162,7 +175,6 @@ httpport=8080
# db type name # db type name
# suport mysql,sqlserver # suport mysql,sqlserver
name=mysql name=mysql
path=$ENV_GOROOT
` `
) )
cfg, err := NewConfigData("ini", []byte(inicontext)) cfg, err := NewConfigData("ini", []byte(inicontext))
......
...@@ -57,6 +57,9 @@ func (js *JSONConfig) ParseData(data []byte) (Configer, error) { ...@@ -57,6 +57,9 @@ func (js *JSONConfig) ParseData(data []byte) (Configer, error) {
} }
x.data["rootArray"] = wrappingArray x.data["rootArray"] = wrappingArray
} }
x.data = ChooseRealValueForMap(x.data)
return x, nil return x, nil
} }
...@@ -250,18 +253,11 @@ func (c *JSONConfigContainer) getData(key string) interface{} { ...@@ -250,18 +253,11 @@ func (c *JSONConfigContainer) getData(key string) interface{} {
} }
} }
} }
if env, ok := Getenv(curValue); ok {
return env
}
return curValue return curValue
} }
if v, ok := c.data[key]; ok { if v, ok := c.data[key]; ok {
if env, ok := Getenv(v); ok {
return env
}
return v return v
} }
return nil return nil
} }
......
...@@ -86,18 +86,25 @@ func TestJson(t *testing.T) { ...@@ -86,18 +86,25 @@ func TestJson(t *testing.T) {
"enableSession": "Y", "enableSession": "Y",
"enableCookie": "N", "enableCookie": "N",
"flag": 1, "flag": 1,
"path": "$ENV_GOROOT", "path1": "$$GOROOT",
"path2": "$$GOROOT||/home/go",
"path3": "$$GOROOT$$GOPATH2||/home/go",
"token1": "$$TOKEN",
"token2": "$$TOKEN||",
"token3": "$$TOKEN||astaxie",
"token4": "token$$TOKEN",
"token5": "$$TOKEN$$TOKEN||TOKEN",
"database": { "database": {
"host": "host", "host": "host",
"port": "port", "port": "port",
"database": "database", "database": "database",
"username": "username", "username": "username",
"password": "$ENV_GOROOT", "password": "$$GOROOT",
"conns":{ "conns":{
"maxconnection":12, "maxconnection":12,
"autoconnect":true, "autoconnect":true,
"connectioninfo":"info", "connectioninfo":"info",
"root": "$ENV_GOROOT" "root": "$$GOROOT"
} }
} }
}` }`
...@@ -117,7 +124,14 @@ func TestJson(t *testing.T) { ...@@ -117,7 +124,14 @@ func TestJson(t *testing.T) {
"enableSession": true, "enableSession": true,
"enableCookie": false, "enableCookie": false,
"flag": true, "flag": true,
"path": os.Getenv("GOROOT"), "path1": os.Getenv("GOROOT"),
"path2": os.Getenv("GOROOT"),
"path3": "/home/go",
"token1": "",
"token2": "",
"token3": "astaxie",
"token4": "token$$TOKEN",
"token5": "TOKEN",
"database::host": "host", "database::host": "host",
"database::port": "port", "database::port": "port",
"database::database": "database", "database::database": "database",
......
...@@ -12,21 +12,21 @@ ...@@ -12,21 +12,21 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package xml for config provider // Package xml for config provider.
// //
// depend on github.com/beego/x2j // depend on github.com/beego/x2j.
// //
// go install github.com/beego/x2j // go install github.com/beego/x2j.
// //
// Usage: // Usage:
// import( // import(
// _ "github.com/astaxie/beego/config/xml" // _ "github.com/astaxie/beego/config/xml"
// "github.com/astaxie/beego/config" // "github.com/astaxie/beego/config"
// ) // )
// //
// cnf, err := config.NewConfig("xml", "config.xml") // cnf, err := config.NewConfig("xml", "config.xml")
// //
// more docs http://beego.me/docs/module/config.md //More docs http://beego.me/docs/module/config.md
package xml package xml
import ( import (
...@@ -69,7 +69,7 @@ func (xc *Config) Parse(filename string) (config.Configer, error) { ...@@ -69,7 +69,7 @@ func (xc *Config) Parse(filename string) (config.Configer, error) {
return nil, err return nil, err
} }
x.data = d["config"].(map[string]interface{}) x.data = config.ChooseRealValueForMap(d["config"].(map[string]interface{}))
return x, nil return x, nil
} }
...@@ -92,7 +92,7 @@ type ConfigContainer struct { ...@@ -92,7 +92,7 @@ type ConfigContainer struct {
// Bool returns the boolean value for a given key. // Bool returns the boolean value for a given key.
func (c *ConfigContainer) Bool(key string) (bool, error) { func (c *ConfigContainer) Bool(key string) (bool, error) {
if v := c.getData(key); v != nil { if v := c.data[key]; v != nil {
return config.ParseBool(v) return config.ParseBool(v)
} }
return false, fmt.Errorf("not exist key: %q", key) return false, fmt.Errorf("not exist key: %q", key)
...@@ -110,7 +110,7 @@ func (c *ConfigContainer) DefaultBool(key string, defaultval bool) bool { ...@@ -110,7 +110,7 @@ func (c *ConfigContainer) DefaultBool(key string, defaultval bool) bool {
// Int returns the integer value for a given key. // Int returns the integer value for a given key.
func (c *ConfigContainer) Int(key string) (int, error) { func (c *ConfigContainer) Int(key string) (int, error) {
return strconv.Atoi(c.getData(key).(string)) return strconv.Atoi(c.data[key].(string))
} }
// DefaultInt returns the integer value for a given key. // DefaultInt returns the integer value for a given key.
...@@ -125,7 +125,7 @@ func (c *ConfigContainer) DefaultInt(key string, defaultval int) int { ...@@ -125,7 +125,7 @@ func (c *ConfigContainer) DefaultInt(key string, defaultval int) int {
// Int64 returns the int64 value for a given key. // Int64 returns the int64 value for a given key.
func (c *ConfigContainer) Int64(key string) (int64, error) { func (c *ConfigContainer) Int64(key string) (int64, error) {
return strconv.ParseInt(c.getData(key).(string), 10, 64) return strconv.ParseInt(c.data[key].(string), 10, 64)
} }
// DefaultInt64 returns the int64 value for a given key. // DefaultInt64 returns the int64 value for a given key.
...@@ -141,7 +141,7 @@ func (c *ConfigContainer) DefaultInt64(key string, defaultval int64) int64 { ...@@ -141,7 +141,7 @@ func (c *ConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
// Float returns the float value for a given key. // Float returns the float value for a given key.
func (c *ConfigContainer) Float(key string) (float64, error) { func (c *ConfigContainer) Float(key string) (float64, error) {
return strconv.ParseFloat(c.getData(key).(string), 64) return strconv.ParseFloat(c.data[key].(string), 64)
} }
// DefaultFloat returns the float64 value for a given key. // DefaultFloat returns the float64 value for a given key.
...@@ -156,7 +156,7 @@ func (c *ConfigContainer) DefaultFloat(key string, defaultval float64) float64 { ...@@ -156,7 +156,7 @@ func (c *ConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
// String returns the string value for a given key. // String returns the string value for a given key.
func (c *ConfigContainer) String(key string) string { func (c *ConfigContainer) String(key string) string {
if v, ok := c.getData(key).(string); ok { if v, ok := c.data[key].(string); ok {
return v return v
} }
return "" return ""
...@@ -194,7 +194,7 @@ func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []stri ...@@ -194,7 +194,7 @@ func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []stri
// GetSection returns map for the given section // GetSection returns map for the given section
func (c *ConfigContainer) GetSection(section string) (map[string]string, error) { func (c *ConfigContainer) GetSection(section string) (map[string]string, error) {
if v, ok := c.data[section]; ok { if v, ok := c.data[section]; ok {
return config.ConvertToStringMap(v.(map[string]interface{})), nil return v.(map[string]string), nil
} }
return nil, errors.New("not exist setction") return nil, errors.New("not exist setction")
} }
...@@ -231,18 +231,6 @@ func (c *ConfigContainer) DIY(key string) (v interface{}, err error) { ...@@ -231,18 +231,6 @@ func (c *ConfigContainer) DIY(key string) (v interface{}, err error) {
return nil, errors.New("not exist key") return nil, errors.New("not exist key")
} }
// Get Data
func (c *ConfigContainer) getData(key string) interface{} {
if v, ok := c.data[key]; ok {
if env, ok := config.Getenv(v); ok {
return env
}
return v
}
return nil
}
func init() { func init() {
config.Register("xml", &Config{}) config.Register("xml", &Config{})
} }
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
package xml package xml
import ( import (
"fmt"
"os" "os"
"strings"
"testing" "testing"
"github.com/astaxie/beego/config" "github.com/astaxie/beego/config"
...@@ -24,8 +24,9 @@ import ( ...@@ -24,8 +24,9 @@ import (
func TestXML(t *testing.T) { func TestXML(t *testing.T) {
//xml parse should incluce in <config></config> tags var (
var xmlcontext = `<?xml version="1.0" encoding="UTF-8"?> //xml parse should incluce in <config></config> tags
xmlcontext = `<?xml version="1.0" encoding="UTF-8"?>
<config> <config>
<appname>beeapi</appname> <appname>beeapi</appname>
<httpport>8080</httpport> <httpport>8080</httpport>
...@@ -34,23 +35,36 @@ func TestXML(t *testing.T) { ...@@ -34,23 +35,36 @@ func TestXML(t *testing.T) {
<runmode>dev</runmode> <runmode>dev</runmode>
<autorender>false</autorender> <autorender>false</autorender>
<copyrequestbody>true</copyrequestbody> <copyrequestbody>true</copyrequestbody>
<path>$ENV_GOROOT</path> <path1>$$GOROOT</path1>
<dbinfo> <path2>$$GOROOT||/home/go</path2>
<db>beego</db> <path3>$$GOROOT$$GOPATH2||/home/go</path3>
<pwd>$ENV_GOROOT</pwd> <token1>$$TOKEN</token1>
<url>localhost</url> <token2>$$TOKEN||</token2>
<detail> <token3>$$TOKEN||astaxie</token3>
<d1>value1</d1> <token4>token$$TOKEN</token4>
<d2>$ENV_GOROOT</d2> <token5>$$TOKEN$$TOKEN||TOKEN</token5>
<d3></d3>
</detail>
<group>
<id>001</id>
<name>gp2</name>
</group>
</dbinfo>
</config> </config>
` `
keyValue = map[string]interface{}{
"appname": "beeapi",
"httpport": 8080,
"mysqlport": int64(3600),
"PI": 3.1415976,
"runmode": "dev",
"autorender": false,
"copyrequestbody": true,
"path1": os.Getenv("GOROOT"),
"path2": os.Getenv("GOROOT"),
"path3": "/home/go",
"token1": "",
"token2": "",
"token3": "astaxie",
"token4": "token$$TOKEN",
"token5": "TOKEN",
"error": "",
"emptystrings": []string{},
}
)
f, err := os.Create("testxml.conf") f, err := os.Create("testxml.conf")
if err != nil { if err != nil {
...@@ -67,50 +81,42 @@ func TestXML(t *testing.T) { ...@@ -67,50 +81,42 @@ func TestXML(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if xmlconf.String("appname") != "beeapi" {
t.Fatal("appname not equal to beeapi") for k, v := range keyValue {
}
if port, err := xmlconf.Int("httpport"); err != nil || port != 8080 { var (
t.Error(port) value interface{}
t.Fatal(err) err error
} )
if port, err := xmlconf.Int64("mysqlport"); err != nil || port != 3600 {
t.Error(port) switch v.(type) {
t.Fatal(err) case int:
} value, err = xmlconf.Int(k)
if pi, err := xmlconf.Float("PI"); err != nil || pi != 3.1415976 { case int64:
t.Error(pi) value, err = xmlconf.Int64(k)
t.Fatal(err) case float64:
} value, err = xmlconf.Float(k)
if xmlconf.String("runmode") != "dev" { case bool:
t.Fatal("runmode not equal to dev") value, err = xmlconf.Bool(k)
} case []string:
if v, err := xmlconf.Bool("autorender"); err != nil || v != false { value = xmlconf.Strings(k)
t.Error(v) case string:
t.Fatal(err) value = xmlconf.String(k)
} default:
if v, err := xmlconf.Bool("copyrequestbody"); err != nil || v != true { value, err = xmlconf.DIY(k)
t.Error(v) }
t.Fatal(err) if err != nil {
t.Errorf("get key %q value fatal,%v err %s", k, v, err)
} else if fmt.Sprintf("%v", v) != fmt.Sprintf("%v", value) {
t.Errorf("get key %q value, want %v got %v .", k, v, value)
}
} }
if err = xmlconf.Set("name", "astaxie"); err != nil { if err = xmlconf.Set("name", "astaxie"); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if xmlconf.String("name") != "astaxie" { if xmlconf.String("name") != "astaxie" {
t.Fatal("get name error") t.Fatal("get name error")
} }
if xmlconf.String("path") != os.Getenv("GOROOT") {
t.Fatal("get path error")
}
if dbinfo, err := xmlconf.GetSection("dbinfo"); err != nil {
t.Fatal(err)
} else if dbinfo["pwd"] != os.Getenv("GOROOT") {
t.Fatal("get pwd error")
} else if strings.Contains(dbinfo["detail"], os.Getenv("GOROOT")) == false {
t.Fatal("get goroot path error")
}
if xmlconf.Strings("emptystrings") != nil {
t.Fatal("get emtpy strings error")
}
} }
...@@ -19,14 +19,14 @@ ...@@ -19,14 +19,14 @@
// go install github.com/beego/goyaml2 // go install github.com/beego/goyaml2
// //
// Usage: // Usage:
// import( // import(
// _ "github.com/astaxie/beego/config/yaml" // _ "github.com/astaxie/beego/config/yaml"
// "github.com/astaxie/beego/config" // "github.com/astaxie/beego/config"
// ) // )
// //
// cnf, err := config.NewConfig("yaml", "config.yaml") // cnf, err := config.NewConfig("yaml", "config.yaml")
// //
// more docs http://beego.me/docs/module/config.md //More docs http://beego.me/docs/module/config.md
package yaml package yaml
import ( import (
...@@ -110,6 +110,7 @@ func ReadYmlReader(path string) (cnf map[string]interface{}, err error) { ...@@ -110,6 +110,7 @@ func ReadYmlReader(path string) (cnf map[string]interface{}, err error) {
log.Println("Not a Map? >> ", string(buf), data) log.Println("Not a Map? >> ", string(buf), data)
cnf = nil cnf = nil
} }
cnf = config.ChooseRealValueForMap(cnf)
return return
} }
...@@ -248,7 +249,7 @@ func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []stri ...@@ -248,7 +249,7 @@ func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []stri
func (c *ConfigContainer) GetSection(section string) (map[string]string, error) { func (c *ConfigContainer) GetSection(section string) (map[string]string, error) {
if v, ok := c.data[section]; ok { if v, ok := c.data[section]; ok {
return config.ConvertToStringMap(v.(map[string]interface{})), nil return v.(map[string]string), nil
} }
return nil, errors.New("not exist setction") return nil, errors.New("not exist setction")
} }
...@@ -285,11 +286,7 @@ func (c *ConfigContainer) getData(key string) (interface{}, error) { ...@@ -285,11 +286,7 @@ func (c *ConfigContainer) getData(key string) (interface{}, error) {
} }
if v, ok := c.data[key]; ok { if v, ok := c.data[key]; ok {
if env, ok := config.Getenv(v); ok { return v, nil
return env, nil
} else {
return v, nil
}
} }
return nil, fmt.Errorf("not exist key %q", key) return nil, fmt.Errorf("not exist key %q", key)
} }
......
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
package yaml package yaml
import ( import (
"fmt"
"os" "os"
"strings"
"testing" "testing"
"github.com/astaxie/beego/config" "github.com/astaxie/beego/config"
...@@ -33,21 +33,38 @@ func TestYaml(t *testing.T) { ...@@ -33,21 +33,38 @@ func TestYaml(t *testing.T) {
"runmode": dev "runmode": dev
"autorender": false "autorender": false
"copyrequestbody": true "copyrequestbody": true
"path": $ENV_GOROOT
"PATH": GOROOT "PATH": GOROOT
"dbinfo": "path1": $$GOROOT
"db": beego "path2": $$GOROOT||/home/go
"pwd": $ENV_GOROOT "path3": $$GOROOT$$GOPATH2||/home/go
"url": localhost "token1": $$TOKEN
"detail": "token2": $$TOKEN||
"d1": value1 "token3": $$TOKEN||astaxie
"d2": $ENV_GOROOT "token4": token$$TOKEN
"d3": "" "token5": $$TOKEN$$TOKEN||TOKEN
"group":
"id": 001
"name": gp2
"empty": "" "empty": ""
` `
keyValue = map[string]interface{}{
"appname": "beeapi",
"httpport": 8080,
"mysqlport": int64(3600),
"PI": 3.1415976,
"runmode": "dev",
"autorender": false,
"copyrequestbody": true,
"PATH": "GOROOT",
"path1": os.Getenv("GOROOT"),
"path2": os.Getenv("GOROOT"),
"path3": "/home/go",
"token1": "",
"token2": "",
"token3": "astaxie",
"token4": "token$$TOKEN",
"token5": "TOKEN",
"error": "",
"emptystrings": []string{},
}
) )
f, err := os.Create("testyaml.conf") f, err := os.Create("testyaml.conf")
if err != nil { if err != nil {
...@@ -68,29 +85,38 @@ func TestYaml(t *testing.T) { ...@@ -68,29 +85,38 @@ func TestYaml(t *testing.T) {
if yamlconf.String("appname") != "beeapi" { if yamlconf.String("appname") != "beeapi" {
t.Fatal("appname not equal to beeapi") t.Fatal("appname not equal to beeapi")
} }
if port, err := yamlconf.Int("httpport"); err != nil || port != 8080 {
t.Error(port) for k, v := range keyValue {
t.Fatal(err)
} var (
if port, err := yamlconf.Int64("mysqlport"); err != nil || port != 3600 { value interface{}
t.Error(port) err error
t.Fatal(err) )
}
if pi, err := yamlconf.Float("PI"); err != nil || pi != 3.1415976 { switch v.(type) {
t.Error(pi) case int:
t.Fatal(err) value, err = yamlconf.Int(k)
} case int64:
if yamlconf.String("runmode") != "dev" { value, err = yamlconf.Int64(k)
t.Fatal("runmode not equal to dev") case float64:
} value, err = yamlconf.Float(k)
if v, err := yamlconf.Bool("autorender"); err != nil || v != false { case bool:
t.Error(v) value, err = yamlconf.Bool(k)
t.Fatal(err) case []string:
} value = yamlconf.Strings(k)
if v, err := yamlconf.Bool("copyrequestbody"); err != nil || v != true { case string:
t.Error(v) value = yamlconf.String(k)
t.Fatal(err) default:
value, err = yamlconf.DIY(k)
}
if err != nil {
t.Errorf("get key %q value fatal,%v err %s", k, v, err)
} else if fmt.Sprintf("%v", v) != fmt.Sprintf("%v", value) {
t.Errorf("get key %q value, want %v got %v .", k, v, value)
}
} }
if err = yamlconf.Set("name", "astaxie"); err != nil { if err = yamlconf.Set("name", "astaxie"); err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -98,15 +124,4 @@ func TestYaml(t *testing.T) { ...@@ -98,15 +124,4 @@ func TestYaml(t *testing.T) {
t.Fatal("get name error") t.Fatal("get name error")
} }
if dbinfo, err := yamlconf.GetSection("dbinfo"); err != nil {
t.Fatal(err)
} else if dbinfo["pwd"] != os.Getenv("GOROOT") {
t.Fatal("get pwd error")
} else if strings.Contains(dbinfo["detail"], os.Getenv("GOROOT")) == false {
t.Fatal("get GOROOT path error")
}
if yamlconf.Strings("emptystrings") != nil {
t.Fatal("get emtpy strings error")
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment