hugo

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

git clone git://git.shimmy1996.com/hugo.git
commit 9b352f04a385703084f7bb116e830e63ac262bc2
parent e66e2e9ce5f2036174ecb114b96761ad023d95a1
Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Date:   Mon, 18 Apr 2022 10:37:58 +0200

Fix syncing of /static regression

As introduced in Hugo `v0.76.1`.

And add a proper test for it.

Fixes  #9794
Closes #9788

Diffstat:
Mcommands/hugo_test.go | 126++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mgo.mod | 2+-
Mgo.sum | 2++
3 files changed, 119 insertions(+), 11 deletions(-)
diff --git a/commands/hugo_test.go b/commands/hugo_test.go
@@ -14,32 +14,138 @@
 package commands
 
 import (
+	"bytes"
+	"fmt"
+	"math/rand"
+	"path/filepath"
+	"strings"
 	"testing"
 
 	qt "github.com/frankban/quicktest"
+	"github.com/gohugoio/hugo/hugofs"
+	"github.com/spf13/afero"
+	"golang.org/x/tools/txtar"
 )
 
 // Issue #5662
 func TestHugoWithContentDirOverride(t *testing.T) {
+	t.Parallel()
 	c := qt.New(t)
 
-	hugoCmd := newCommandsBuilder().addAll().build()
-	cmd := hugoCmd.getCommand()
+	files := `
+-- config.toml --
+baseURL = "https://example.org"
+title = "Hugo Commands"
+-- mycontent/p1.md --
+---
+title: "P1"
+---
+-- layouts/_default/single.html --
+Page: {{ .Title }}|
 
-	contentDir := "contentOverride"
+`
+	s := newTestHugoCmdBuilder(c, files, []string{"-c", "mycontent"}).Build()
+	s.AssertFileContent("public/p1/index.html", `Page: P1|`)
 
-	cfgStr := `
+}
 
-baseURL = "https://example.org"
-title = "Hugo Commands"
+// Issue #9794
+func TestHugoStaticFilesMultipleStaticAndManyFolders(t *testing.T) {
+	t.Parallel()
+	c := qt.New(t)
 
-contentDir = "thisdoesnotexist"
+	files := `
+-- config.toml --
+baseURL = "https://example.org"
+theme = "mytheme"
+-- layouts/index.html --
+Home.
 
 `
-	dir := createSimpleTestSite(t, testSiteConfig{configTOML: cfgStr, contentDir: contentDir})
+	const (
+		numDirs     = 33
+		numFilesMax = 12
+	)
+
+	r := rand.New(rand.NewSource(32))
+
+	for i := 0; i < numDirs; i++ {
+		for j := 0; j < r.Intn(numFilesMax); j++ {
+			if j%3 == 0 {
+				files += fmt.Sprintf("-- themes/mytheme/static/d%d/f%d.txt --\nHellot%d-%d\n", i, j, i, j)
+				files += fmt.Sprintf("-- themes/mytheme/static/d%d/ft%d.txt --\nHellot%d-%d\n", i, j, i, j)
+			}
+			files += fmt.Sprintf("-- static/d%d/f%d.txt --\nHello%d-%d\n", i, j, i, j)
+		}
+	}
 
-	cmd.SetArgs([]string{"-s=" + dir, "-c=" + contentDir})
+	r = rand.New(rand.NewSource(32))
+
+	s := newTestHugoCmdBuilder(c, files, []string{"-c", "mycontent"}).Build()
+	for i := 0; i < numDirs; i++ {
+		for j := 0; j < r.Intn(numFilesMax); j++ {
+			if j%3 == 0 {
+				if j%3 == 0 {
+					s.AssertFileContent(fmt.Sprintf("public/d%d/ft%d.txt", i, j), fmt.Sprintf("Hellot%d-%d", i, j))
+				}
+				s.AssertFileContent(fmt.Sprintf("public/d%d/f%d.txt", i, j), fmt.Sprintf("Hello%d-%d", i, j))
+			}
+		}
+	}
+
+}
+
+type testHugoCmdBuilder struct {
+	*qt.C
+
+	fs    afero.Fs
+	dir   string
+	files string
+	args  []string
+}
+
+func newTestHugoCmdBuilder(c *qt.C, files string, args []string) *testHugoCmdBuilder {
+	s := &testHugoCmdBuilder{C: c, files: files, args: args}
+	s.dir = s.TempDir()
+	s.fs = afero.NewBasePathFs(hugofs.Os, s.dir)
+
+	return s
+}
+
+func (s *testHugoCmdBuilder) Build() *testHugoCmdBuilder {
+	data := txtar.Parse([]byte(s.files))
+
+	for _, f := range data.Files {
+		filename := filepath.Clean(f.Name)
+		data := bytes.TrimSuffix(f.Data, []byte("\n"))
+		s.Assert(s.fs.MkdirAll(filepath.Dir(filename), 0777), qt.IsNil)
+		s.Assert(afero.WriteFile(s.fs, filename, data, 0666), qt.IsNil)
+	}
+
+	hugoCmd := newCommandsBuilder().addAll().build()
+	cmd := hugoCmd.getCommand()
+	args := append(s.args, "-s="+s.dir, "--quiet")
+	cmd.SetArgs(args)
 
 	_, err := cmd.ExecuteC()
-	c.Assert(err, qt.IsNil)
+	s.Assert(err, qt.IsNil)
+
+	return s
+}
+
+func (s *testHugoCmdBuilder) AssertFileContent(filename string, matches ...string) {
+	s.Helper()
+	data, err := afero.ReadFile(s.fs, filename)
+	s.Assert(err, qt.IsNil)
+	content := strings.TrimSpace(string(data))
+	for _, m := range matches {
+		lines := strings.Split(m, "\n")
+		for _, match := range lines {
+			match = strings.TrimSpace(match)
+			if match == "" || strings.HasPrefix(match, "#") {
+				continue
+			}
+			s.Assert(content, qt.Contains, match, qt.Commentf(m))
+		}
+	}
 }
diff --git a/go.mod b/go.mod
@@ -12,7 +12,7 @@ require (
 	github.com/bep/godartsass v0.14.0
 	github.com/bep/golibsass v1.0.0
 	github.com/bep/gowebp v0.1.0
-	github.com/bep/overlayfs v0.5.0
+	github.com/bep/overlayfs v0.6.0
 	github.com/bep/tmc v0.5.1
 	github.com/clbanning/mxj/v2 v2.5.5
 	github.com/cli/safeexec v1.0.0
diff --git a/go.sum b/go.sum
@@ -236,6 +236,8 @@ github.com/bep/overlayfs v0.4.0 h1:J/G5YltfU2BxO2KV/VcFzJo94jpRMjtthRNEZ+7V7uA=
 github.com/bep/overlayfs v0.4.0/go.mod h1:NFjSmn3kCqG7KX2Lmz8qT8VhPPCwZap3UNogXawoQHM=
 github.com/bep/overlayfs v0.5.0 h1:5F7xbjVhPSMv/PX5KYeCeEMR/17Fm20G2A0Phe+dUmc=
 github.com/bep/overlayfs v0.5.0/go.mod h1:NFjSmn3kCqG7KX2Lmz8qT8VhPPCwZap3UNogXawoQHM=
+github.com/bep/overlayfs v0.6.0 h1:sgLcq/qtIzbaQNl2TldGXOkHvqeZB025sPvHOQL+DYo=
+github.com/bep/overlayfs v0.6.0/go.mod h1:NFjSmn3kCqG7KX2Lmz8qT8VhPPCwZap3UNogXawoQHM=
 github.com/bep/tmc v0.5.1 h1:CsQnSC6MsomH64gw0cT5f+EwQDcvZz4AazKunFwTpuI=
 github.com/bep/tmc v0.5.1/go.mod h1:tGYHN8fS85aJPhDLgXETVKp+PR382OvFi2+q2GkGsq0=
 github.com/bep/workers v1.0.0 h1:U+H8YmEaBCEaFZBst7GcRVEoqeRC9dzH2dWOwGmOchg=