summaryrefslogtreecommitdiffstats
path: root/cache
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2023-01-04 18:24:36 +0100
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2023-05-16 18:01:29 +0200
commit241b21b0fd34d91fccb2ce69874110dceae6f926 (patch)
treed4e0118eac7e9c42f065815447a70805f8d6ad3e /cache
parent6aededf6b42011c3039f5f66487a89a8dd65e0e7 (diff)
Create a struct with all of Hugo's config options
Primary motivation is documentation, but it will also hopefully simplify the code. Also, * Lower case the default output format names; this is in line with the custom ones (map keys) and how it's treated all the places. This avoids doing `stringds.EqualFold` everywhere. Closes #10896 Closes #10620
Diffstat (limited to 'cache')
-rw-r--r--cache/docs.go2
-rw-r--r--cache/filecache/filecache.go28
-rw-r--r--cache/filecache/filecache_config.go103
-rw-r--r--cache/filecache/filecache_config_test.go88
-rw-r--r--cache/filecache/filecache_pruner.go2
-rw-r--r--cache/filecache/filecache_pruner_test.go13
-rw-r--r--cache/filecache/filecache_test.go88
-rw-r--r--cache/filecache/integration_test.go9
8 files changed, 106 insertions, 227 deletions
diff --git a/cache/docs.go b/cache/docs.go
new file mode 100644
index 000000000..babecec22
--- /dev/null
+++ b/cache/docs.go
@@ -0,0 +1,2 @@
+// Package cache contains the differenct cache implementations.
+package cache
diff --git a/cache/filecache/filecache.go b/cache/filecache/filecache.go
index 88a466218..05d9379b4 100644
--- a/cache/filecache/filecache.go
+++ b/cache/filecache/filecache.go
@@ -35,7 +35,7 @@ import (
var ErrFatal = errors.New("fatal filecache error")
const (
- filecacheRootDirname = "filecache"
+ FilecacheRootDirname = "filecache"
)
// Cache caches a set of files in a directory. This is usually a file on
@@ -301,7 +301,7 @@ func (c *Cache) isExpired(modTime time.Time) bool {
}
// For testing
-func (c *Cache) getString(id string) string {
+func (c *Cache) GetString(id string) string {
id = cleanID(id)
c.nlocker.Lock(id)
@@ -328,38 +328,24 @@ func (f Caches) Get(name string) *Cache {
// NewCaches creates a new set of file caches from the given
// configuration.
func NewCaches(p *helpers.PathSpec) (Caches, error) {
- var dcfg Configs
- if c, ok := p.Cfg.Get("filecacheConfigs").(Configs); ok {
- dcfg = c
- } else {
- var err error
- dcfg, err = DecodeConfig(p.Fs.Source, p.Cfg)
- if err != nil {
- return nil, err
- }
- }
-
+ dcfg := p.Cfg.GetConfigSection("caches").(Configs)
fs := p.Fs.Source
m := make(Caches)
for k, v := range dcfg {
var cfs afero.Fs
- if v.isResourceDir {
+ if v.IsResourceDir {
cfs = p.BaseFs.ResourcesCache
} else {
cfs = fs
}
if cfs == nil {
- // TODO(bep) we still have some places that do not initialize the
- // full dependencies of a site, e.g. the import Jekyll command.
- // That command does not need these caches, so let us just continue
- // for now.
- continue
+ panic("nil fs")
}
- baseDir := v.Dir
+ baseDir := v.DirCompiled
if err := cfs.MkdirAll(baseDir, 0777); err != nil && !os.IsExist(err) {
return nil, err
@@ -368,7 +354,7 @@ func NewCaches(p *helpers.PathSpec) (Caches, error) {
bfs := afero.NewBasePathFs(cfs, baseDir)
var pruneAllRootDir string
- if k == cacheKeyModules {
+ if k == CacheKeyModules {
pruneAllRootDir = "pkg"
}
diff --git a/cache/filecache/filecache_config.go b/cache/filecache/filecache_config.go
index a82133ab7..e8019578a 100644
--- a/cache/filecache/filecache_config.go
+++ b/cache/filecache/filecache_config.go
@@ -11,6 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// Package filecache provides a file based cache for Hugo.
package filecache
import (
@@ -21,11 +22,8 @@ import (
"time"
"github.com/gohugoio/hugo/common/maps"
-
"github.com/gohugoio/hugo/config"
- "github.com/gohugoio/hugo/helpers"
-
"errors"
"github.com/mitchellh/mapstructure"
@@ -33,98 +31,102 @@ import (
)
const (
- cachesConfigKey = "caches"
-
resourcesGenDir = ":resourceDir/_gen"
cacheDirProject = ":cacheDir/:project"
)
-var defaultCacheConfig = Config{
+var defaultCacheConfig = FileCacheConfig{
MaxAge: -1, // Never expire
Dir: cacheDirProject,
}
const (
- cacheKeyGetJSON = "getjson"
- cacheKeyGetCSV = "getcsv"
- cacheKeyImages = "images"
- cacheKeyAssets = "assets"
- cacheKeyModules = "modules"
- cacheKeyGetResource = "getresource"
+ CacheKeyGetJSON = "getjson"
+ CacheKeyGetCSV = "getcsv"
+ CacheKeyImages = "images"
+ CacheKeyAssets = "assets"
+ CacheKeyModules = "modules"
+ CacheKeyGetResource = "getresource"
)
-type Configs map[string]Config
+type Configs map[string]FileCacheConfig
+// For internal use.
func (c Configs) CacheDirModules() string {
- return c[cacheKeyModules].Dir
+ return c[CacheKeyModules].DirCompiled
}
var defaultCacheConfigs = Configs{
- cacheKeyModules: {
+ CacheKeyModules: {
MaxAge: -1,
Dir: ":cacheDir/modules",
},
- cacheKeyGetJSON: defaultCacheConfig,
- cacheKeyGetCSV: defaultCacheConfig,
- cacheKeyImages: {
+ CacheKeyGetJSON: defaultCacheConfig,
+ CacheKeyGetCSV: defaultCacheConfig,
+ CacheKeyImages: {
MaxAge: -1,
Dir: resourcesGenDir,
},
- cacheKeyAssets: {
+ CacheKeyAssets: {
MaxAge: -1,
Dir: resourcesGenDir,
},
- cacheKeyGetResource: Config{
+ CacheKeyGetResource: FileCacheConfig{
MaxAge: -1, // Never expire
Dir: cacheDirProject,
},
}
-type Config struct {
+type FileCacheConfig struct {
// Max age of cache entries in this cache. Any items older than this will
// be removed and not returned from the cache.
- // a negative value means forever, 0 means cache is disabled.
+ // A negative value means forever, 0 means cache is disabled.
+ // Hugo is leninent with what types it accepts here, but we recommend using
+ // a duration string, a sequence of decimal numbers, each with optional fraction and a unit suffix,
+ // such as "300ms", "1.5h" or "2h45m".
+ // Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
MaxAge time.Duration
// The directory where files are stored.
- Dir string
+ Dir string
+ DirCompiled string `json:"-"`
// Will resources/_gen will get its own composite filesystem that
// also checks any theme.
- isResourceDir bool
+ IsResourceDir bool
}
// GetJSONCache gets the file cache for getJSON.
func (f Caches) GetJSONCache() *Cache {
- return f[cacheKeyGetJSON]
+ return f[CacheKeyGetJSON]
}
// GetCSVCache gets the file cache for getCSV.
func (f Caches) GetCSVCache() *Cache {
- return f[cacheKeyGetCSV]
+ return f[CacheKeyGetCSV]
}
// ImageCache gets the file cache for processed images.
func (f Caches) ImageCache() *Cache {
- return f[cacheKeyImages]
+ return f[CacheKeyImages]
}
// ModulesCache gets the file cache for Hugo Modules.
func (f Caches) ModulesCache() *Cache {
- return f[cacheKeyModules]
+ return f[CacheKeyModules]
}
// AssetsCache gets the file cache for assets (processed resources, SCSS etc.).
func (f Caches) AssetsCache() *Cache {
- return f[cacheKeyAssets]
+ return f[CacheKeyAssets]
}
// GetResourceCache gets the file cache for remote resources.
func (f Caches) GetResourceCache() *Cache {
- return f[cacheKeyGetResource]
+ return f[CacheKeyGetResource]
}
-func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) {
+func DecodeConfig(fs afero.Fs, bcfg config.BaseConfig, m map[string]any) (Configs, error) {
c := make(Configs)
valid := make(map[string]bool)
// Add defaults
@@ -133,8 +135,6 @@ func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) {
valid[k] = true
}
- m := cfg.GetStringMap(cachesConfigKey)
-
_, isOsFs := fs.(*afero.OsFs)
for k, v := range m {
@@ -170,9 +170,6 @@ func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) {
c[name] = cc
}
- // This is a very old flag in Hugo, but we need to respect it.
- disabled := cfg.GetBool("ignoreCache")
-
for k, v := range c {
dir := filepath.ToSlash(filepath.Clean(v.Dir))
hadSlash := strings.HasPrefix(dir, "/")
@@ -180,12 +177,12 @@ func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) {
for i, part := range parts {
if strings.HasPrefix(part, ":") {
- resolved, isResource, err := resolveDirPlaceholder(fs, cfg, part)
+ resolved, isResource, err := resolveDirPlaceholder(fs, bcfg, part)
if err != nil {
return c, err
}
if isResource {
- v.isResourceDir = true
+ v.IsResourceDir = true
}
parts[i] = resolved
}
@@ -195,33 +192,29 @@ func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) {
if hadSlash {
dir = "/" + dir
}
- v.Dir = filepath.Clean(filepath.FromSlash(dir))
+ v.DirCompiled = filepath.Clean(filepath.FromSlash(dir))
- if !v.isResourceDir {
- if isOsFs && !filepath.IsAbs(v.Dir) {
- return c, fmt.Errorf("%q must resolve to an absolute directory", v.Dir)
+ if !v.IsResourceDir {
+ if isOsFs && !filepath.IsAbs(v.DirCompiled) {
+ return c, fmt.Errorf("%q must resolve to an absolute directory", v.DirCompiled)
}
// Avoid cache in root, e.g. / (Unix) or c:\ (Windows)
- if len(strings.TrimPrefix(v.Dir, filepath.VolumeName(v.Dir))) == 1 {
- return c, fmt.Errorf("%q is a root folder and not allowed as cache dir", v.Dir)
+ if len(strings.TrimPrefix(v.DirCompiled, filepath.VolumeName(v.DirCompiled))) == 1 {
+ return c, fmt.Errorf("%q is a root folder and not allowed as cache dir", v.DirCompiled)
}
}
- if !strings.HasPrefix(v.Dir, "_gen") {
+ if !strings.HasPrefix(v.DirCompiled, "_gen") {
// We do cache eviction (file removes) and since the user can set
// his/hers own cache directory, we really want to make sure
// we do not delete any files that do not belong to this cache.
// We do add the cache name as the root, but this is an extra safe
// guard. We skip the files inside /resources/_gen/ because
// that would be breaking.
- v.Dir = filepath.Join(v.Dir, filecacheRootDirname, k)
+ v.DirCompiled = filepath.Join(v.DirCompiled, FilecacheRootDirname, k)
} else {
- v.Dir = filepath.Join(v.Dir, k)
- }
-
- if disabled {
- v.MaxAge = 0
+ v.DirCompiled = filepath.Join(v.DirCompiled, k)
}
c[k] = v
@@ -231,17 +224,15 @@ func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) {
}
// Resolves :resourceDir => /myproject/resources etc., :cacheDir => ...
-func resolveDirPlaceholder(fs afero.Fs, cfg config.Provider, placeholder string) (cacheDir string, isResource bool, err error) {
- workingDir := cfg.GetString("workingDir")
+func resolveDirPlaceholder(fs afero.Fs, bcfg config.BaseConfig, placeholder string) (cacheDir string, isResource bool, err error) {
switch strings.ToLower(placeholder) {
case ":resourcedir":
return "", true, nil
case ":cachedir":
- d, err := helpers.GetCacheDir(fs, cfg)
- return d, false, err
+ return bcfg.CacheDir, false, nil
case ":project":
- return filepath.Base(workingDir), false, nil
+ return filepath.Base(bcfg.WorkingDir), false, nil
}
return "", false, fmt.Errorf("%q is not a valid placeholder (valid values are :cacheDir or :resourceDir)", placeholder)
diff --git a/cache/filecache/filecache_config_test.go b/cache/filecache/filecache_config_test.go
index 1ed020ef1..f93c7060e 100644
--- a/cache/filecache/filecache_config_test.go
+++ b/cache/filecache/filecache_config_test.go
@@ -11,18 +11,19 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package filecache
+package filecache_test
import (
"path/filepath"
"runtime"
- "strings"
"testing"
"time"
"github.com/spf13/afero"
+ "github.com/gohugoio/hugo/cache/filecache"
"github.com/gohugoio/hugo/config"
+ "github.com/gohugoio/hugo/config/testconfig"
qt "github.com/frankban/quicktest"
)
@@ -57,22 +58,20 @@ dir = "/path/to/c4"
cfg, err := config.FromConfigString(configStr, "toml")
c.Assert(err, qt.IsNil)
fs := afero.NewMemMapFs()
- decoded, err := DecodeConfig(fs, cfg)
- c.Assert(err, qt.IsNil)
-
+ decoded := testconfig.GetTestConfigs(fs, cfg).Base.Caches
c.Assert(len(decoded), qt.Equals, 6)
c2 := decoded["getcsv"]
c.Assert(c2.MaxAge.String(), qt.Equals, "11h0m0s")
- c.Assert(c2.Dir, qt.Equals, filepath.FromSlash("/path/to/c2/filecache/getcsv"))
+ c.Assert(c2.DirCompiled, qt.Equals, filepath.FromSlash("/path/to/c2/filecache/getcsv"))
c3 := decoded["images"]
c.Assert(c3.MaxAge, qt.Equals, time.Duration(-1))
- c.Assert(c3.Dir, qt.Equals, filepath.FromSlash("/path/to/c3/filecache/images"))
+ c.Assert(c3.DirCompiled, qt.Equals, filepath.FromSlash("/path/to/c3/filecache/images"))
c4 := decoded["getresource"]
c.Assert(c4.MaxAge, qt.Equals, time.Duration(-1))
- c.Assert(c4.Dir, qt.Equals, filepath.FromSlash("/path/to/c4/filecache/getresource"))
+ c.Assert(c4.DirCompiled, qt.Equals, filepath.FromSlash("/path/to/c4/filecache/getresource"))
}
func TestDecodeConfigIgnoreCache(t *testing.T) {
@@ -106,9 +105,7 @@ dir = "/path/to/c4"
cfg, err := config.FromConfigString(configStr, "toml")
c.Assert(err, qt.IsNil)
fs := afero.NewMemMapFs()
- decoded, err := DecodeConfig(fs, cfg)
- c.Assert(err, qt.IsNil)
-
+ decoded := testconfig.GetTestConfigs(fs, cfg).Base.Caches
c.Assert(len(decoded), qt.Equals, 6)
for _, v := range decoded {
@@ -118,7 +115,7 @@ dir = "/path/to/c4"
func TestDecodeConfigDefault(t *testing.T) {
c := qt.New(t)
- cfg := newTestConfig()
+ cfg := config.New()
if runtime.GOOS == "windows" {
cfg.Set("resourceDir", "c:\\cache\\resources")
@@ -128,71 +125,22 @@ func TestDecodeConfigDefault(t *testing.T) {
cfg.Set("resourceDir", "/cache/resources")
cfg.Set("cacheDir", "/cache/thecache")
}
+ cfg.Set("workingDir", filepath.FromSlash("/my/cool/hugoproject"))
fs := afero.NewMemMapFs()
-
- decoded, err := DecodeConfig(fs, cfg)
-
- c.Assert(err, qt.IsNil)
-
+ decoded := testconfig.GetTestConfigs(fs, cfg).Base.Caches
c.Assert(len(decoded), qt.Equals, 6)
- imgConfig := decoded[cacheKeyImages]
- jsonConfig := decoded[cacheKeyGetJSON]
+ imgConfig := decoded[filecache.CacheKeyImages]
+ jsonConfig := decoded[filecache.CacheKeyGetJSON]
if runtime.GOOS == "windows" {
- c.Assert(imgConfig.Dir, qt.Equals, filepath.FromSlash("_gen/images"))
+ c.Assert(imgConfig.DirCompiled, qt.Equals, filepath.FromSlash("_gen/images"))
} else {
- c.Assert(imgConfig.Dir, qt.Equals, "_gen/images")
- c.Assert(jsonConfig.Dir, qt.Equals, "/cache/thecache/hugoproject/filecache/getjson")
+ c.Assert(imgConfig.DirCompiled, qt.Equals, "_gen/images")
+ c.Assert(jsonConfig.DirCompiled, qt.Equals, "/cache/thecache/hugoproject/filecache/getjson")
}
- c.Assert(imgConfig.isResourceDir, qt.Equals, true)
- c.Assert(jsonConfig.isResourceDir, qt.Equals, false)
-}
-
-func TestDecodeConfigInvalidDir(t *testing.T) {
- t.Parallel()
-
- c := qt.New(t)
-
- configStr := `
-resourceDir = "myresources"
-contentDir = "content"
-dataDir = "data"
-i18nDir = "i18n"
-layoutDir = "layouts"
-assetDir = "assets"
-archeTypedir = "archetypes"
-
-[caches]
-[caches.getJSON]
-maxAge = "10m"
-dir = "/"
-
-`
- if runtime.GOOS == "windows" {
- configStr = strings.Replace(configStr, "/", "c:\\\\", 1)
- }
-
- cfg, err := config.FromConfigString(configStr, "toml")
- c.Assert(err, qt.IsNil)
- fs := afero.NewMemMapFs()
-
- _, err = DecodeConfig(fs, cfg)
- c.Assert(err, qt.Not(qt.IsNil))
-}
-
-func newTestConfig() config.Provider {
- cfg := config.NewWithTestDefaults()
- cfg.Set("workingDir", filepath.FromSlash("/my/cool/hugoproject"))
- cfg.Set("contentDir", "content")
- cfg.Set("dataDir", "data")
- cfg.Set("resourceDir", "resources")
- cfg.Set("i18nDir", "i18n")
- cfg.Set("layoutDir", "layouts")
- cfg.Set("archetypeDir", "archetypes")
- cfg.Set("assetDir", "assets")
-
- return cfg
+ c.Assert(imgConfig.IsResourceDir, qt.Equals, true)
+ c.Assert(jsonConfig.IsResourceDir, qt.Equals, false)
}
diff --git a/cache/filecache/filecache_pruner.go b/cache/filecache/filecache_pruner.go
index b8aa76c15..e1b7f1947 100644
--- a/cache/filecache/filecache_pruner.go
+++ b/cache/filecache/filecache_pruner.go
@@ -31,7 +31,6 @@ import (
func (c Caches) Prune() (int, error) {
counter := 0
for k, cache := range c {
-
count, err := cache.Prune(false)
counter += count
@@ -58,6 +57,7 @@ func (c *Cache) Prune(force bool) (int, error) {
counter := 0
err := afero.Walk(c.Fs, "", func(name string, info os.FileInfo, err error) error {
+
if info == nil {
return nil
}
diff --git a/cache/filecache/filecache_pruner_test.go b/cache/filecache/filecache_pruner_test.go
index 46e1317ce..f0cecfe9f 100644
--- a/cache/filecache/filecache_pruner_test.go
+++ b/cache/filecache/filecache_pruner_test.go
@@ -11,13 +11,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package filecache
+package filecache_test
import (
"fmt"
"testing"
"time"
+ "github.com/gohugoio/hugo/cache/filecache"
"github.com/spf13/afero"
qt "github.com/frankban/quicktest"
@@ -52,10 +53,10 @@ maxAge = "200ms"
dir = ":resourceDir/_gen"
`
- for _, name := range []string{cacheKeyGetCSV, cacheKeyGetJSON, cacheKeyAssets, cacheKeyImages} {
+ for _, name := range []string{filecache.CacheKeyGetCSV, filecache.CacheKeyGetJSON, filecache.CacheKeyAssets, filecache.CacheKeyImages} {
msg := qt.Commentf("cache: %s", name)
p := newPathsSpec(t, afero.NewMemMapFs(), configStr)
- caches, err := NewCaches(p)
+ caches, err := filecache.NewCaches(p)
c.Assert(err, qt.IsNil)
cache := caches[name]
for i := 0; i < 10; i++ {
@@ -75,7 +76,7 @@ dir = ":resourceDir/_gen"
for i := 0; i < 10; i++ {
id := fmt.Sprintf("i%d", i)
- v := cache.getString(id)
+ v := cache.GetString(id)
if i < 5 {
c.Assert(v, qt.Equals, "")
} else {
@@ -83,7 +84,7 @@ dir = ":resourceDir/_gen"
}
}
- caches, err = NewCaches(p)
+ caches, err = filecache.NewCaches(p)
c.Assert(err, qt.IsNil)
cache = caches[name]
// Touch one and then prune.
@@ -98,7 +99,7 @@ dir = ":resourceDir/_gen"
// Now only the i5 should be left.
for i := 0; i < 10; i++ {
id := fmt.Sprintf("i%d", i)
- v := cache.getString(id)
+ v := cache.GetString(id)
if i != 5 {
c.Assert(v, qt.Equals, "")
} else {
diff --git a/cache/filecache/filecache_test.go b/cache/filecache/filecache_test.go
index 6b96a8601..61f9eda64 100644
--- a/cache/filecache/filecache_test.go
+++ b/cache/filecache/filecache_test.go
@@ -11,7 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package filecache
+package filecache_test
import (
"errors"
@@ -23,13 +23,10 @@ import (
"testing"
"time"
- "github.com/gobwas/glob"
-
- "github.com/gohugoio/hugo/langs"
- "github.com/gohugoio/hugo/modules"
-
+ "github.com/gohugoio/hugo/cache/filecache"
"github.com/gohugoio/hugo/common/hugio"
"github.com/gohugoio/hugo/config"
+ "github.com/gohugoio/hugo/config/testconfig"
"github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/hugofs"
@@ -83,27 +80,19 @@ dir = ":cacheDir/c"
p := newPathsSpec(t, osfs, configStr)
- caches, err := NewCaches(p)
+ caches, err := filecache.NewCaches(p)
c.Assert(err, qt.IsNil)
cache := caches.Get("GetJSON")
c.Assert(cache, qt.Not(qt.IsNil))
- c.Assert(cache.maxAge.String(), qt.Equals, "10h0m0s")
bfs, ok := cache.Fs.(*afero.BasePathFs)
c.Assert(ok, qt.Equals, true)
filename, err := bfs.RealPath("key")
c.Assert(err, qt.IsNil)
- if test.cacheDir != "" {
- c.Assert(filename, qt.Equals, filepath.Join(test.cacheDir, "c/"+filecacheRootDirname+"/getjson/key"))
- } else {
- // Temp dir.
- c.Assert(filename, qt.Matches, ".*hugo_cache.*"+filecacheRootDirname+".*key")
- }
cache = caches.Get("Images")
c.Assert(cache, qt.Not(qt.IsNil))
- c.Assert(cache.maxAge, qt.Equals, time.Duration(-1))
bfs, ok = cache.Fs.(*afero.BasePathFs)
c.Assert(ok, qt.Equals, true)
filename, _ = bfs.RealPath("key")
@@ -125,7 +114,7 @@ dir = ":cacheDir/c"
return []byte("bcd"), nil
}
- for _, ca := range []*Cache{caches.ImageCache(), caches.AssetsCache(), caches.GetJSONCache(), caches.GetCSVCache()} {
+ for _, ca := range []*filecache.Cache{caches.ImageCache(), caches.AssetsCache(), caches.GetJSONCache(), caches.GetCSVCache()} {
for i := 0; i < 2; i++ {
info, r, err := ca.GetOrCreate("a", rf("abc"))
c.Assert(err, qt.IsNil)
@@ -160,7 +149,7 @@ dir = ":cacheDir/c"
c.Assert(info.Name, qt.Equals, "mykey")
io.WriteString(w, "Hugo is great!")
w.Close()
- c.Assert(caches.ImageCache().getString("mykey"), qt.Equals, "Hugo is great!")
+ c.Assert(caches.ImageCache().GetString("mykey"), qt.Equals, "Hugo is great!")
info, r, err := caches.ImageCache().Get("mykey")
c.Assert(err, qt.IsNil)
@@ -201,7 +190,7 @@ dir = "/cache/c"
p := newPathsSpec(t, afero.NewMemMapFs(), configStr)
- caches, err := NewCaches(p)
+ caches, err := filecache.NewCaches(p)
c.Assert(err, qt.IsNil)
const cacheName = "getjson"
@@ -244,11 +233,11 @@ func TestFileCacheReadOrCreateErrorInRead(t *testing.T) {
var result string
- rf := func(failLevel int) func(info ItemInfo, r io.ReadSeeker) error {
- return func(info ItemInfo, r io.ReadSeeker) error {
+ rf := func(failLevel int) func(info filecache.ItemInfo, r io.ReadSeeker) error {
+ return func(info filecache.ItemInfo, r io.ReadSeeker) error {
if failLevel > 0 {
if failLevel > 1 {
- return ErrFatal
+ return filecache.ErrFatal
}
return errors.New("fail")
}
@@ -260,8 +249,8 @@ func TestFileCacheReadOrCreateErrorInRead(t *testing.T) {
}
}
- bf := func(s string) func(info ItemInfo, w io.WriteCloser) error {
- return func(info ItemInfo, w io.WriteCloser) error {
+ bf := func(s string) func(info filecache.ItemInfo, w io.WriteCloser) error {
+ return func(info filecache.ItemInfo, w io.WriteCloser) error {
defer w.Close()
result = s
_, err := w.Write([]byte(s))
@@ -269,7 +258,7 @@ func TestFileCacheReadOrCreateErrorInRead(t *testing.T) {
}
}
- cache := NewCache(afero.NewMemMapFs(), 100*time.Hour, "")
+ cache := filecache.NewCache(afero.NewMemMapFs(), 100*time.Hour, "")
const id = "a32"
@@ -283,60 +272,15 @@ func TestFileCacheReadOrCreateErrorInRead(t *testing.T) {
c.Assert(err, qt.IsNil)
c.Assert(result, qt.Equals, "v3")
_, err = cache.ReadOrCreate(id, rf(2), bf("v3"))
- c.Assert(err, qt.Equals, ErrFatal)
-}
-
-func TestCleanID(t *testing.T) {
- c := qt.New(t)
- c.Assert(cleanID(filepath.FromSlash("/a/b//c.txt")), qt.Equals, filepath.FromSlash("a/b/c.txt"))
- c.Assert(cleanID(filepath.FromSlash("a/b//c.txt")), qt.Equals, filepath.FromSlash("a/b/c.txt"))
-}
-
-func initConfig(fs afero.Fs, cfg config.Provider) error {
- if _, err := langs.LoadLanguageSettings(cfg, nil); err != nil {
- return err
- }
-
- modConfig, err := modules.DecodeConfig(cfg)
- if err != nil {
- return err
- }
-
- workingDir := cfg.GetString("workingDir")
- themesDir := cfg.GetString("themesDir")
- if !filepath.IsAbs(themesDir) {
- themesDir = filepath.Join(workingDir, themesDir)
- }
- globAll := glob.MustCompile("**", '/')
- modulesClient := modules.NewClient(modules.ClientConfig{
- Fs: fs,
- WorkingDir: workingDir,
- ThemesDir: themesDir,
- ModuleConfig: modConfig,
- IgnoreVendor: globAll,
- })
-
- moduleConfig, err := modulesClient.Collect()
- if err != nil {
- return err
- }
-
- if err := modules.ApplyProjectConfigDefaults(cfg, moduleConfig.ActiveModules[len(moduleConfig.ActiveModules)-1]); err != nil {
- return err
- }
-
- cfg.Set("allModules", moduleConfig.ActiveModules)
-
- return nil
+ c.Assert(err, qt.Equals, filecache.ErrFatal)
}
func newPathsSpec(t *testing.T, fs afero.Fs, configStr string) *helpers.PathSpec {
c := qt.New(t)
cfg, err := config.FromConfigString(configStr, "toml")
c.Assert(err, qt.IsNil)
- initConfig(fs, cfg)
- config.SetBaseTestDefaults(cfg)
- p, err := helpers.NewPathSpec(hugofs.NewFrom(fs, cfg), cfg, nil)
+ acfg := testconfig.GetTestConfig(fs, cfg)
+ p, err := helpers.NewPathSpec(hugofs.NewFrom(fs, acfg.BaseConfig()), acfg, nil)
c.Assert(err, qt.IsNil)
return p
}
diff --git a/cache/filecache/integration_test.go b/cache/filecache/integration_test.go
index 26653fc35..909895ec5 100644
--- a/cache/filecache/integration_test.go
+++ b/cache/filecache/integration_test.go
@@ -15,6 +15,9 @@ package filecache_test
import (
"path/filepath"
+
+ jww "github.com/spf13/jwalterweatherman"
+
"testing"
"time"
@@ -62,6 +65,7 @@ title: "Home"
-- assets/a/pixel.png --
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==
-- layouts/index.html --
+{{ warnf "HOME!" }}
{{ $img := resources.GetMatch "**.png" }}
{{ $img = $img.Resize "3x3" }}
{{ $img.RelPermalink }}
@@ -71,10 +75,11 @@ iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAA
`
b := hugolib.NewIntegrationTestBuilder(
- hugolib.IntegrationTestConfig{T: t, TxtarString: files, RunGC: true, NeedsOsFS: true},
+ hugolib.IntegrationTestConfig{T: t, TxtarString: files, Running: true, RunGC: true, NeedsOsFS: true, LogLevel: jww.LevelInfo},
).Build()
b.Assert(b.GCCount, qt.Equals, 0)
+ b.Assert(b.H, qt.IsNotNil)
imagesCacheDir := filepath.Join("_gen", "images")
_, err := b.H.BaseFs.ResourcesCache.Stat(imagesCacheDir)
@@ -86,9 +91,11 @@ iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAA
time.Sleep(300 * time.Millisecond)
b.RenameFile("assets/a/pixel.png", "assets/b/pixel2.png").Build()
+
b.Assert(b.GCCount, qt.Equals, 1)
// Build it again to GC the empty a dir.
b.Build()
+
_, err = b.H.BaseFs.ResourcesCache.Stat(filepath.Join(imagesCacheDir, "a"))
b.Assert(err, qt.Not(qt.IsNil))
_, err = b.H.BaseFs.ResourcesCache.Stat(imagesCacheDir)