Skip to content

Commit

Permalink
Fix regression on handling of overlapping file mounts
Browse files Browse the repository at this point in the history
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 #12103
  • Loading branch information
bep committed Feb 22, 2024
1 parent e757849 commit 16406d9
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 12 deletions.
9 changes: 8 additions & 1 deletion helpers/general.go
Expand Up @@ -328,7 +328,14 @@ func PrintFs(fs afero.Fs, path string, w io.Writer) {
}

afero.Walk(fs, path, func(path string, info os.FileInfo, err error) error {
fmt.Fprintln(w, filepath.ToSlash(path))
if err != nil {
panic(fmt.Sprintf("error: path %q: %s", path, err))
}
path = filepath.ToSlash(path)
if path == "" {
path = "."
}
fmt.Fprintln(w, path, info.IsDir())
return nil
})
}
Expand Down
39 changes: 32 additions & 7 deletions hugofs/rootmapping_fs.go
Expand Up @@ -323,7 +323,6 @@ func (fs *RootMappingFs) Stat(name string) (os.FileInfo, error) {
if err != nil {
return nil, err
}

return fis[0], nil
}

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

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

func (fs *RootMappingFs) getRootsReverse(key string) (string, []RootMapping) {
return fs.getRootsIn(key, fs.realMapToRoot)
var roots []RootMapping
var s string

for {
var found bool
ss, vv, found := tree.LongestPrefix(key)
if !found || (levels < 2 && ss == key) {
break
}

for _, rm := range vv.([]RootMapping) {
if !seen[rm] {
seen[rm] = true
roots = append(roots, rm)
}
}
s = ss

// We may have more than one root for this key, so walk up.
oldKey := key
key = filepath.Dir(key)
if key == oldKey {
break
}
}

return s, roots
}

func (fs *RootMappingFs) getRootsIn(key string, tree *radix.Tree) (string, []RootMapping) {
func (fs *RootMappingFs) getRootsReverse(key string) (string, []RootMapping) {
tree := fs.realMapToRoot
s, v, found := tree.LongestPrefix(key)

if !found {
return "", nil
}
Expand Down
42 changes: 39 additions & 3 deletions hugolib/filesystems/basefs_test.go
Expand Up @@ -478,11 +478,47 @@ Home.
_ = stat("blog/b1.md")
}

func TestStaticComposite(t *testing.T) {
files := `
-- hugo.toml --
disableKinds = ["taxonomy", "term"]
[module]
[[module.mounts]]
source = "myfiles/f1.txt"
target = "static/files/f1.txt"
[[module.mounts]]
source = "f3.txt"
target = "static/f3.txt"
[[module.mounts]]
source = "static"
target = "static"
-- static/files/f2.txt --
f2
-- myfiles/f1.txt --
f1
-- f3.txt --
f3
-- layouts/home.html --
Home.
`
b := hugolib.Test(t, files)

b.AssertFs(b.H.BaseFs.StaticFs(""), `
. true
f3.txt false
files true
files/f1.txt false
files/f2.txt false
`)
}

func checkFileCount(fs afero.Fs, dirname string, c *qt.C, expected int) {
c.Helper()
count, _, err := countFilesAndGetFilenames(fs, dirname)
c.Assert(err, qt.IsNil)
c.Assert(count, qt.Equals, expected)
count, names, err := countFilesAndGetFilenames(fs, dirname)
namesComment := qt.Commentf("filenames: %v", names)
c.Assert(err, qt.IsNil, namesComment)
c.Assert(count, qt.Equals, expected, namesComment)
}

func checkFileContent(fs afero.Fs, filename string, c *qt.C, expected ...string) {
Expand Down
6 changes: 5 additions & 1 deletion hugolib/integrationtest_builder.go
Expand Up @@ -275,9 +275,13 @@ func (s *IntegrationTestBuilder) AssertFileContentExact(filename string, matches
}

func (s *IntegrationTestBuilder) AssertPublishDir(matches ...string) {
s.AssertFs(s.fs.PublishDir, matches...)
}

func (s *IntegrationTestBuilder) AssertFs(fs afero.Fs, matches ...string) {
s.Helper()
var buff bytes.Buffer
helpers.PrintFs(s.H.Fs.PublishDir, "", &buff)
helpers.PrintFs(fs, "", &buff)
printFsLines := strings.Split(buff.String(), "\n")
sort.Strings(printFsLines)
content := strings.TrimSpace((strings.Join(printFsLines, "\n")))
Expand Down
27 changes: 27 additions & 0 deletions testscripts/commands/hugo__static_composite.txt
@@ -0,0 +1,27 @@
hugo
ls public/files
checkfile public/files/f1.txt
checkfile public/files/f2.txt
checkfile public/f3.txt

-- hugo.toml --
disableKinds = ["taxonomy", "term"]
[module]
[[module.mounts]]
source = "myfiles/f1.txt"
target = "static/files/f1.txt"
[[module.mounts]]
source = "f3.txt"
target = "static/f3.txt"
[[module.mounts]]
source = "static"
target = "static"
-- static/files/f2.txt --
f2
-- myfiles/f1.txt --
f1
-- f3.txt --
f3
-- layouts/home.html --
Home.

0 comments on commit 16406d9

Please sign in to comment.