Skip to content

Commit 16406d9

Browse files
committed
Fix regression on handling of overlapping file mounts
But note that the overlay file system is set up horizontally (project -> module1 -> module2), so I would not recommend too complex overlapping mount setups within the same module. But this worked in v0.122.0, so we should fix it. Fixes gohugoio#12103
1 parent e757849 commit 16406d9

File tree

5 files changed

+111
-12
lines changed

5 files changed

+111
-12
lines changed

helpers/general.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,14 @@ func PrintFs(fs afero.Fs, path string, w io.Writer) {
328328
}
329329

330330
afero.Walk(fs, path, func(path string, info os.FileInfo, err error) error {
331-
fmt.Fprintln(w, filepath.ToSlash(path))
331+
if err != nil {
332+
panic(fmt.Sprintf("error: path %q: %s", path, err))
333+
}
334+
path = filepath.ToSlash(path)
335+
if path == "" {
336+
path = "."
337+
}
338+
fmt.Fprintln(w, path, info.IsDir())
332339
return nil
333340
})
334341
}

hugofs/rootmapping_fs.go

+32-7
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,6 @@ func (fs *RootMappingFs) Stat(name string) (os.FileInfo, error) {
323323
if err != nil {
324324
return nil, err
325325
}
326-
327326
return fis[0], nil
328327
}
329328

@@ -403,16 +402,42 @@ func (fs *RootMappingFs) getRoot(key string) []RootMapping {
403402
}
404403

405404
func (fs *RootMappingFs) getRoots(key string) (string, []RootMapping) {
406-
return fs.getRootsIn(key, fs.rootMapToReal)
407-
}
405+
tree := fs.rootMapToReal
406+
levels := strings.Count(key, filepathSeparator)
407+
seen := make(map[RootMapping]bool)
408408

409-
func (fs *RootMappingFs) getRootsReverse(key string) (string, []RootMapping) {
410-
return fs.getRootsIn(key, fs.realMapToRoot)
409+
var roots []RootMapping
410+
var s string
411+
412+
for {
413+
var found bool
414+
ss, vv, found := tree.LongestPrefix(key)
415+
if !found || (levels < 2 && ss == key) {
416+
break
417+
}
418+
419+
for _, rm := range vv.([]RootMapping) {
420+
if !seen[rm] {
421+
seen[rm] = true
422+
roots = append(roots, rm)
423+
}
424+
}
425+
s = ss
426+
427+
// We may have more than one root for this key, so walk up.
428+
oldKey := key
429+
key = filepath.Dir(key)
430+
if key == oldKey {
431+
break
432+
}
433+
}
434+
435+
return s, roots
411436
}
412437

413-
func (fs *RootMappingFs) getRootsIn(key string, tree *radix.Tree) (string, []RootMapping) {
438+
func (fs *RootMappingFs) getRootsReverse(key string) (string, []RootMapping) {
439+
tree := fs.realMapToRoot
414440
s, v, found := tree.LongestPrefix(key)
415-
416441
if !found {
417442
return "", nil
418443
}

hugolib/filesystems/basefs_test.go

+39-3
Original file line numberDiff line numberDiff line change
@@ -478,11 +478,47 @@ Home.
478478
_ = stat("blog/b1.md")
479479
}
480480

481+
func TestStaticComposite(t *testing.T) {
482+
files := `
483+
-- hugo.toml --
484+
disableKinds = ["taxonomy", "term"]
485+
[module]
486+
[[module.mounts]]
487+
source = "myfiles/f1.txt"
488+
target = "static/files/f1.txt"
489+
[[module.mounts]]
490+
source = "f3.txt"
491+
target = "static/f3.txt"
492+
[[module.mounts]]
493+
source = "static"
494+
target = "static"
495+
-- static/files/f2.txt --
496+
f2
497+
-- myfiles/f1.txt --
498+
f1
499+
-- f3.txt --
500+
f3
501+
-- layouts/home.html --
502+
Home.
503+
504+
`
505+
b := hugolib.Test(t, files)
506+
507+
b.AssertFs(b.H.BaseFs.StaticFs(""), `
508+
. true
509+
f3.txt false
510+
files true
511+
files/f1.txt false
512+
files/f2.txt false
513+
`)
514+
}
515+
481516
func checkFileCount(fs afero.Fs, dirname string, c *qt.C, expected int) {
482517
c.Helper()
483-
count, _, err := countFilesAndGetFilenames(fs, dirname)
484-
c.Assert(err, qt.IsNil)
485-
c.Assert(count, qt.Equals, expected)
518+
count, names, err := countFilesAndGetFilenames(fs, dirname)
519+
namesComment := qt.Commentf("filenames: %v", names)
520+
c.Assert(err, qt.IsNil, namesComment)
521+
c.Assert(count, qt.Equals, expected, namesComment)
486522
}
487523

488524
func checkFileContent(fs afero.Fs, filename string, c *qt.C, expected ...string) {

hugolib/integrationtest_builder.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,13 @@ func (s *IntegrationTestBuilder) AssertFileContentExact(filename string, matches
275275
}
276276

277277
func (s *IntegrationTestBuilder) AssertPublishDir(matches ...string) {
278+
s.AssertFs(s.fs.PublishDir, matches...)
279+
}
280+
281+
func (s *IntegrationTestBuilder) AssertFs(fs afero.Fs, matches ...string) {
278282
s.Helper()
279283
var buff bytes.Buffer
280-
helpers.PrintFs(s.H.Fs.PublishDir, "", &buff)
284+
helpers.PrintFs(fs, "", &buff)
281285
printFsLines := strings.Split(buff.String(), "\n")
282286
sort.Strings(printFsLines)
283287
content := strings.TrimSpace((strings.Join(printFsLines, "\n")))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
hugo
2+
ls public/files
3+
checkfile public/files/f1.txt
4+
checkfile public/files/f2.txt
5+
checkfile public/f3.txt
6+
7+
-- hugo.toml --
8+
disableKinds = ["taxonomy", "term"]
9+
[module]
10+
[[module.mounts]]
11+
source = "myfiles/f1.txt"
12+
target = "static/files/f1.txt"
13+
[[module.mounts]]
14+
source = "f3.txt"
15+
target = "static/f3.txt"
16+
[[module.mounts]]
17+
source = "static"
18+
target = "static"
19+
-- static/files/f2.txt --
20+
f2
21+
-- myfiles/f1.txt --
22+
f1
23+
-- f3.txt --
24+
f3
25+
-- layouts/home.html --
26+
Home.
27+

0 commit comments

Comments
 (0)