mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
parent
9312059888
commit
4a9d408fe0
9 changed files with 133 additions and 17 deletions
|
@ -49,6 +49,15 @@ func ToParamsAndPrepare(in interface{}) (Params, bool) {
|
||||||
return m, true
|
return m, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MustToParamsAndPrepare calls ToParamsAndPrepare and panics if it fails.
|
||||||
|
func MustToParamsAndPrepare(in interface{}) Params {
|
||||||
|
if p, ok := ToParamsAndPrepare(in); ok {
|
||||||
|
return p
|
||||||
|
} else {
|
||||||
|
panic(fmt.Sprintf("cannot convert %T to maps.Params", in))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ToStringMap converts in to map[string]interface{}.
|
// ToStringMap converts in to map[string]interface{}.
|
||||||
func ToStringMap(in interface{}) map[string]interface{} {
|
func ToStringMap(in interface{}) map[string]interface{} {
|
||||||
m, _ := ToStringMapE(in)
|
m, _ := ToStringMapE(in)
|
||||||
|
|
|
@ -21,10 +21,10 @@ import (
|
||||||
qt "github.com/frankban/quicktest"
|
qt "github.com/frankban/quicktest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestToLower(t *testing.T) {
|
func TestPrepareParams(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
input map[string]interface{}
|
input Params
|
||||||
expected map[string]interface{}
|
expected Params
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
|
@ -47,6 +47,9 @@ func TestToLower(t *testing.T) {
|
||||||
"gHi": map[string]interface{}{
|
"gHi": map[string]interface{}{
|
||||||
"J": 25,
|
"J": 25,
|
||||||
},
|
},
|
||||||
|
"jKl": map[string]string{
|
||||||
|
"M": "26",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Params{
|
Params{
|
||||||
"abc": 32,
|
"abc": 32,
|
||||||
|
@ -60,13 +63,16 @@ func TestToLower(t *testing.T) {
|
||||||
"ghi": Params{
|
"ghi": Params{
|
||||||
"j": 25,
|
"j": 25,
|
||||||
},
|
},
|
||||||
|
"jkl": Params{
|
||||||
|
"m": "26",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
t.Run(fmt.Sprint(i), func(t *testing.T) {
|
t.Run(fmt.Sprint(i), func(t *testing.T) {
|
||||||
// ToLower modifies input.
|
// PrepareParams modifies input.
|
||||||
PrepareParams(test.input)
|
PrepareParams(test.input)
|
||||||
if !reflect.DeepEqual(test.expected, test.input) {
|
if !reflect.DeepEqual(test.expected, test.input) {
|
||||||
t.Errorf("[%d] Expected\n%#v, got\n%#v\n", i, test.expected, test.input)
|
t.Errorf("[%d] Expected\n%#v, got\n%#v\n", i, test.expected, test.input)
|
||||||
|
|
|
@ -226,7 +226,7 @@ func toMergeStrategy(v interface{}) ParamsMergeStrategy {
|
||||||
// PrepareParams
|
// PrepareParams
|
||||||
// * makes all the keys in the given map lower cased and will do so
|
// * makes all the keys in the given map lower cased and will do so
|
||||||
// * This will modify the map given.
|
// * This will modify the map given.
|
||||||
// * Any nested map[interface{}]interface{} will be converted to Params.
|
// * Any nested map[interface{}]interface{}, map[string]interface{},map[string]string will be converted to Params.
|
||||||
// * Any _merge value will be converted to proper type and value.
|
// * Any _merge value will be converted to proper type and value.
|
||||||
func PrepareParams(m Params) {
|
func PrepareParams(m Params) {
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
|
@ -236,7 +236,7 @@ func PrepareParams(m Params) {
|
||||||
v = toMergeStrategy(v)
|
v = toMergeStrategy(v)
|
||||||
retyped = true
|
retyped = true
|
||||||
} else {
|
} else {
|
||||||
switch v.(type) {
|
switch vv := v.(type) {
|
||||||
case map[interface{}]interface{}:
|
case map[interface{}]interface{}:
|
||||||
var p Params = cast.ToStringMap(v)
|
var p Params = cast.ToStringMap(v)
|
||||||
v = p
|
v = p
|
||||||
|
@ -247,6 +247,14 @@ func PrepareParams(m Params) {
|
||||||
v = p
|
v = p
|
||||||
PrepareParams(p)
|
PrepareParams(p)
|
||||||
retyped = true
|
retyped = true
|
||||||
|
case map[string]string:
|
||||||
|
p := make(Params)
|
||||||
|
for k, v := range vv {
|
||||||
|
p[k] = v
|
||||||
|
}
|
||||||
|
v = p
|
||||||
|
PrepareParams(p)
|
||||||
|
retyped = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,10 @@ func (c *compositeConfig) Set(key string, value interface{}) {
|
||||||
c.layer.Set(key, value)
|
c.layer.Set(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *compositeConfig) SetDefaults(params maps.Params) {
|
||||||
|
c.layer.SetDefaults(params)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *compositeConfig) WalkParams(walkFn func(params ...KeyParams) bool) {
|
func (c *compositeConfig) WalkParams(walkFn func(params ...KeyParams) bool) {
|
||||||
panic("not supported")
|
panic("not supported")
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ type Provider interface {
|
||||||
Get(key string) interface{}
|
Get(key string) interface{}
|
||||||
Set(key string, value interface{})
|
Set(key string, value interface{})
|
||||||
Merge(key string, value interface{})
|
Merge(key string, value interface{})
|
||||||
|
SetDefaults(params maps.Params)
|
||||||
SetDefaultMergeStrategy()
|
SetDefaultMergeStrategy()
|
||||||
WalkParams(walkFn func(params ...KeyParams) bool)
|
WalkParams(walkFn func(params ...KeyParams) bool)
|
||||||
IsSet(key string) bool
|
IsSet(key string) bool
|
||||||
|
|
|
@ -163,10 +163,9 @@ func (c *defaultConfigProvider) Set(k string, v interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch vv := v.(type) {
|
switch vv := v.(type) {
|
||||||
case map[string]interface{}:
|
case map[string]interface{}, map[interface{}]interface{}, map[string]string:
|
||||||
var p maps.Params = vv
|
p := maps.MustToParamsAndPrepare(vv)
|
||||||
v = p
|
v = p
|
||||||
maps.PrepareParams(p)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
key, m := c.getNestedKeyAndMap(k, true)
|
key, m := c.getNestedKeyAndMap(k, true)
|
||||||
|
@ -183,6 +182,16 @@ func (c *defaultConfigProvider) Set(k string, v interface{}) {
|
||||||
m[key] = v
|
m[key] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetDefaults will set values from params if not already set.
|
||||||
|
func (c *defaultConfigProvider) SetDefaults(params maps.Params) {
|
||||||
|
maps.PrepareParams(params)
|
||||||
|
for k, v := range params {
|
||||||
|
if _, found := c.root[k]; !found {
|
||||||
|
c.root[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *defaultConfigProvider) Merge(k string, v interface{}) {
|
func (c *defaultConfigProvider) Merge(k string, v interface{}) {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
|
@ -226,10 +235,9 @@ func (c *defaultConfigProvider) Merge(k string, v interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch vv := v.(type) {
|
switch vv := v.(type) {
|
||||||
case map[string]interface{}:
|
case map[string]interface{}, map[interface{}]interface{}, map[string]string:
|
||||||
var p maps.Params = vv
|
p := maps.MustToParamsAndPrepare(vv)
|
||||||
v = p
|
v = p
|
||||||
maps.PrepareParams(p)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
key, m := c.getNestedKeyAndMap(k, true)
|
key, m := c.getNestedKeyAndMap(k, true)
|
||||||
|
|
|
@ -204,6 +204,85 @@ func TestDefaultConfigProvider(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Issue #8679
|
||||||
|
c.Run("Merge typed maps", func(c *qt.C) {
|
||||||
|
|
||||||
|
for _, left := range []interface{}{
|
||||||
|
map[string]string{
|
||||||
|
"c": "cv1",
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"c": "cv1",
|
||||||
|
},
|
||||||
|
map[interface{}]interface{}{
|
||||||
|
"c": "cv1",
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
cfg := New()
|
||||||
|
|
||||||
|
cfg.Set("", map[string]interface{}{
|
||||||
|
"b": left,
|
||||||
|
})
|
||||||
|
|
||||||
|
cfg.Merge("", maps.Params{
|
||||||
|
"b": maps.Params{
|
||||||
|
"c": "cv2",
|
||||||
|
"d": "dv2",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
c.Assert(cfg.Get(""), qt.DeepEquals, maps.Params{
|
||||||
|
"b": maps.Params{
|
||||||
|
"c": "cv1",
|
||||||
|
"d": "dv2",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, left := range []interface{}{
|
||||||
|
map[string]string{
|
||||||
|
"b": "bv1",
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"b": "bv1",
|
||||||
|
},
|
||||||
|
map[interface{}]interface{}{
|
||||||
|
"b": "bv1",
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
|
||||||
|
for _, right := range []interface{}{
|
||||||
|
map[string]string{
|
||||||
|
"b": "bv2",
|
||||||
|
"c": "cv2",
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"b": "bv2",
|
||||||
|
"c": "cv2",
|
||||||
|
},
|
||||||
|
map[interface{}]interface{}{
|
||||||
|
"b": "bv2",
|
||||||
|
"c": "cv2",
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
cfg := New()
|
||||||
|
|
||||||
|
cfg.Set("a", left)
|
||||||
|
|
||||||
|
cfg.Merge("a", right)
|
||||||
|
|
||||||
|
c.Assert(cfg.Get(""), qt.DeepEquals, maps.Params{
|
||||||
|
"a": maps.Params{
|
||||||
|
"b": "bv1",
|
||||||
|
"c": "cv2",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
c.Run("IsSet", func(c *qt.C) {
|
c.Run("IsSet", func(c *qt.C) {
|
||||||
cfg := New()
|
cfg := New()
|
||||||
|
|
||||||
|
|
|
@ -64,10 +64,6 @@ func LoadConfig(d ConfigSourceDescriptor, doWithConfig ...func(cfg config.Provid
|
||||||
|
|
||||||
l := configLoader{ConfigSourceDescriptor: d, cfg: config.New()}
|
l := configLoader{ConfigSourceDescriptor: d, cfg: config.New()}
|
||||||
|
|
||||||
if err := l.applyConfigDefaults(); err != nil {
|
|
||||||
return l.cfg, configFiles, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, name := range d.configFilenames() {
|
for _, name := range d.configFilenames() {
|
||||||
var filename string
|
var filename string
|
||||||
filename, err := l.loadConfig(name)
|
filename, err := l.loadConfig(name)
|
||||||
|
@ -78,6 +74,10 @@ func LoadConfig(d ConfigSourceDescriptor, doWithConfig ...func(cfg config.Provid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := l.applyConfigDefaults(); err != nil {
|
||||||
|
return l.cfg, configFiles, err
|
||||||
|
}
|
||||||
|
|
||||||
if d.AbsConfigDir != "" {
|
if d.AbsConfigDir != "" {
|
||||||
dcfg, dirnames, err := config.LoadConfigFromDir(l.Fs, d.AbsConfigDir, l.Environment)
|
dcfg, dirnames, err := config.LoadConfigFromDir(l.Fs, d.AbsConfigDir, l.Environment)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -298,7 +298,7 @@ func (l configLoader) applyConfigDefaults() error {
|
||||||
"enableInlineShortcodes": false,
|
"enableInlineShortcodes": false,
|
||||||
}
|
}
|
||||||
|
|
||||||
l.cfg.Merge("", defaultSettings)
|
l.cfg.SetDefaults(defaultSettings)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ title: P1
|
||||||
b.AssertFileContent("public/p1/index.html", `Link First Link|PARTIAL1_EDITED PARTIAL2_EDITEDEND`)
|
b.AssertFileContent("public/p1/index.html", `Link First Link|PARTIAL1_EDITED PARTIAL2_EDITEDEND`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestRenderHooks(t *testing.T) {
|
func TestRenderHooks(t *testing.T) {
|
||||||
config := `
|
config := `
|
||||||
baseURL="https://example.org"
|
baseURL="https://example.org"
|
||||||
|
|
Loading…
Reference in a new issue