Repository: gohugoio/hugo (language: go)

Issue:
Weird cache-related issue with image processing .Resize
<!-- Please answer these questions before submitting your issue. Thanks! -->

### What version of Hugo are you using (`hugo version`)?

It's the official release of 0.87 Extended for Windows 64bit:

    $ hugo version
    hugo v0.87.0-B0C541E4+extended windows/amd64 BuildDate=2021-08-03T10:57:28Z VendorInfo=gohugoio

### Does this issue reproduce with the latest release?

Yes

# Minimal Test Case

Blank site, generated using `hugo new site`, with just these files.

`content/posts/a/index.md`: just a post. content is unimportant. 
`content/posts/a/file.jpg`: JPEG image as a resource to the post

`layouts/_default/single.html`:
```
{{ range .Resources }}
	{{ .Name }} {{ .MediaType }}

	{{ $webp := .Resize "100x webp" -}}
	{{ $webp.Name }} {{ $webp.MediaType }}
{{ end }}
```

Run `hugo` to generate the files:
```
D:\hugotest>hugo
Start building sites …
hugo v0.87.0-B0C541E4+extended windows/amd64 BuildDate=2021-08-03T10:57:28Z VendorInfo=gohugoio
WARN 2021/08/26 22:42:34 found no layout file for "HTML" for kind "home": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN 2021/08/26 22:42:34 found no layout file for "HTML" for kind "taxonomy": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN 2021/08/26 22:42:34 found no layout file for "HTML" for kind "section": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN 2021/08/26 22:42:34 found no layout file for "HTML" for kind "taxonomy": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.

                   | EN
-------------------+-----
  Pages            |  5
  Paginator pages  |  0
  Non-page files   |  1
  Static files     |  0
  Processed images |  1
  Aliases          |  0
  Sitemaps         |  1
  Cleaned          |  0

Total in 66 ms
```

Inspect the output is correct, as expected:
```
D:\hugotest>more public\posts\a\index.html

        file.jpg image/jpeg

        file.jpg image/webp
```

Run `hugo` again:
```
...
                   | EN
-------------------+-----
  Pages            |  5
  Paginator pages  |  0
  Non-page files   |  1
  Static files     |  0
  Processed images |  1
  Aliases          |  0
  Sitemaps         |  1
  Cleaned          |  0

Total in 39 ms
```

Inspect the output file again:
```
D:\hugotest>more public\posts\a\index.html

        file.jpg image/jpeg

        file.jpg image/jpeg
```

Notice the output of `$webp.MediaType` is now `image/jpeg`.

I understand that files are generated in `resources/_gen` and those need to be GC-ed. But specifying `--gc` to Hugo doesn't fix the problem.

It can only be fixed when the whole `resources` directory is deleted.

The file contents itself is correct. `$webp.Content` will get a WebP image, not a JPEG one, but the MIME type is wrong here.

I don't think this is supposed to happen, as it's working correctly the first time. Subsequent builds, or `hugo serve`, will yield weird results because of this.


Discussion / hints:
Verified. This cost me a couple of hours today, trying to figure out why the `MediaType` was wrong when building `<source>` elements within a `<picture>` element.

MRE: 

```bash
git clone --single-branch -b hugo-github-issue-8931 https://github.com/jmooring/hugo-testing hugo-github-issue-8931
cd hugo-github-issue-8931
```

The first run will look fine.

```bash
hugo && cat public/tests/test-1/index.html
```

The next run will be wrong:

```bash
hugo && cat public/tests/test-1/index.html
```

To obtain the correct results, you _must_ remove the cached images:

```bash
rm -rf resources/_gen/images/* && hugo && cat public/tests/test-1/index.html
```

Summary:
1. The problem _appears_ to be limited to the value of `MediaType`. 
2. The problem _always_ occurs when running hugo server.
3. You can work around the problem when running hugo (but not hugo server) by removing the cache before each run, which can be expensive.
This came up again today:
<https://discourse.gohugo.io/t/mediatype-of-converted-image-resource-does-not-change-after-conversion/38215>

Fix patch:
diff --git a/resources/image_cache.go b/resources/image_cache.go
index b5832f740f8..ca651fd5cab 100644
--- a/resources/image_cache.go
+++ b/resources/image_cache.go
@@ -95,6 +95,7 @@ func (c *imageCache) getOrCreate(
 		rp := img.getResourcePaths()
 		rp.relTargetDirFile.file = relTarget.file
 		img.setSourceFilename(info.Name)
+		img.setMediaType(conf.TargetFormat.MediaType())
 
 		if err := img.InitConfig(r); err != nil {
 			return err


Test patch:
diff --git a/hugolib/integrationtest_builder.go b/hugolib/integrationtest_builder.go
index e5c9a685620..58e75189270 100644
--- a/hugolib/integrationtest_builder.go
+++ b/hugolib/integrationtest_builder.go
@@ -2,6 +2,7 @@ package hugolib
 
 import (
 	"bytes"
+	"encoding/base64"
 	"fmt"
 	"io"
 	"os"
@@ -40,12 +41,13 @@ func NewIntegrationTestBuilder(conf IntegrationTestConfig) *IntegrationTestBuild
 	}
 
 	if conf.NeedsOsFS {
-		doClean := true
 		tempDir, clean, err := htesting.CreateTempDir(hugofs.Os, "hugo-integration-test")
 		c.Assert(err, qt.IsNil)
 		conf.WorkingDir = filepath.Join(tempDir, conf.WorkingDir)
-		if doClean {
+		if !conf.PrintAndKeepTempDir {
 			c.Cleanup(clean)
+		} else {
+			fmt.Println("\nUsing WorkingDir dir:", conf.WorkingDir)
 		}
 	} else if conf.WorkingDir == "" {
 		conf.WorkingDir = helpers.FilePathSeparator
@@ -278,10 +280,19 @@ func (s *IntegrationTestBuilder) initBuilder() {
 
 		logger := loggers.NewBasicLoggerForWriter(s.Cfg.LogLevel, &s.logBuff)
 
+		isBinaryRe := regexp.MustCompile(`^(.*)(\.png|\.jpg)$`)
+
 		for _, f := range s.data.Files {
 			filename := filepath.Join(s.Cfg.WorkingDir, f.Name)
+			data := bytes.TrimSuffix(f.Data, []byte("\n"))
+			if isBinaryRe.MatchString(filename) {
+				var err error
+				data, err = base64.StdEncoding.DecodeString(string(data))
+				s.Assert(err, qt.IsNil)
+
+			}
 			s.Assert(afs.MkdirAll(filepath.Dir(filename), 0777), qt.IsNil)
-			s.Assert(afero.WriteFile(afs, filename, bytes.TrimSuffix(f.Data, []byte("\n")), 0666), qt.IsNil)
+			s.Assert(afero.WriteFile(afs, filename, data, 0666), qt.IsNil)
 		}
 
 		cfg, _, err := LoadConfig(
@@ -297,6 +308,8 @@ func (s *IntegrationTestBuilder) initBuilder() {
 			},
 		)
 
+		s.Assert(err, qt.IsNil)
+
 		cfg.Set("workingDir", s.Cfg.WorkingDir)
 
 		fs := hugofs.NewFrom(afs, cfg)
@@ -457,6 +470,9 @@ type IntegrationTestConfig struct {
 	// Whether it needs the real file system (e.g. for js.Build tests).
 	NeedsOsFS bool
 
+	// Do not remove the temp dir after the test.
+	PrintAndKeepTempDir bool
+
 	// Whether to run npm install before Build.
 	NeedsNpmInstall bool
 
diff --git a/resources/integration_test.go b/resources/integration_test.go
new file mode 100644
index 00000000000..19cf8c19890
--- /dev/null
+++ b/resources/integration_test.go
@@ -0,0 +1,69 @@
+// Copyright 2022 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package resources_test
+
+import (
+	"strings"
+	"testing"
+
+	"github.com/gohugoio/hugo/hugolib"
+)
+
+// Issue 8931
+func TestImageCache(t *testing.T) {
+
+	files := `
+-- config.toml --
+baseURL = "https://example.org"
+-- content/mybundle/index.md --
+---
+title: "My Bundle"
+---
+-- content/mybundle/pixel.png --
+iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==
+-- layouts/foo.html --
+-- layouts/index.html --
+{{ $p := site.GetPage "mybundle"}}
+{{ $img := $p.Resources.Get "pixel.png" }}
+{{ $gif := $img.Resize "1x1 gif" }}
+{{ $bmp := $img.Resize "1x1 bmp" }}
+
+gif: {{ $gif.RelPermalink }}|{{ $gif.MediaType }}|
+bmp: {{ $bmp.RelPermalink }}|{{ $bmp.MediaType }}|	
+`
+
+	b := hugolib.NewIntegrationTestBuilder(
+		hugolib.IntegrationTestConfig{
+			T:           t,
+			TxtarString: files,
+			NeedsOsFS:   true,
+			Running:     true,
+		}).Build()
+
+	assertImages := func() {
+		b.AssertFileContent("public/index.html", `
+		gif: /mybundle/pixel_hu8aa3346827e49d756ff4e630147c42b5_70_1x1_resize_box_3.gif|image/gif|
+		bmp: /mybundle/pixel_hu8aa3346827e49d756ff4e630147c42b5_70_1x1_resize_box_3.bmp|image/bmp|
+		
+		`)
+	}
+
+	assertImages()
+
+	b.EditFileReplace("content/mybundle/index.md", func(s string) string { return strings.ReplaceAll(s, "Bundle", "BUNDLE") })
+	b.Build()
+
+	assertImages()
+
+}