Make sure file mounts higher up wins

Fixes #9693
This commit is contained in:
Bjørn Erik Pedersen 2022-03-20 11:24:44 +01:00
parent cad2d8cc70
commit 1c0e7c1ae1
6 changed files with 142 additions and 40 deletions

View file

@ -60,7 +60,6 @@ type FileMeta struct {
Module string
Weight int
Ordinal int
IsOrdered bool
IsSymlink bool
IsRootFile bool

View file

@ -47,10 +47,9 @@ func NewLanguageFs(langs map[string]int, fs afero.Fs) (afero.Fs, error) {
lang := meta.Lang
fileLang, translationBaseName, translationBaseNameWithExt := langInfoFrom(langs, fi.Name())
weight := 0
weight := meta.Weight
if fileLang != "" {
weight = 1
if fileLang == lang {
// Give priority to myfile.sv.txt inside the sv filesystem.
weight++
@ -63,7 +62,6 @@ func NewLanguageFs(langs map[string]int, fs afero.Fs) (afero.Fs, error) {
&FileMeta{
Lang: lang,
Weight: weight,
Ordinal: langs[lang],
TranslationBaseName: translationBaseName,
TranslationBaseNameWithExt: translationBaseNameWithExt,
Classifier: files.ClassifyContentFile(fi.Name(), meta.OpenFunc),

View file

@ -15,7 +15,6 @@ package hugofs
import (
"os"
"path"
"github.com/spf13/afero"
)
@ -56,32 +55,20 @@ func (fs *languageCompositeFs) Open(name string) (afero.File, error) {
// LanguageDirsMerger implements the afero.DirsMerger interface, which is used
// to merge two directories.
var LanguageDirsMerger = func(lofi, bofi []os.FileInfo) ([]os.FileInfo, error) {
m := make(map[string]FileMetaInfo)
getKey := func(fim FileMetaInfo) string {
return path.Join(fim.Meta().Lang, fim.Name())
}
for _, fi := range lofi {
fim := fi.(FileMetaInfo)
m[getKey(fim)] = fim
}
for _, fi := range bofi {
fim := fi.(FileMetaInfo)
key := getKey(fim)
_, found := m[key]
for _, fi1 := range bofi {
fim1 := fi1.(FileMetaInfo)
var found bool
for _, fi2 := range lofi {
fim2 := fi2.(FileMetaInfo)
if fi1.Name() == fi2.Name() && fim1.Meta().Lang == fim2.Meta().Lang {
found = true
break
}
}
if !found {
m[key] = fim
lofi = append(lofi, fi1)
}
}
merged := make([]os.FileInfo, len(m))
i := 0
for _, v := range m {
merged[i] = v
i++
}
return merged, nil
return lofi, nil
}

View file

@ -224,13 +224,8 @@ func (w *Walkway) walk(path string, info FileMetaInfo, dirEntries []FileMetaInfo
// to the closest one.
fiw, fjw := fim.Weight, fjm.Weight
if fiw != fjw {
return fiw > fjw
}
// Explicit order set.
fio, fjo := fim.Ordinal, fjm.Ordinal
if fio != fjo {
return fio < fjo
return fiw > fjw
}
// When we walk into a symlink, we keep the reference to

View file

@ -602,6 +602,7 @@ func (b *sourceFilesystemsBuilder) createMainOverlayFs(p *paths.Paths) (*filesys
Module: mod,
dir: dir,
isMainProject: isMainProject,
ordinal: j,
}
j++
}
@ -635,12 +636,12 @@ func (b *sourceFilesystemsBuilder) createModFs(
return md.dir, paths.AbsPathify(md.dir, path)
}
for _, mount := range md.Mounts() {
for i, mount := range md.Mounts() {
mountWeight := 1
if md.isMainProject {
mountWeight++
}
// Add more weight to early mounts.
// When two mounts contain the same filename,
// the first entry wins.
mountWeight := (10 + md.ordinal) * (len(md.Mounts()) - i)
inclusionFilter, err := glob.NewFilenameFilter(
types.ToStringSlicePreserveString(mount.IncludeFiles),
@ -829,6 +830,7 @@ type mountsDescriptor struct {
modules.Module
dir string
isMainProject bool
ordinal int
}
func (b *sourceFilesystemsBuilder) createOverlayFs(collector *filesystemsCollector, mounts []mountsDescriptor) error {

View file

@ -403,3 +403,124 @@ Page: /fr/event/page2/|ev-fr2
Page: /fr/other/page1/|other-fr1
Page: /fr/other/page2/|other-fr2`)
}
// Issue 9693
func TestContentMountMerge(t *testing.T) {
t.Parallel()
files := `
-- config.toml --
baseURL = 'https://example.org/'
languageCode = 'en-us'
title = 'Hugo Forum Topic #37225'
theme = 'mytheme'
disableKinds = ['sitemap','RSS','taxonomy','term']
defaultContentLanguage = 'en'
defaultContentLanguageInSubdir = true
[languages.en]
languageName = 'English'
weight = 1
[languages.de]
languageName = 'Deutsch'
weight = 2
[languages.nl]
languageName = 'Nederlands'
weight = 3
# EN content
[[module.mounts]]
source = 'content/en'
target = 'content'
lang = 'en'
# DE content
[[module.mounts]]
source = 'content/de'
target = 'content'
lang = 'de'
# This fills in the gaps in DE content with EN content
[[module.mounts]]
source = 'content/en'
target = 'content'
lang = 'de'
# NL content
[[module.mounts]]
source = 'content/nl'
target = 'content'
lang = 'nl'
# This should fill in the gaps in NL content with EN content
[[module.mounts]]
source = 'content/en'
target = 'content'
lang = 'nl'
-- content/de/_index.md --
---
title: "home (de)"
---
-- content/de/p1.md --
---
title: "p1 (de)"
---
-- content/en/_index.md --
---
title: "home (en)"
---
-- content/en/p1.md --
---
title: "p1 (en)"
---
-- content/en/p2.md --
---
title: "p2 (en)"
---
-- content/en/p3.md --
---
title: "p3 (en)"
---
-- content/nl/_index.md --
---
title: "home (nl)"
---
-- content/nl/p1.md --
---
title: "p1 (nl)"
---
-- content/nl/p3.md --
---
title: "p3 (nl)"
---
-- layouts/home.html --
{{ .Title }}: {{ site.Language.Lang }}: {{ range site.RegularPages }}{{ .Title }}|{{ end }}:END
-- themes/mytheme/config.toml --
[[module.mounts]]
source = 'content/nlt'
target = 'content'
lang = 'nl'
-- themes/mytheme/content/nlt/p3.md --
---
title: "p3 theme (nl)"
---
-- themes/mytheme/content/nlt/p4.md --
---
title: "p4 theme (nl)"
---
`
b := NewIntegrationTestBuilder(
IntegrationTestConfig{
T: t,
TxtarString: files,
},
).Build()
b.AssertFileContent("public/nl/index.html", `home (nl): nl: p1 (nl)|p2 (en)|p3 (nl)|p4 theme (nl)|:END`)
b.AssertFileContent("public/de/index.html", `home (de): de: p1 (de)|p2 (en)|p3 (en)|:END`)
b.AssertFileContent("public/en/index.html", `home (en): en: p1 (en)|p2 (en)|p3 (en)|:END`)
}