From 1c0e7c1ae1eb9cd47fbe030ebddbf89df04fe667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Sun, 20 Mar 2022 11:24:44 +0100 Subject: [PATCH] Make sure file mounts higher up wins Fixes #9693 --- hugofs/fileinfo.go | 1 - hugofs/filter_fs.go | 4 +- hugofs/language_composite_fs.go | 37 +++----- hugofs/walk.go | 7 +- hugolib/filesystems/basefs.go | 12 +-- hugolib/language_content_dir_test.go | 121 +++++++++++++++++++++++++++ 6 files changed, 142 insertions(+), 40 deletions(-) diff --git a/hugofs/fileinfo.go b/hugofs/fileinfo.go index 40955545a..29ac3c240 100644 --- a/hugofs/fileinfo.go +++ b/hugofs/fileinfo.go @@ -60,7 +60,6 @@ type FileMeta struct { Module string Weight int - Ordinal int IsOrdered bool IsSymlink bool IsRootFile bool diff --git a/hugofs/filter_fs.go b/hugofs/filter_fs.go index 9da63bbb7..ec3897d9e 100644 --- a/hugofs/filter_fs.go +++ b/hugofs/filter_fs.go @@ -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), diff --git a/hugofs/language_composite_fs.go b/hugofs/language_composite_fs.go index 09c4540a9..65bc89e71 100644 --- a/hugofs/language_composite_fs.go +++ b/hugofs/language_composite_fs.go @@ -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 } diff --git a/hugofs/walk.go b/hugofs/walk.go index c02d36671..26f1b74e0 100644 --- a/hugofs/walk.go +++ b/hugofs/walk.go @@ -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 diff --git a/hugolib/filesystems/basefs.go b/hugolib/filesystems/basefs.go index 2e32932c6..6e3f88a4b 100644 --- a/hugolib/filesystems/basefs.go +++ b/hugolib/filesystems/basefs.go @@ -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 { diff --git a/hugolib/language_content_dir_test.go b/hugolib/language_content_dir_test.go index 682531566..541878220 100644 --- a/hugolib/language_content_dir_test.go +++ b/hugolib/language_content_dir_test.go @@ -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`) + +}