summaryrefslogtreecommitdiffstats
path: root/hugolib
diff options
context:
space:
mode:
authorVas Sudanagunta <vas@commonkarma.org>2018-02-11 18:34:03 -0500
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2018-02-12 17:14:40 +0100
commitbb549a0d57505a6b8f28930bb91a9ab44cbb3288 (patch)
tree18123e5c2eddc4bb511c8395cb7f282f643c7c82 /hugolib
parent82eefded1353f0198fd8fe9f7df1aa620d3d50eb (diff)
Account for array type data in data dir merge/override logic
* Fixes #4366 * Error message to console for unsupported data types
Diffstat (limited to 'hugolib')
-rw-r--r--hugolib/datafiles_test.go27
-rw-r--r--hugolib/site.go56
2 files changed, 64 insertions, 19 deletions
diff --git a/hugolib/datafiles_test.go b/hugolib/datafiles_test.go
index a11929542..de124a77d 100644
--- a/hugolib/datafiles_test.go
+++ b/hugolib/datafiles_test.go
@@ -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
}
diff --git a/hugolib/site.go b/hugolib/site.go
index 044866cca..d62662814 100644
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -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{})
-
- 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())
+ // 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()]
+
+ 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
}