1
0
mirror of https://github.com/astaxie/beego.git synced 2024-11-22 10:40:55 +00:00

Change key format

key format : ${ENV_PART||defaultValue} or  ${ENV_PART}
This commit is contained in:
ysqi 2016-03-29 21:47:33 +08:00
parent 5bd7d8c43f
commit 7e65338c87
10 changed files with 105 additions and 93 deletions

View File

@ -43,7 +43,6 @@ package config
import ( import (
"fmt" "fmt"
"os" "os"
"strings"
) )
// Configer defines how to get and set value from configuration raw data. // Configer defines how to get and set value from configuration raw data.
@ -107,17 +106,17 @@ func NewConfigData(adapterName string, data []byte) (Configer, error) {
return adapter.ParseData(data) return adapter.ParseData(data)
} }
// ChooseRealValueForMap convert all string value with environment variable. // ExpandValueEnvForMap convert all string value with environment variable.
func ChooseRealValueForMap(m map[string]interface{}) map[string]interface{} { func ExpandValueEnvForMap(m map[string]interface{}) map[string]interface{} {
for k, v := range m { for k, v := range m {
switch value := v.(type) { switch value := v.(type) {
case string: case string:
m[k] = ChooseRealValue(value) m[k] = ExpandValueEnv(value)
case map[string]interface{}: case map[string]interface{}:
m[k] = ChooseRealValueForMap(value) m[k] = ExpandValueEnvForMap(value)
case map[string]string: case map[string]string:
for k2, v2 := range value { for k2, v2 := range value {
value[k2] = ChooseRealValue(v2) value[k2] = ExpandValueEnv(v2)
} }
m[k] = value m[k] = value
} }
@ -125,40 +124,46 @@ func ChooseRealValueForMap(m map[string]interface{}) map[string]interface{} {
return m return m
} }
// ChooseRealValue returns value of convert with environment variable. // ExpandValueEnv returns value of convert with environment variable.
// //
// Return environment variable if value start with "$$". // Return environment variable if value start with "${" and end with "}".
// Return default value if environment variable is empty or not exist. // Return default value if environment variable is empty or not exist.
// //
// It accept value formats "$$env" , "$$env||" , "$$env||defaultValue" , "defaultvalue". // It accept value formats "${env}" , "${env||}}" , "${env||defaultValue}" , "defaultvalue".
// Examples: // Examples:
// v1 := config.ChooseRealValue("$$GOPATH") // return the GOPATH environment variable. // v1 := config.ExpandValueEnv("${GOPATH}") // return the GOPATH environment variable.
// v2 := config.ChooseRealValue("$$GOAsta||/usr/local/go/") // return the default value "/usr/local/go/". // v2 := config.ExpandValueEnv("${GOAsta||/usr/local/go}") // return the default value "/usr/local/go/".
// v3 := config.ChooseRealValue("Astaxie") // return the value "Astaxie". // v3 := config.ExpandValueEnv("Astaxie") // return the value "Astaxie".
func ChooseRealValue(value string) (realValue string) { func ExpandValueEnv(value string) (realValue string) {
realValue = value realValue = value
if value == "" { vLen := len(value)
// 3 = ${}
if vLen < 3 {
return
}
// Need start with "${" and end with "}", then return.
if value[0] != '$' || value[1] != '{' || value[vLen-1] != '}' {
return return
} }
sign := "$$" // Environment variable identifier. key := ""
sep := "||" // Environment variable and default value separator. defalutV := ""
// value start with "${"
// Not use environment variable. for i := 2; i < vLen; i++ {
if strings.HasPrefix(value, sign) == false { if value[i] == '|' && (i+1 < vLen && value[i+1] == '|') {
return key = value[2:i]
defalutV = value[i+2 : vLen-1] // other string is default value.
break
} else if value[i] == '}' {
key = value[2:i]
break
}
} }
sepIndex := strings.Index(value, sep) realValue = os.Getenv(key)
if sepIndex == -1 {
realValue = os.Getenv(string(value[len(sign):]))
} else {
realValue = os.Getenv(string(value[len(sign):sepIndex]))
// Find defalut value.
if realValue == "" { if realValue == "" {
realValue = string(value[sepIndex+len(sep):]) realValue = defalutV
}
} }
return return

55
config/config_test.go Normal file
View File

@ -0,0 +1,55 @@
// Copyright 2016 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package config
import (
"os"
"testing"
)
func TestExpandValueEnv(t *testing.T) {
testCases := []struct {
item string
want string
}{
{"", ""},
{"$", "$"},
{"{", "{"},
{"{}", "{}"},
{"${}", ""},
{"${|}", ""},
{"${}", ""},
{"${{}}", ""},
{"${{||}}", "}"},
{"${pwd||}", ""},
{"${pwd||}", ""},
{"${pwd||}", ""},
{"${pwd||}}", "}"},
{"${pwd||{{||}}}", "{{||}}"},
{"${GOPATH}", os.Getenv("GOPATH")},
{"${GOPATH||}", os.Getenv("GOPATH")},
{"${GOPATH||root}", os.Getenv("GOPATH")},
{"${GOPATH_NOT||root}", "root"},
{"${GOPATH_NOT||||root}", "||root"},
}
for _, c := range testCases {
if got := ExpandValueEnv(c.item); got != c.want {
t.Errorf("expand value error, item %q want %q, got %q", c.item, c.want, got)
}
}
}

View File

@ -166,7 +166,7 @@ func (ini *IniConfig) parseFile(name string) (*IniConfigContainer, error) {
val = bytes.Trim(val, `"`) val = bytes.Trim(val, `"`)
} }
cfg.data[section][key] = ChooseRealValue(string(val)) cfg.data[section][key] = ExpandValueEnv(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()

View File

@ -42,20 +42,14 @@ needlogin = ON
enableSession = Y enableSession = Y
enableCookie = N enableCookie = N
flag = 1 flag = 1
path1 = $$GOPATH path1 = ${GOPATH}
path2 = $$GOPATH||/home/go path2 = ${GOPATH||/home/go}
path3 = $$GOPATH$$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 = $$GOPATH password = ${GOPATH}
` `
keyValue = map[string]interface{}{ keyValue = map[string]interface{}{
@ -75,12 +69,6 @@ password = $$GOPATH
"flag": true, "flag": true,
"path1": os.Getenv("GOPATH"), "path1": os.Getenv("GOPATH"),
"path2": os.Getenv("GOPATH"), "path2": os.Getenv("GOPATH"),
"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,

View File

@ -58,7 +58,7 @@ func (js *JSONConfig) ParseData(data []byte) (Configer, error) {
x.data["rootArray"] = wrappingArray x.data["rootArray"] = wrappingArray
} }
x.data = ChooseRealValueForMap(x.data) x.data = ExpandValueEnvForMap(x.data)
return x, nil return x, nil
} }

View File

@ -86,25 +86,19 @@ func TestJson(t *testing.T) {
"enableSession": "Y", "enableSession": "Y",
"enableCookie": "N", "enableCookie": "N",
"flag": 1, "flag": 1,
"path1": "$$GOPATH", "path1": "${GOPATH}",
"path2": "$$GOPATH||/home/go", "path2": "${GOPATH||/home/go}",
"path3": "$$GOPATH$$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": "$$GOPATH", "password": "${GOPATH}",
"conns":{ "conns":{
"maxconnection":12, "maxconnection":12,
"autoconnect":true, "autoconnect":true,
"connectioninfo":"info", "connectioninfo":"info",
"root": "$$GOPATH" "root": "${GOPATH}"
} }
} }
}` }`
@ -126,12 +120,6 @@ func TestJson(t *testing.T) {
"flag": true, "flag": true,
"path1": os.Getenv("GOPATH"), "path1": os.Getenv("GOPATH"),
"path2": os.Getenv("GOPATH"), "path2": os.Getenv("GOPATH"),
"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",

View File

@ -69,7 +69,7 @@ func (xc *Config) Parse(filename string) (config.Configer, error) {
return nil, err return nil, err
} }
x.data = config.ChooseRealValueForMap(d["config"].(map[string]interface{})) x.data = config.ExpandValueEnvForMap(d["config"].(map[string]interface{}))
return x, nil return x, nil
} }

View File

@ -35,14 +35,8 @@ func TestXML(t *testing.T) {
<runmode>dev</runmode> <runmode>dev</runmode>
<autorender>false</autorender> <autorender>false</autorender>
<copyrequestbody>true</copyrequestbody> <copyrequestbody>true</copyrequestbody>
<path1>$$GOPATH</path1> <path1>${GOPATH}</path1>
<path2>$$GOPATH||/home/go</path2> <path2>${GOPATH||/home/go}</path2>
<path3>$$GOPATH$$GOPATH2||/home/go</path3>
<token1>$$TOKEN</token1>
<token2>$$TOKEN||</token2>
<token3>$$TOKEN||astaxie</token3>
<token4>token$$TOKEN</token4>
<token5>$$TOKEN$$TOKEN||TOKEN</token5>
</config> </config>
` `
keyValue = map[string]interface{}{ keyValue = map[string]interface{}{
@ -55,12 +49,6 @@ func TestXML(t *testing.T) {
"copyrequestbody": true, "copyrequestbody": true,
"path1": os.Getenv("GOPATH"), "path1": os.Getenv("GOPATH"),
"path2": os.Getenv("GOPATH"), "path2": os.Getenv("GOPATH"),
"path3": "/home/go",
"token1": "",
"token2": "",
"token3": "astaxie",
"token4": "token$$TOKEN",
"token5": "TOKEN",
"error": "", "error": "",
"emptystrings": []string{}, "emptystrings": []string{},
} }

View File

@ -110,7 +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) cnf = config.ExpandValueEnvForMap(cnf)
return return
} }

View File

@ -34,14 +34,8 @@ func TestYaml(t *testing.T) {
"autorender": false "autorender": false
"copyrequestbody": true "copyrequestbody": true
"PATH": GOPATH "PATH": GOPATH
"path1": $$GOPATH "path1": ${GOPATH}
"path2": $$GOPATH||/home/go "path2": ${GOPATH||/home/go}
"path3": $$GOPATH$$GOPATH2||/home/go
"token1": $$TOKEN
"token2": $$TOKEN||
"token3": $$TOKEN||astaxie
"token4": token$$TOKEN
"token5": $$TOKEN$$TOKEN||TOKEN
"empty": "" "empty": ""
` `
@ -56,12 +50,6 @@ func TestYaml(t *testing.T) {
"PATH": "GOPATH", "PATH": "GOPATH",
"path1": os.Getenv("GOPATH"), "path1": os.Getenv("GOPATH"),
"path2": os.Getenv("GOPATH"), "path2": os.Getenv("GOPATH"),
"path3": "/home/go",
"token1": "",
"token2": "",
"token3": "astaxie",
"token4": "token$$TOKEN",
"token5": "TOKEN",
"error": "", "error": "",
"emptystrings": []string{}, "emptystrings": []string{},
} }