hugo

Unnamed repository; edit this file 'description' to name the repository.

git clone git://git.shimmy1996.com/hugo.git
commit 6b6dcb44a014699c289bf32fe57d4c4216777be0
parent d96f2a460f58e91d8f6253a489d4879acfec6916
Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Date:   Wed, 11 Jul 2018 19:23:22 +0200

Flush partialCached cache on rebuilds

Fixes #4931

Diffstat:
Mdeps/deps.go | 29+++++++++++++++++++++++++++++
Mhugolib/hugo_sites_build.go | 5+++++
Mtpl/partials/init_test.go | 4+++-
Mtpl/partials/partials.go | 16++++++++++++++--
4 files changed, 51 insertions(+), 3 deletions(-)
diff --git a/deps/deps.go b/deps/deps.go
@@ -1,6 +1,7 @@
 package deps
 
 import (
+	"sync"
 	"time"
 
 	"github.com/gohugoio/hugo/common/loggers"
@@ -22,6 +23,7 @@ import (
 // There will be normally only one instance of deps in play
 // at a given time, i.e. one per Site built.
 type Deps struct {
+
 	// The logger to use.
 	Log *jww.Notepad `json:"-"`
 
@@ -69,6 +71,30 @@ type Deps struct {
 
 	// Timeout is configurable in site config.
 	Timeout time.Duration
+
+	// BuildStartListeners will be notified before a build starts.
+	BuildStartListeners *Listeners
+}
+
+type Listeners struct {
+	sync.Mutex
+
+	// A list of funcs to be notified about an event.
+	listeners []func()
+}
+
+func (b *Listeners) Add(f func()) {
+	b.Lock()
+	defer b.Unlock()
+	b.listeners = append(b.listeners, f)
+}
+
+func (b *Listeners) Notify() {
+	b.Lock()
+	defer b.Unlock()
+	for _, notify := range b.listeners {
+		notify()
+	}
 }
 
 // ResourceProvider is used to create and refresh, and clone resources needed.
@@ -168,6 +194,7 @@ func New(cfg DepsCfg) (*Deps, error) {
 		ResourceSpec:        resourceSpec,
 		Cfg:                 cfg.Language,
 		Language:            cfg.Language,
+		BuildStartListeners: &Listeners{},
 		Timeout:             time.Duration(timeoutms) * time.Millisecond,
 	}
 
@@ -210,6 +237,8 @@ func (d Deps) ForLanguage(cfg DepsCfg) (*Deps, error) {
 		return nil, err
 	}
 
+	d.BuildStartListeners = &Listeners{}
+
 	return &d, nil
 
 }
diff --git a/hugolib/hugo_sites_build.go b/hugolib/hugo_sites_build.go
@@ -28,6 +28,7 @@ import (
 // Build builds all sites. If filesystem events are provided,
 // this is considered to be a potential partial rebuild.
 func (h *HugoSites) Build(config BuildCfg, events ...fsnotify.Event) error {
+
 	if h.Metrics != nil {
 		h.Metrics.Reset()
 	}
@@ -42,6 +43,10 @@ func (h *HugoSites) Build(config BuildCfg, events ...fsnotify.Event) error {
 		conf.whatChanged = &whatChanged{source: true, other: true}
 	}
 
+	for _, s := range h.Sites {
+		s.Deps.BuildStartListeners.Notify()
+	}
+
 	if len(events) > 0 {
 		// Rebuild
 		if err := h.initRebuild(conf); err != nil {
diff --git a/tpl/partials/init_test.go b/tpl/partials/init_test.go
@@ -26,7 +26,9 @@ func TestInit(t *testing.T) {
 	var ns *internal.TemplateFuncsNamespace
 
 	for _, nsf := range internal.TemplateFuncsNamespaceRegistry {
-		ns = nsf(&deps.Deps{})
+		ns = nsf(&deps.Deps{
+			BuildStartListeners: &deps.Listeners{},
+		})
 		if ns.Name == name {
 			found = true
 			break
diff --git a/tpl/partials/partials.go b/tpl/partials/partials.go
@@ -34,18 +34,30 @@ type partialCache struct {
 	p map[string]interface{}
 }
 
+func (p *partialCache) clear() {
+	p.Lock()
+	defer p.Unlock()
+	p.p = make(map[string]interface{})
+}
+
 // New returns a new instance of the templates-namespaced template functions.
 func New(deps *deps.Deps) *Namespace {
+	cache := &partialCache{p: make(map[string]interface{})}
+	deps.BuildStartListeners.Add(
+		func() {
+			cache.clear()
+		})
+
 	return &Namespace{
 		deps:           deps,
-		cachedPartials: partialCache{p: make(map[string]interface{})},
+		cachedPartials: cache,
 	}
 }
 
 // Namespace provides template functions for the "templates" namespace.
 type Namespace struct {
 	deps           *deps.Deps
-	cachedPartials partialCache
+	cachedPartials *partialCache
 }
 
 // Include executes the named partial and returns either a string,