mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
Account for array type data in data dir merge/override logic
* Fixes #4366 * Error message to console for unsupported data types
This commit is contained in:
parent
82eefded13
commit
bb549a0d57
2 changed files with 63 additions and 18 deletions
|
@ -261,8 +261,7 @@ func TestDataDirMultipleSourcesCommingled(t *testing.T) {
|
||||||
doTestDataDir(t, dd, expected, "theme", "mytheme")
|
doTestDataDir(t, dd, expected, "theme", "mytheme")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Issue #4366 unresolved
|
func TestDataDirCollidingChildArrays(t *testing.T) {
|
||||||
func _TestDataDirMultipleSourcesCollidingChildArrays(t *testing.T) {
|
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
var dd dataDir
|
var dd dataDir
|
||||||
|
@ -284,8 +283,7 @@ func _TestDataDirMultipleSourcesCollidingChildArrays(t *testing.T) {
|
||||||
doTestDataDir(t, dd, expected, "theme", "mytheme")
|
doTestDataDir(t, dd, expected, "theme", "mytheme")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Issue #4366 unresolved
|
func TestDataDirCollidingTopLevelArrays(t *testing.T) {
|
||||||
func _TestDataDirMultipleSourcesCollidingTopLevelArrays(t *testing.T) {
|
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
var dd dataDir
|
var dd dataDir
|
||||||
|
@ -302,6 +300,27 @@ func _TestDataDirMultipleSourcesCollidingTopLevelArrays(t *testing.T) {
|
||||||
doTestDataDir(t, dd, expected, "theme", "mytheme")
|
doTestDataDir(t, dd, expected, "theme", "mytheme")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDataDirCollidingMapsAndArrays(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
var dd dataDir
|
||||||
|
// on
|
||||||
|
dd.addSource("themes/mytheme/data/a.json", `["1", "2", "3"]`)
|
||||||
|
dd.addSource("themes/mytheme/data/b.json", `{ "film" : "Logan Lucky" }`)
|
||||||
|
dd.addSource("data/a.json", `{ "music" : "Queen's Rebuke" }`)
|
||||||
|
dd.addSource("data/b.json", `["x", "y", "z"]`)
|
||||||
|
|
||||||
|
expected :=
|
||||||
|
map[string]interface{}{
|
||||||
|
"a": map[string]interface{}{
|
||||||
|
"music": "Queen's Rebuke",
|
||||||
|
},
|
||||||
|
"b": []interface{}{"x", "y", "z"},
|
||||||
|
}
|
||||||
|
|
||||||
|
doTestDataDir(t, dd, expected, "theme", "mytheme")
|
||||||
|
}
|
||||||
|
|
||||||
type dataDir struct {
|
type dataDir struct {
|
||||||
sources [][2]string
|
sources [][2]string
|
||||||
}
|
}
|
||||||
|
|
|
@ -812,24 +812,50 @@ func (s *Site) handleDataFile(r source.ReadableFile) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy content from current to data when needed
|
|
||||||
if _, ok := current[r.BaseFileName()]; ok {
|
|
||||||
data := data.(map[string]interface{})
|
|
||||||
|
|
||||||
for key, value := range current[r.BaseFileName()].(map[string]interface{}) {
|
|
||||||
if _, override := data[key]; override {
|
|
||||||
// filepath.Walk walks the files in lexical order, '/' comes before '.'
|
// filepath.Walk walks the files in lexical order, '/' comes before '.'
|
||||||
// this warning could happen if
|
// this warning could happen if
|
||||||
// 1. A theme uses the same key; the main data folder wins
|
// 1. A theme uses the same key; the main data folder wins
|
||||||
// 2. A sub folder uses the same key: the sub folder wins
|
// 2. A sub folder uses the same key: the sub folder wins
|
||||||
s.Log.WARN.Printf("Data for key '%s' in path '%s' is overridden in subfolder", key, r.Path())
|
higherPrecedentData := current[r.BaseFileName()]
|
||||||
|
|
||||||
|
switch data.(type) {
|
||||||
|
case nil:
|
||||||
|
// hear the crickets?
|
||||||
|
|
||||||
|
case map[string]interface{}:
|
||||||
|
|
||||||
|
switch higherPrecedentData.(type) {
|
||||||
|
case nil:
|
||||||
|
current[r.BaseFileName()] = data
|
||||||
|
case map[string]interface{}:
|
||||||
|
// merge maps: insert entries from data for keys that
|
||||||
|
// don't already exist in higherPrecedentData
|
||||||
|
higherPrecedentMap := higherPrecedentData.(map[string]interface{})
|
||||||
|
for key, value := range data.(map[string]interface{}) {
|
||||||
|
if _, exists := higherPrecedentMap[key]; exists {
|
||||||
|
s.Log.WARN.Printf("Data for key '%s' in path '%s' is overridden higher precedence data already in the data tree", key, r.Path())
|
||||||
|
} else {
|
||||||
|
higherPrecedentMap[key] = value
|
||||||
}
|
}
|
||||||
data[key] = value
|
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
// can't merge: higherPrecedentData is not a map
|
||||||
|
s.Log.WARN.Printf("The %T data from '%s' overridden by "+
|
||||||
|
"higher precedence %T data already in the data tree", data, r.Path(), higherPrecedentData)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert data
|
case []interface{}:
|
||||||
|
if higherPrecedentData == nil {
|
||||||
current[r.BaseFileName()] = data
|
current[r.BaseFileName()] = data
|
||||||
|
} else {
|
||||||
|
// we don't merge array data
|
||||||
|
s.Log.WARN.Printf("The %T data from '%s' overridden by "+
|
||||||
|
"higher precedence %T data already in the data tree", data, r.Path(), higherPrecedentData)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
s.Log.ERROR.Printf("unexpected data type %T in file %s", data, r.LogicalName())
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue