mirror of
https://github.com/astaxie/beego.git
synced 2024-11-22 10:20:56 +00:00
Change key format
key format : ${ENV_PART||defaultValue} or ${ENV_PART}
This commit is contained in:
parent
5bd7d8c43f
commit
7e65338c87
@ -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
55
config/config_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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()
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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{},
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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{},
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user