diff options
Diffstat (limited to 'hugolib/filesystems/basefs_test.go')
-rw-r--r-- | hugolib/filesystems/basefs_test.go | 319 |
1 files changed, 223 insertions, 96 deletions
diff --git a/hugolib/filesystems/basefs_test.go b/hugolib/filesystems/basefs_test.go index 1724f3838..5398055ed 100644 --- a/hugolib/filesystems/basefs_test.go +++ b/hugolib/filesystems/basefs_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 The Hugo Authors. All rights reserved. +// Copyright 2024 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,11 +18,13 @@ import ( "fmt" "os" "path/filepath" + "runtime" "strings" "testing" "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/config/testconfig" + "github.com/gohugoio/hugo/hugolib" "github.com/spf13/afero" @@ -54,22 +56,22 @@ func TestNewBaseFs(t *testing.T) { base := filepath.Join(workingDir, "themes", theme, dir) filenameTheme := filepath.Join(base, fmt.Sprintf("theme-file-%s.txt", theme)) filenameOverlap := filepath.Join(base, "f3.txt") - afs.Mkdir(base, 0755) + afs.Mkdir(base, 0o755) content := []byte(fmt.Sprintf("content:%s:%s", theme, dir)) - afero.WriteFile(afs, filenameTheme, content, 0755) - afero.WriteFile(afs, filenameOverlap, content, 0755) + afero.WriteFile(afs, filenameTheme, content, 0o755) + afero.WriteFile(afs, filenameOverlap, content, 0o755) } // Write some files to the root of the theme base := filepath.Join(workingDir, "themes", theme) - afero.WriteFile(afs, filepath.Join(base, fmt.Sprintf("theme-root-%s.txt", theme)), []byte(fmt.Sprintf("content:%s", theme)), 0755) - afero.WriteFile(afs, filepath.Join(base, "file-theme-root.txt"), []byte(fmt.Sprintf("content:%s", theme)), 0755) + afero.WriteFile(afs, filepath.Join(base, fmt.Sprintf("theme-root-%s.txt", theme)), []byte(fmt.Sprintf("content:%s", theme)), 0o755) + afero.WriteFile(afs, filepath.Join(base, "file-theme-root.txt"), []byte(fmt.Sprintf("content:%s", theme)), 0o755) } - afero.WriteFile(afs, filepath.Join(workingDir, "file-root.txt"), []byte("content-project"), 0755) + afero.WriteFile(afs, filepath.Join(workingDir, "file-root.txt"), []byte("content-project"), 0o755) afero.WriteFile(afs, filepath.Join(workingDir, "themes", "btheme", "config.toml"), []byte(` theme = ["atheme"] -`), 0755) +`), 0o755) setConfigAndWriteSomeFilesTo(afs, v, "contentDir", "mycontent", 3) setConfigAndWriteSomeFilesTo(afs, v, "i18nDir", "myi18n", 4) @@ -113,17 +115,10 @@ theme = ["atheme"] checkFileCount(bfs.Assets.Fs, "", c, 9) checkFileCount(bfs.Work, "", c, 90) - c.Assert(bfs.IsData(filepath.Join(workingDir, "mydata", "file1.txt")), qt.Equals, true) - c.Assert(bfs.IsI18n(filepath.Join(workingDir, "myi18n", "file1.txt")), qt.Equals, true) - c.Assert(bfs.IsLayout(filepath.Join(workingDir, "mylayouts", "file1.txt")), qt.Equals, true) c.Assert(bfs.IsStatic(filepath.Join(workingDir, "mystatic", "file1.txt")), qt.Equals, true) - c.Assert(bfs.IsAsset(filepath.Join(workingDir, "myassets", "file1.txt")), qt.Equals, true) contentFilename := filepath.Join(workingDir, "mycontent", "file1.txt") c.Assert(bfs.IsContent(contentFilename), qt.Equals, true) - rel := bfs.RelContentDir(contentFilename) - c.Assert(rel, qt.Equals, "file1.txt") - // Check Work fs vs theme checkFileContent(bfs.Work, "file-root.txt", c, "content-project") checkFileContent(bfs.Work, "theme-root-atheme.txt", c, "content:atheme") @@ -168,34 +163,29 @@ func TestRealDirs(t *testing.T) { v.Set("assetDir", "myassets") v.Set("theme", "mytheme") - afs := hugofs.Os - - defer func() { - os.RemoveAll(root) - os.RemoveAll(themesDir) - }() + afs := &hugofs.OpenFilesFs{Fs: hugofs.Os} - c.Assert(afs.MkdirAll(filepath.Join(root, "myassets", "scss", "sf1"), 0755), qt.IsNil) - c.Assert(afs.MkdirAll(filepath.Join(root, "myassets", "scss", "sf2"), 0755), qt.IsNil) - c.Assert(afs.MkdirAll(filepath.Join(themesDir, "mytheme", "assets", "scss", "sf2"), 0755), qt.IsNil) - c.Assert(afs.MkdirAll(filepath.Join(themesDir, "mytheme", "assets", "scss", "sf3"), 0755), qt.IsNil) - c.Assert(afs.MkdirAll(filepath.Join(root, "resources"), 0755), qt.IsNil) - c.Assert(afs.MkdirAll(filepath.Join(themesDir, "mytheme", "resources"), 0755), qt.IsNil) + c.Assert(afs.MkdirAll(filepath.Join(root, "myassets", "scss", "sf1"), 0o755), qt.IsNil) + c.Assert(afs.MkdirAll(filepath.Join(root, "myassets", "scss", "sf2"), 0o755), qt.IsNil) + c.Assert(afs.MkdirAll(filepath.Join(themesDir, "mytheme", "assets", "scss", "sf2"), 0o755), qt.IsNil) + c.Assert(afs.MkdirAll(filepath.Join(themesDir, "mytheme", "assets", "scss", "sf3"), 0o755), qt.IsNil) + c.Assert(afs.MkdirAll(filepath.Join(root, "resources"), 0o755), qt.IsNil) + c.Assert(afs.MkdirAll(filepath.Join(themesDir, "mytheme", "resources"), 0o755), qt.IsNil) - c.Assert(afs.MkdirAll(filepath.Join(root, "myassets", "js", "f2"), 0755), qt.IsNil) + c.Assert(afs.MkdirAll(filepath.Join(root, "myassets", "js", "f2"), 0o755), qt.IsNil) - afero.WriteFile(afs, filepath.Join(filepath.Join(root, "myassets", "scss", "sf1", "a1.scss")), []byte("content"), 0755) - afero.WriteFile(afs, filepath.Join(filepath.Join(root, "myassets", "scss", "sf2", "a3.scss")), []byte("content"), 0755) - afero.WriteFile(afs, filepath.Join(filepath.Join(root, "myassets", "scss", "a2.scss")), []byte("content"), 0755) - afero.WriteFile(afs, filepath.Join(filepath.Join(themesDir, "mytheme", "assets", "scss", "sf2", "a3.scss")), []byte("content"), 0755) - afero.WriteFile(afs, filepath.Join(filepath.Join(themesDir, "mytheme", "assets", "scss", "sf3", "a4.scss")), []byte("content"), 0755) + afero.WriteFile(afs, filepath.Join(filepath.Join(root, "myassets", "scss", "sf1", "a1.scss")), []byte("content"), 0o755) + afero.WriteFile(afs, filepath.Join(filepath.Join(root, "myassets", "scss", "sf2", "a3.scss")), []byte("content"), 0o755) + afero.WriteFile(afs, filepath.Join(filepath.Join(root, "myassets", "scss", "a2.scss")), []byte("content"), 0o755) + afero.WriteFile(afs, filepath.Join(filepath.Join(themesDir, "mytheme", "assets", "scss", "sf2", "a3.scss")), []byte("content"), 0o755) + afero.WriteFile(afs, filepath.Join(filepath.Join(themesDir, "mytheme", "assets", "scss", "sf3", "a4.scss")), []byte("content"), 0o755) - afero.WriteFile(afs, filepath.Join(filepath.Join(themesDir, "mytheme", "resources", "t1.txt")), []byte("content"), 0755) - afero.WriteFile(afs, filepath.Join(filepath.Join(root, "resources", "p1.txt")), []byte("content"), 0755) - afero.WriteFile(afs, filepath.Join(filepath.Join(root, "resources", "p2.txt")), []byte("content"), 0755) + afero.WriteFile(afs, filepath.Join(filepath.Join(themesDir, "mytheme", "resources", "t1.txt")), []byte("content"), 0o755) + afero.WriteFile(afs, filepath.Join(filepath.Join(root, "resources", "p1.txt")), []byte("content"), 0o755) + afero.WriteFile(afs, filepath.Join(filepath.Join(root, "resources", "p2.txt")), []byte("content"), 0o755) - afero.WriteFile(afs, filepath.Join(filepath.Join(root, "myassets", "js", "f2", "a1.js")), []byte("content"), 0755) - afero.WriteFile(afs, filepath.Join(filepath.Join(root, "myassets", "js", "a2.js")), []byte("content"), 0755) + afero.WriteFile(afs, filepath.Join(filepath.Join(root, "myassets", "js", "f2", "a1.js")), []byte("content"), 0o755) + afero.WriteFile(afs, filepath.Join(filepath.Join(root, "myassets", "js", "a2.js")), []byte("content"), 0o755) conf := testconfig.GetTestConfig(afs, v) fs := hugofs.NewFrom(afs, conf.BaseConfig()) @@ -212,6 +202,83 @@ func TestRealDirs(t *testing.T) { c.Assert(realDirs[0], qt.Equals, filepath.Join(root, "myassets/scss")) c.Assert(realDirs[len(realDirs)-1], qt.Equals, filepath.Join(themesDir, "mytheme/assets/scss")) + realDirs = bfs.Assets.RealDirs("foo") + c.Assert(len(realDirs), qt.Equals, 0) + + c.Assert(afs.OpenFiles(), qt.HasLen, 0) +} + +func TestWatchFilenames(t *testing.T) { + t.Parallel() + files := ` +-- hugo.toml -- +theme = "t1" +[[module.mounts]] +source = 'content' +target = 'content' +[[module.mounts]] +source = 'content2' +target = 'content/c2' +[[module.mounts]] +source = "hugo_stats.json" +target = "assets/watching/hugo_stats.json" +-- hugo_stats.json -- +Some stats. +-- content/foo.md -- +foo +-- content2/bar.md -- +-- themes/t1/layouts/_default/single.html -- +{{ .Content }} +-- themes/t1/static/f1.txt -- +` + b := hugolib.Test(t, files) + bfs := b.H.BaseFs + watchFilenames := bfs.WatchFilenames() + b.Assert(watchFilenames, qt.HasLen, 6) +} + +func TestNoSymlinks(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("skip on Windows") + } + files := ` +-- hugo.toml -- +theme = "t1" +-- content/a/foo.md -- +foo +-- static/a/f1.txt -- +F1 text +-- themes/t1/layouts/_default/single.html -- +{{ .Content }} +-- themes/t1/static/a/f1.txt -- +` + tmpDir := t.TempDir() + + wd, _ := os.Getwd() + + for _, component := range []string{"content", "static"} { + aDir := filepath.Join(tmpDir, component, "a") + bDir := filepath.Join(tmpDir, component, "b") + os.MkdirAll(aDir, 0o755) + os.MkdirAll(bDir, 0o755) + os.Chdir(bDir) + os.Symlink("../a", "c") + } + + os.Chdir(wd) + + b := hugolib.NewIntegrationTestBuilder( + hugolib.IntegrationTestConfig{ + T: t, + TxtarString: files, + NeedsOsFS: true, + WorkingDir: tmpDir, + }, + ).Build() + + bfs := b.H.BaseFs + watchFilenames := bfs.WatchFilenames() + b.Assert(watchFilenames, qt.HasLen, 10) } func TestStaticFs(t *testing.T) { @@ -228,10 +295,10 @@ func TestStaticFs(t *testing.T) { themeStaticDir := filepath.Join(workDir, "themes", "t1", "static") themeStaticDir2 := filepath.Join(workDir, "themes", "t2", "static") - afero.WriteFile(afs, filepath.Join(workDir, "mystatic", "f1.txt"), []byte("Hugo Rocks!"), 0755) - afero.WriteFile(afs, filepath.Join(themeStaticDir, "f1.txt"), []byte("Hugo Themes Rocks!"), 0755) - afero.WriteFile(afs, filepath.Join(themeStaticDir, "f2.txt"), []byte("Hugo Themes Still Rocks!"), 0755) - afero.WriteFile(afs, filepath.Join(themeStaticDir2, "f2.txt"), []byte("Hugo Themes Rocks in t2!"), 0755) + afero.WriteFile(afs, filepath.Join(workDir, "mystatic", "f1.txt"), []byte("Hugo Rocks!"), 0o755) + afero.WriteFile(afs, filepath.Join(themeStaticDir, "f1.txt"), []byte("Hugo Themes Rocks!"), 0o755) + afero.WriteFile(afs, filepath.Join(themeStaticDir, "f2.txt"), []byte("Hugo Themes Still Rocks!"), 0o755) + afero.WriteFile(afs, filepath.Join(themeStaticDir2, "f2.txt"), []byte("Hugo Themes Rocks in t2!"), 0o755) conf := testconfig.GetTestConfig(afs, v) fs := hugofs.NewFrom(afs, conf.BaseConfig()) @@ -273,17 +340,15 @@ func TestStaticFsMultiHost(t *testing.T) { themeStaticDir := filepath.Join(workDir, "themes", "t1", "static") - afero.WriteFile(afs, filepath.Join(workDir, "mystatic", "f1.txt"), []byte("Hugo Rocks!"), 0755) - afero.WriteFile(afs, filepath.Join(workDir, "static_no", "f1.txt"), []byte("Hugo Rocks in Norway!"), 0755) + afero.WriteFile(afs, filepath.Join(workDir, "mystatic", "f1.txt"), []byte("Hugo Rocks!"), 0o755) + afero.WriteFile(afs, filepath.Join(workDir, "static_no", "f1.txt"), []byte("Hugo Rocks in Norway!"), 0o755) - afero.WriteFile(afs, filepath.Join(themeStaticDir, "f1.txt"), []byte("Hugo Themes Rocks!"), 0755) - afero.WriteFile(afs, filepath.Join(themeStaticDir, "f2.txt"), []byte("Hugo Themes Still Rocks!"), 0755) + afero.WriteFile(afs, filepath.Join(themeStaticDir, "f1.txt"), []byte("Hugo Themes Rocks!"), 0o755) + afero.WriteFile(afs, filepath.Join(themeStaticDir, "f2.txt"), []byte("Hugo Themes Still Rocks!"), 0o755) conf := testconfig.GetTestConfig(afs, v) fs := hugofs.NewFrom(afs, conf.BaseConfig()) - fmt.Println("IS", conf.IsMultihost()) - p, err := paths.New(fs, conf) c.Assert(err, qt.IsNil) bfs, err := filesystems.NewBase(p, nil) @@ -298,54 +363,119 @@ func TestStaticFsMultiHost(t *testing.T) { } func TestMakePathRelative(t *testing.T) { - c := qt.New(t) - v := config.New() - afs := afero.NewMemMapFs() - workDir := "mywork" - v.Set("workingDir", workDir) + files := ` +-- hugo.toml -- +[[module.mounts]] +source = "bar.txt" +target = "assets/foo/baz.txt" +[[module.imports]] +path = "t1" +[[module.imports.mounts]] +source = "src" +target = "assets/foo/bar" +-- bar.txt -- +Bar. +-- themes/t1/src/main.js -- +Main. +` + b := hugolib.Test(t, files) + + rel, found := b.H.BaseFs.Assets.MakePathRelative(filepath.FromSlash("/themes/t1/src/main.js")) + b.Assert(found, qt.Equals, true) + b.Assert(rel, qt.Equals, filepath.FromSlash("foo/bar/main.js")) + + rel, found = b.H.BaseFs.Assets.MakePathRelative(filepath.FromSlash("/bar.txt")) + b.Assert(found, qt.Equals, true) + b.Assert(rel, qt.Equals, filepath.FromSlash("foo/baz.txt")) +} - c.Assert(afs.MkdirAll(filepath.Join(workDir, "dist", "d1"), 0777), qt.IsNil) - c.Assert(afs.MkdirAll(filepath.Join(workDir, "static", "d2"), 0777), qt.IsNil) - c.Assert(afs.MkdirAll(filepath.Join(workDir, "dust", "d2"), 0777), qt.IsNil) - - moduleCfg := map[string]any{ - "mounts": []any{ - map[string]any{ - "source": "dist", - "target": "static/mydist", - }, - map[string]any{ - "source": "dust", - "target": "static/foo/bar", - }, - map[string]any{ - "source": "static", - "target": "static", - }, +func TestAbsProjectContentDir(t *testing.T) { + tempDir := t.TempDir() + + files := ` +-- hugo.toml -- +[[module.mounts]] +source = "content" +target = "content" +-- content/foo.md -- +--- +title: "Foo" +--- +` + + b := hugolib.NewIntegrationTestBuilder( + hugolib.IntegrationTestConfig{ + T: t, + WorkingDir: tempDir, + TxtarString: files, }, - } - - v.Set("module", moduleCfg) - - conf := testconfig.GetTestConfig(afs, v) - fs := hugofs.NewFrom(afs, conf.BaseConfig()) + ).Build() + + abs1 := filepath.Join(tempDir, "content", "foo.md") + rel, abs2, err := b.H.BaseFs.AbsProjectContentDir("foo.md") + b.Assert(err, qt.IsNil) + b.Assert(abs2, qt.Equals, abs1) + b.Assert(rel, qt.Equals, filepath.FromSlash("foo.md")) + rel2, abs3, err := b.H.BaseFs.AbsProjectContentDir(abs1) + b.Assert(err, qt.IsNil) + b.Assert(abs3, qt.Equals, abs1) + b.Assert(rel2, qt.Equals, rel) +} - p, err := paths.New(fs, conf) - c.Assert(err, qt.IsNil) - bfs, err := filesystems.NewBase(p, nil) - c.Assert(err, qt.IsNil) +func TestContentReverseLookup(t *testing.T) { + files := ` +-- README.md -- +--- +title: README +--- +-- blog/b1.md -- +--- +title: b1 +--- +-- docs/d1.md -- +--- +title: d1 +--- +-- hugo.toml -- +baseURL = "https://example.com/" +[module] +[[module.mounts]] +source = "layouts" +target = "layouts" +[[module.mounts]] +source = "README.md" +target = "content/_index.md" +[[module.mounts]] +source = "blog" +target = "content/posts" +[[module.mounts]] +source = "docs" +target = "content/mydocs" +-- layouts/index.html -- +Home. + +` + b := hugolib.Test(t, files) + + b.AssertFileContent("public/index.html", "Home.") + + stat := func(path string) hugofs.FileMetaInfo { + ps, err := b.H.BaseFs.Content.ReverseLookup(filepath.FromSlash(path)) + b.Assert(err, qt.IsNil) + b.Assert(ps, qt.HasLen, 1) + first := ps[0] + fi, err := b.H.BaseFs.Content.Fs.Stat(filepath.FromSlash(first.Path)) + b.Assert(err, qt.IsNil) + b.Assert(fi, qt.Not(qt.IsNil)) + return fi.(hugofs.FileMetaInfo) + } - sfs := bfs.Static[""] - c.Assert(sfs, qt.Not(qt.IsNil)) + sfs := b.H.Fs.Source - makeRel := func(s string) string { - r, _ := sfs.MakePathRelative(s) - return r - } + _, err := sfs.Stat("blog/b1.md") + b.Assert(err, qt.Not(qt.IsNil)) - c.Assert(makeRel(filepath.Join(workDir, "dist", "d1", "foo.txt")), qt.Equals, filepath.FromSlash("mydist/d1/foo.txt")) - c.Assert(makeRel(filepath.Join(workDir, "static", "d2", "foo.txt")), qt.Equals, filepath.FromSlash("d2/foo.txt")) - c.Assert(makeRel(filepath.Join(workDir, "dust", "d3", "foo.txt")), qt.Equals, filepath.FromSlash("foo/bar/d3/foo.txt")) + _ = stat("blog/b1.md") } func checkFileCount(fs afero.Fs, dirname string, c *qt.C, expected int) { @@ -374,10 +504,7 @@ func countFilesAndGetFilenames(fs afero.Fs, dirname string) (int, []string, erro counter := 0 var filenames []string - wf := func(path string, info hugofs.FileMetaInfo, err error) error { - if err != nil { - return err - } + wf := func(path string, info hugofs.FileMetaInfo) error { if !info.IsDir() { counter++ } @@ -403,9 +530,9 @@ func countFilesAndGetFilenames(fs afero.Fs, dirname string) (int, []string, erro func setConfigAndWriteSomeFilesTo(fs afero.Fs, v config.Provider, key, val string, num int) { workingDir := v.GetString("workingDir") v.Set(key, val) - fs.Mkdir(val, 0755) + fs.Mkdir(val, 0o755) for i := 0; i < num; i++ { filename := filepath.Join(workingDir, val, fmt.Sprintf("f%d.txt", i+1)) - afero.WriteFile(fs, filename, []byte(fmt.Sprintf("content:%s:%d", key, i+1)), 0755) + afero.WriteFile(fs, filename, []byte(fmt.Sprintf("content:%s:%d", key, i+1)), 0o755) } } |