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")
|
||||
}
|
||||
|
||||
// TODO Issue #4366 unresolved
|
||||
func _TestDataDirMultipleSourcesCollidingChildArrays(t *testing.T) {
|
||||
func TestDataDirCollidingChildArrays(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var dd dataDir
|
||||
|
@ -284,8 +283,7 @@ func _TestDataDirMultipleSourcesCollidingChildArrays(t *testing.T) {
|
|||
doTestDataDir(t, dd, expected, "theme", "mytheme")
|
||||
}
|
||||
|
||||
// TODO Issue #4366 unresolved
|
||||
func _TestDataDirMultipleSourcesCollidingTopLevelArrays(t *testing.T) {
|
||||
func TestDataDirCollidingTopLevelArrays(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var dd dataDir
|
||||
|
@ -302,6 +300,27 @@ func _TestDataDirMultipleSourcesCollidingTopLevelArrays(t *testing.T) {
|
|||
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 {
|
||||
sources [][2]string
|
||||
}
|
||||
|
|
|
@ -812,24 +812,50 @@ func (s *Site) handleDataFile(r source.ReadableFile) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Copy content from current to data when needed
|
||||
if _, ok := current[r.BaseFileName()]; ok {
|
||||
data := data.(map[string]interface{})
|
||||
// filepath.Walk walks the files in lexical order, '/' comes before '.'
|
||||
// this warning could happen if
|
||||
// 1. A theme uses the same key; the main data folder wins
|
||||
// 2. A sub folder uses the same key: the sub folder wins
|
||||
higherPrecedentData := current[r.BaseFileName()]
|
||||
|
||||
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 '.'
|
||||
// this warning could happen if
|
||||
// 1. A theme uses the same key; the main data 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())
|
||||
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
|
||||
current[r.BaseFileName()] = data
|
||||
case []interface{}:
|
||||
if higherPrecedentData == nil {
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue