From 2b2f2b75eff43ea3536350fa5a2c9ebbc1723ba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Fri, 1 Mar 2024 14:42:56 +0100 Subject: [PATCH] hugofs: Fix vertical mount merge issue Fixes #12175 --- hugofs/rootmapping_fs.go | 28 +++++++++++++++++++++++- hugolib/filesystems/basefs_test.go | 34 ++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/hugofs/rootmapping_fs.go b/hugofs/rootmapping_fs.go index 336c8b4e7..a30498668 100644 --- a/hugofs/rootmapping_fs.go +++ b/hugofs/rootmapping_fs.go @@ -475,6 +475,11 @@ func (fs *RootMappingFs) newUnionFile(fis ...FileMetaInfo) (afero.File, error) { return fis[0].Meta().Open() } + if !fis[0].IsDir() { + // Pick the last file mount. + return fis[len(fis)-1].Meta().Open() + } + openers := make([]func() (afero.File, error), len(fis)) for i := len(fis) - 1; i >= 0; i-- { fi := fis[i] @@ -647,6 +652,28 @@ func (rfs *RootMappingFs) collectDirEntries(prefix string) ([]iofs.DirEntry, err } func (fs *RootMappingFs) doStat(name string) ([]FileMetaInfo, error) { + fis, err := fs.doDoStat(name) + if err != nil { + return nil, err + } + // Sanity check. Check that all is either file or directories. + var isDir, isFile bool + for _, fi := range fis { + if fi.IsDir() { + isDir = true + } else { + isFile = true + } + } + if isDir && isFile { + // For now. + return nil, os.ErrNotExist + } + + return fis, nil +} + +func (fs *RootMappingFs) doDoStat(name string) ([]FileMetaInfo, error) { name = fs.cleanName(name) key := filepathSeparator + name @@ -669,7 +696,6 @@ func (fs *RootMappingFs) doStat(name string) ([]FileMetaInfo, error) { var fis []FileMetaInfo for _, rm := range roots { - var fi FileMetaInfo fi, err = fs.statRoot(rm, name) if err == nil { diff --git a/hugolib/filesystems/basefs_test.go b/hugolib/filesystems/basefs_test.go index 4fdeba765..10b4a4cb2 100644 --- a/hugolib/filesystems/basefs_test.go +++ b/hugolib/filesystems/basefs_test.go @@ -509,6 +509,40 @@ l2 } } +func TestAssetsIssue12175(t *testing.T) { + files := ` +-- hugo.toml -- +baseURL = "https://example.com/" +[module] +[[module.mounts]] +source = "node_modules/@foo/core/assets" +target = "assets" +[[module.mounts]] +source = "assets" +target = "assets" +-- node_modules/@foo/core/assets/js/app.js -- +JS. +-- node_modules/@foo/core/assets/scss/app.scss -- +body { color: red; } +-- assets/scss/app.scss -- +body { color: blue; } +-- layouts/index.html -- +Home. +SCSS: {{ with resources.Get "scss/app.scss" }}{{ .RelPermalink }}|{{ .Content }}{{ end }}| +# Note that the pattern below will match 2 resources, which doesn't make much sense, +# but is how the current (and also < v0.123.0) merge logic works, and for most practical purposes, it doesn't matter. +SCSS Match: {{ with resources.Match "**.scss" }}{{ . | len }}|{{ range .}}{{ .RelPermalink }}|{{ end }}{{ end }}| + +` + + b := hugolib.Test(t, files) + + b.AssertFileContent("public/index.html", ` +SCSS: /scss/app.scss|body { color: blue; }| +SCSS Match: 2| +`) +} + func TestStaticComposite(t *testing.T) { files := ` -- hugo.toml --