summaryrefslogtreecommitdiffstats
path: root/tpl
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-02-17 14:22:40 +0100
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-02-17 17:15:26 +0100
commit77cbe4d60bfa708cbf695ae5f2524d4f76007e71 (patch)
tree98a1ce3dc892bd8b13d7e36dc18839ab3cb3f6f4 /tpl
parentc507e2717df7dd4b870478033bc5ece0b039a8c4 (diff)
tplimpl: Refactor imageConfig into a struct
Updates #2701
Diffstat (limited to 'tpl')
-rw-r--r--tpl/tplimpl/template_funcs.go53
-rw-r--r--tpl/tplimpl/template_funcs_test.go58
2 files changed, 34 insertions, 77 deletions
diff --git a/tpl/tplimpl/template_funcs.go b/tpl/tplimpl/template_funcs.go
index dae621ac3..20f46a4e2 100644
--- a/tpl/tplimpl/template_funcs.go
+++ b/tpl/tplimpl/template_funcs.go
@@ -40,6 +40,8 @@ import (
"time"
"unicode/utf8"
+ "github.com/spf13/hugo/hugofs"
+
"github.com/bep/inflect"
"github.com/spf13/afero"
"github.com/spf13/cast"
@@ -57,6 +59,7 @@ import (
type templateFuncster struct {
funcMap template.FuncMap
cachedPartials partialCache
+ image *imageHandler
*deps.Deps
}
@@ -64,6 +67,7 @@ func newTemplateFuncster(deps *deps.Deps) *templateFuncster {
return &templateFuncster{
Deps: deps,
cachedPartials: partialCache{p: make(map[string]template.HTML)},
+ image: &imageHandler{fs: deps.Fs, imageConfigCache: map[string]image.Config{}},
}
}
@@ -395,64 +399,43 @@ func intersect(l1, l2 interface{}) (interface{}, error) {
}
}
-// ResetCaches resets all caches that might be used during build.
-// TODO(bep) globals move image config cache to funcster
-func ResetCaches() {
- resetImageConfigCache()
-}
-
-// imageConfigCache is a lockable cache for image.Config objects. It must be
-// locked before reading or writing to config.
-type imageConfigCache struct {
- config map[string]image.Config
+type imageHandler struct {
+ imageConfigCache map[string]image.Config
sync.RWMutex
-}
-
-var defaultImageConfigCache = imageConfigCache{
- config: map[string]image.Config{},
-}
-
-// resetImageConfigCache initializes and resets the imageConfig cache for the
-// imageConfig template function. This should be run once before every batch of
-// template renderers so the cache is cleared for new data.
-func resetImageConfigCache() {
- defaultImageConfigCache.Lock()
- defer defaultImageConfigCache.Unlock()
-
- defaultImageConfigCache.config = map[string]image.Config{}
+ fs *hugofs.Fs
}
// imageConfig returns the image.Config for the specified path relative to the
-// working directory. resetImageConfigCache must be run beforehand.
-func (t *templateFuncster) imageConfig(path interface{}) (image.Config, error) {
+// working directory.
+func (ic *imageHandler) config(path interface{}) (image.Config, error) {
filename, err := cast.ToStringE(path)
if err != nil {
return image.Config{}, err
}
if filename == "" {
- return image.Config{}, errors.New("imageConfig needs a filename")
+ return image.Config{}, errors.New("config needs a filename")
}
// Check cache for image config.
- defaultImageConfigCache.RLock()
- config, ok := defaultImageConfigCache.config[filename]
- defaultImageConfigCache.RUnlock()
+ ic.RLock()
+ config, ok := ic.imageConfigCache[filename]
+ ic.RUnlock()
if ok {
return config, nil
}
- f, err := t.Fs.WorkingDir.Open(filename)
+ f, err := ic.fs.WorkingDir.Open(filename)
if err != nil {
return image.Config{}, err
}
config, _, err = image.DecodeConfig(f)
- defaultImageConfigCache.Lock()
- defaultImageConfigCache.config[filename] = config
- defaultImageConfigCache.Unlock()
+ ic.Lock()
+ ic.imageConfigCache[filename] = config
+ ic.Unlock()
return config, err
}
@@ -2144,7 +2127,7 @@ func (t *templateFuncster) initFuncMap() {
"htmlEscape": htmlEscape,
"htmlUnescape": htmlUnescape,
"humanize": humanize,
- "imageConfig": t.imageConfig,
+ "imageConfig": t.image.config,
"in": in,
"index": index,
"int": func(v interface{}) (int, error) { return cast.ToIntE(v) },
diff --git a/tpl/tplimpl/template_funcs_test.go b/tpl/tplimpl/template_funcs_test.go
index 0fba97bd3..db7533dd3 100644
--- a/tpl/tplimpl/template_funcs_test.go
+++ b/tpl/tplimpl/template_funcs_test.go
@@ -667,16 +667,13 @@ func TestImageConfig(t *testing.T) {
f := newTestFuncsterWithViper(v)
for i, this := range []struct {
- resetCache bool
- path string
- input []byte
- expected image.Config
+ path string
+ input []byte
+ expected image.Config
}{
- // Make sure that the cache is initialized by default.
{
- resetCache: false,
- path: "a.png",
- input: blankImage(10, 10),
+ path: "a.png",
+ input: blankImage(10, 10),
expected: image.Config{
Width: 10,
Height: 10,
@@ -684,9 +681,8 @@ func TestImageConfig(t *testing.T) {
},
},
{
- resetCache: true,
- path: "a.png",
- input: blankImage(10, 10),
+ path: "a.png",
+ input: blankImage(10, 10),
expected: image.Config{
Width: 10,
Height: 10,
@@ -694,9 +690,8 @@ func TestImageConfig(t *testing.T) {
},
},
{
- resetCache: false,
- path: "b.png",
- input: blankImage(20, 15),
+ path: "b.png",
+ input: blankImage(20, 15),
expected: image.Config{
Width: 20,
Height: 15,
@@ -704,33 +699,18 @@ func TestImageConfig(t *testing.T) {
},
},
{
- resetCache: false,
- path: "a.png",
- input: blankImage(20, 15),
+ path: "a.png",
+ input: blankImage(20, 15),
expected: image.Config{
Width: 10,
Height: 10,
ColorModel: color.NRGBAModel,
},
},
- {
- resetCache: true,
- path: "a.png",
- input: blankImage(20, 15),
- expected: image.Config{
- Width: 20,
- Height: 15,
- ColorModel: color.NRGBAModel,
- },
- },
} {
afero.WriteFile(f.Fs.Source, filepath.Join(workingDir, this.path), this.input, 0755)
- if this.resetCache {
- resetImageConfigCache()
- }
-
- result, err := f.imageConfig(this.path)
+ result, err := f.image.config(this.path)
if err != nil {
t.Errorf("imageConfig returned error: %s", err)
}
@@ -739,29 +719,23 @@ func TestImageConfig(t *testing.T) {
t.Errorf("[%d] imageConfig: expected '%v', got '%v'", i, this.expected, result)
}
- if len(defaultImageConfigCache.config) == 0 {
+ if len(f.image.imageConfigCache) == 0 {
t.Error("defaultImageConfigCache should have at least 1 item")
}
}
- if _, err := f.imageConfig(t); err == nil {
+ if _, err := f.image.config(t); err == nil {
t.Error("Expected error from imageConfig when passed invalid path")
}
- if _, err := f.imageConfig("non-existent.png"); err == nil {
+ if _, err := f.image.config("non-existent.png"); err == nil {
t.Error("Expected error from imageConfig when passed non-existent file")
}
- if _, err := f.imageConfig(""); err == nil {
+ if _, err := f.image.config(""); err == nil {
t.Error("Expected error from imageConfig when passed empty path")
}
- // test cache clearing
- ResetCaches()
-
- if len(defaultImageConfigCache.config) != 0 {
- t.Error("ResetCaches should have cleared defaultImageConfigCache")
- }
}
func TestIn(t *testing.T) {