]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
Fix Processed images count regression for multiple languages
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sun, 28 May 2023 09:35:00 +0000 (11:35 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sun, 28 May 2023 10:55:44 +0000 (12:55 +0200)
Fixes #11002

deps/deps.go
main_test.go
resources/image.go
resources/image_cache.go
resources/resource_spec.go
resources/resource_transformers/htesting/testhelpers.go
resources/testdata/pix.gif [new file with mode: 0644]
testscripts/commands/hugo__processingstats.txt [new file with mode: 0644]

index 0eeb4248bd8b7a3ddfa32f6a00c573826c9e4ba0..39462de96fe773ecaa8f8400d6dc69a0b1899ea5 100644 (file)
@@ -189,10 +189,13 @@ func (d *Deps) Init() error {
        }
 
        var common *resources.SpecCommon
+       var imageCache *resources.ImageCache
        if d.ResourceSpec != nil {
                common = d.ResourceSpec.SpecCommon
+               imageCache = d.ResourceSpec.ImageCache
        }
-       resourceSpec, err := resources.NewSpec(d.PathSpec, common, d.BuildState, d.Log, d, d.ExecHelper)
+
+       resourceSpec, err := resources.NewSpec(d.PathSpec, common, imageCache, d.BuildState, d.Log, d, d.ExecHelper)
        if err != nil {
                return fmt.Errorf("failed to create resource spec: %w", err)
        }
index 73b9a08384cfee20afaf1c8e348dcf4b2136ef4f..5629db3fe21c9795a1c14224de1d51c4cdf83496 100644 (file)
@@ -370,12 +370,15 @@ var commonTestScriptsParam = testscript.Params{
 }
 
 func testSetupFunc() func(env *testscript.Env) error {
+       sourceDir, _ := os.Getwd()
        return func(env *testscript.Env) error {
                var keyVals []string
                keyVals = append(keyVals, "HUGO_TESTRUN", "true")
                hugoCachedDir := filepath.Join(env.WorkDir, "hugocache")
                keyVals = append(keyVals, "HUGO_CACHEDIR", hugoCachedDir)
 
+               keyVals = append(keyVals, "SOURCE", sourceDir)
+
                goVersion := runtime.Version()
                // Strip all but the major and minor version.
                goVersion = regexp.MustCompile(`^go(\d+\.\d+)`).FindStringSubmatch(goVersion)[1]
index c61e903abb50aaa9dec98240d94a56e28693f158..ad2f9de322739574fd87bc733ae85ba6bf413e3e 100644 (file)
@@ -126,7 +126,7 @@ func (i *imageResource) getExif() *exif.ExifInfo {
                        return enc.Encode(i.meta)
                }
 
-               _, i.metaInitErr = i.getSpec().imageCache.fileCache.ReadOrCreate(key, read, create)
+               _, i.metaInitErr = i.getSpec().ImageCache.fileCache.ReadOrCreate(key, read, create)
        })
 
        if i.metaInitErr != nil {
@@ -296,7 +296,7 @@ const imageProcWorkers = 1
 var imageProcSem = make(chan bool, imageProcWorkers)
 
 func (i *imageResource) doWithImageConfig(conf images.ImageConfig, f func(src image.Image) (image.Image, error)) (images.ImageResource, error) {
-       img, err := i.getSpec().imageCache.getOrCreate(i, conf, func() (*imageResource, image.Image, error) {
+       img, err := i.getSpec().ImageCache.getOrCreate(i, conf, func() (*imageResource, image.Image, error) {
                imageProcSem <- true
                defer func() {
                        <-imageProcSem
index ca651fd5cabd87c8a202896ddce1b865ee941862..636607f945254ae7e0fd75aa6fdfba8bd715fe23 100644 (file)
@@ -26,16 +26,27 @@ import (
        "github.com/gohugoio/hugo/helpers"
 )
 
-type imageCache struct {
+// ImageCache is a cache for image resources. The backing caches are shared between all sites.
+type ImageCache struct {
        pathSpec *helpers.PathSpec
 
        fileCache *filecache.Cache
 
+       *imageCacheStore
+}
+
+type imageCacheStore struct {
        mu    sync.RWMutex
        store map[string]*resourceAdapter
 }
 
-func (c *imageCache) deleteIfContains(s string) {
+// WithPathSpec returns a copy of the ImageCache with the given PathSpec set.
+func (c ImageCache) WithPathSpec(ps *helpers.PathSpec) *ImageCache {
+       c.pathSpec = ps
+       return &c
+}
+
+func (c *ImageCache) deleteIfContains(s string) {
        c.mu.Lock()
        defer c.mu.Unlock()
        s = c.normalizeKeyBase(s)
@@ -48,21 +59,21 @@ func (c *imageCache) deleteIfContains(s string) {
 
 // The cache key is a lowercase path with Unix style slashes and it always starts with
 // a leading slash.
-func (c *imageCache) normalizeKey(key string) string {
+func (c *ImageCache) normalizeKey(key string) string {
        return "/" + c.normalizeKeyBase(key)
 }
 
-func (c *imageCache) normalizeKeyBase(key string) string {
+func (c *ImageCache) normalizeKeyBase(key string) string {
        return strings.Trim(strings.ToLower(filepath.ToSlash(key)), "/")
 }
 
-func (c *imageCache) clear() {
+func (c *ImageCache) clear() {
        c.mu.Lock()
        defer c.mu.Unlock()
        c.store = make(map[string]*resourceAdapter)
 }
 
-func (c *imageCache) getOrCreate(
+func (c *ImageCache) getOrCreate(
        parent *imageResource, conf images.ImageConfig,
        createImage func() (*imageResource, image.Image, error)) (*resourceAdapter, error) {
        relTarget := parent.relTargetPathFromConfig(conf)
@@ -163,6 +174,6 @@ func (c *imageCache) getOrCreate(
        return imgAdapter, nil
 }
 
-func newImageCache(fileCache *filecache.Cache, ps *helpers.PathSpec) *imageCache {
-       return &imageCache{fileCache: fileCache, pathSpec: ps, store: make(map[string]*resourceAdapter)}
+func newImageCache(fileCache *filecache.Cache, ps *helpers.PathSpec) *ImageCache {
+       return &ImageCache{fileCache: fileCache, pathSpec: ps, imageCacheStore: &imageCacheStore{store: make(map[string]*resourceAdapter)}}
 }
index 4d2ceccb3b0ecf9e3114367f867c553d852311a2..5ecb021fe3a6b42783577746aed503f35a41e24e 100644 (file)
@@ -51,6 +51,7 @@ import (
 func NewSpec(
        s *helpers.PathSpec,
        common *SpecCommon, // may be nil
+       imageCache *ImageCache, // may be nil
        incr identity.Incrementer,
        logger loggers.Logger,
        errorHandler herrors.ErrorSender,
@@ -90,11 +91,6 @@ func NewSpec(
                                PostProcessResources: make(map[string]postpub.PostPublishedResource),
                                JSConfigBuilder:      jsconfig.NewBuilder(),
                        },
-                       imageCache: newImageCache(
-                               fileCaches.ImageCache(),
-
-                               s,
-                       ),
                        ResourceCache: &ResourceCache{
                                fileCache: fileCaches.AssetsCache(),
                                cache:     make(map[string]any),
@@ -103,11 +99,22 @@ func NewSpec(
                }
        }
 
+       if imageCache == nil {
+               imageCache = newImageCache(
+                       fileCaches.ImageCache(),
+                       s,
+               )
+       } else {
+               imageCache = imageCache.WithPathSpec(s)
+
+       }
+
        rs := &Spec{
                PathSpec:    s,
                Logger:      logger,
                ErrorSender: errorHandler,
                imaging:     imaging,
+               ImageCache:  imageCache,
                ExecHelper:  execHelper,
 
                Permalinks: permalinks,
@@ -128,6 +135,8 @@ type Spec struct {
 
        Permalinks page.PermalinkExpander
 
+       ImageCache *ImageCache
+
        // Holds default filter settings etc.
        imaging *images.ImageProcessor
 
@@ -139,7 +148,6 @@ type Spec struct {
 // The parts of Spec that's comoon for all sites.
 type SpecCommon struct {
        incr          identity.Incrementer
-       imageCache    *imageCache
        ResourceCache *ResourceCache
        FileCaches    filecache.Caches
 
@@ -171,13 +179,13 @@ func (r *Spec) BuildConfig() config.BuildConfig {
 }
 
 func (r *Spec) CacheStats() string {
-       r.imageCache.mu.RLock()
-       defer r.imageCache.mu.RUnlock()
+       r.ImageCache.mu.RLock()
+       defer r.ImageCache.mu.RUnlock()
 
-       s := fmt.Sprintf("Cache entries: %d", len(r.imageCache.store))
+       s := fmt.Sprintf("Cache entries: %d", len(r.ImageCache.store))
 
        count := 0
-       for k := range r.imageCache.store {
+       for k := range r.ImageCache.store {
                if count > 5 {
                        break
                }
@@ -189,12 +197,12 @@ func (r *Spec) CacheStats() string {
 }
 
 func (r *Spec) ClearCaches() {
-       r.imageCache.clear()
+       r.ImageCache.clear()
        r.ResourceCache.clear()
 }
 
 func (r *Spec) DeleteBySubstring(s string) {
-       r.imageCache.deleteIfContains(s)
+       r.ImageCache.deleteIfContains(s)
 }
 
 func (s *Spec) String() string {
index 75ae4245e95e91622b6f748fc82c74cb28aa3c3a..b1feccc5f0b63a327466dc5fc9ad6c1570f248da 100644 (file)
@@ -43,7 +43,7 @@ func NewTestResourceSpec() (*resources.Spec, error) {
                return nil, err
        }
 
-       spec, err := resources.NewSpec(s, nil, nil, nil, nil, nil)
+       spec, err := resources.NewSpec(s, nil, nil, nil, nil, nil, nil)
        return spec, err
 }
 
diff --git a/resources/testdata/pix.gif b/resources/testdata/pix.gif
new file mode 100644 (file)
index 0000000..f191b28
Binary files /dev/null and b/resources/testdata/pix.gif differ
diff --git a/testscripts/commands/hugo__processingstats.txt b/testscripts/commands/hugo__processingstats.txt
new file mode 100644 (file)
index 0000000..0e700b6
--- /dev/null
@@ -0,0 +1,34 @@
+cp $SOURCE/resources/testdata/pix.gif content/en/bundle1/pix.gif
+cp $SOURCE/resources/testdata/pix.gif content/en/bundle2/pix.gif
+cp $SOURCE/resources/testdata/pix.gif content/fr/bundle1/pix.gif
+
+hugo
+
+stdout 'Pages.*3.*2'
+stdout 'Processed images.*2.*1'
+
+-- content/en/bundle1/index.md --
+-- content/en/bundle2/index.md --
+-- content/fr/bundle1/index.md --
+-- hugo.toml --
+disableKinds = ["taxonomy", "term", "RSS", "sitemap", "robotsTXT", "404"]
+baseURL = "https://example.com/"
+[languages]
+    [languages.en]
+        languageName = "English"
+        weight = 1
+        title = "English Title"
+        contentDir = "content/en"
+    [languages.fr]
+        languageName = "French"
+        weight = 2
+        title = "French Title"
+        contentDir = "content/fr"
+-- layouts/index.html --
+Home.
+-- layouts/_default/single.html --
+Single.
+{{ range .Resources }}
+{{ $img := .Resize "3x" }}
+Resized: {{ $img.RelPermalink }}
+{{ end }}