From 78578632f545283741a01f024a6ccedc0b695a30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Fri, 26 Oct 2018 09:41:24 +0200 Subject: [PATCH] Fix archetype handling of directories in theme Fixes #5318 --- create/content.go | 10 ++++++---- create/content_test.go | 12 ++++++++++++ hugolib/filesystems/basefs.go | 3 +++ hugolib/filesystems/basefs_test.go | 30 ++++++++++++++++++++++-------- 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/create/content.go b/create/content.go index 388f2b4a0f2..31b7b2e4d70 100644 --- a/create/content.go +++ b/create/content.go @@ -71,6 +71,7 @@ func NewContent( siteUsed := false if archetypeFilename != "" { + var err error siteUsed, err = usesSiteVar(archetypeFs, archetypeFilename) if err != nil { @@ -130,7 +131,7 @@ func newContentFromDir( // Just copy the file to destination. in, err := sourceFs.Open(filename) if err != nil { - return err + return errors.Wrap(err, "failed to open non-content file") } targetFilename := filepath.Join(targetPath, strings.TrimPrefix(filename, archetypeDir)) @@ -158,11 +159,11 @@ func newContentFromDir( content, err := executeArcheTypeAsTemplate(s, name, archetypeDir, targetFilename, filename) if err != nil { - return err + return errors.Wrap(err, "failed to execute archetype template") } if err := helpers.SafeWriteToDisk(targetFilename, bytes.NewReader(content), targetFs); err != nil { - return err + return errors.Wrap(err, "failed to save results") } } @@ -189,6 +190,7 @@ func mapArcheTypeDir( var m archetypeMap walkFn := func(filename string, fi os.FileInfo, err error) error { + if err != nil { return err } @@ -216,7 +218,7 @@ func mapArcheTypeDir( } if err := helpers.SymbolicWalk(fs, archetypeDir, walkFn); err != nil { - return m, err + return m, errors.Wrapf(err, "failed to walk archetype dir %q", archetypeDir) } return m, nil diff --git a/create/content_test.go b/create/content_test.go index 503c9da8d2d..e321900bcf0 100644 --- a/create/content_test.go +++ b/create/content_test.go @@ -93,6 +93,9 @@ func TestNewContentFromDir(t *testing.T) { archetypeDir := filepath.Join("archetypes", "my-bundle") assert.NoError(fs.Source.Mkdir(archetypeDir, 0755)) + archetypeThemeDir := filepath.Join("themes", "mytheme", "archetypes", "my-theme-bundle") + assert.NoError(fs.Source.Mkdir(archetypeThemeDir, 0755)) + contentFile := ` File: %s Site Lang: {{ .Site.Language.Lang }} @@ -107,6 +110,9 @@ i18n: {{ T "hugo" }} assert.NoError(afero.WriteFile(fs.Source, filepath.Join(archetypeDir, "resources", "hugo1.json"), []byte(`hugo1: {{ printf "no template handling in here" }}`), 0755)) assert.NoError(afero.WriteFile(fs.Source, filepath.Join(archetypeDir, "resources", "hugo2.xml"), []byte(`hugo2: {{ printf "no template handling in here" }}`), 0755)) + assert.NoError(afero.WriteFile(fs.Source, filepath.Join(archetypeThemeDir, "index.md"), []byte(fmt.Sprintf(contentFile, "index.md")), 0755)) + assert.NoError(afero.WriteFile(fs.Source, filepath.Join(archetypeThemeDir, "resources", "hugo1.json"), []byte(`hugo1: {{ printf "no template handling in here" }}`), 0755)) + h, err := hugolib.NewHugoSites(deps.DepsCfg{Cfg: cfg, Fs: fs}) assert.NoError(err) assert.Equal(2, len(h.Sites)) @@ -123,6 +129,10 @@ i18n: {{ T "hugo" }} assertContains(assert, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/pages/bio.md")), `File: bio.md`, `Site Lang: en`, `Name: My Post`) + assert.NoError(create.NewContent(h, "my-theme-bundle", "post/my-theme-post")) + assertContains(assert, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-theme-post/index.md")), `File: index.md`, `Site Lang: en`, `Name: My Theme Post`, `i18n: Hugo Rocks!`) + assertContains(assert, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-theme-post/resources/hugo1.json")), `hugo1: {{ printf "no template handling in here" }}`) + } func initFs(fs *hugofs.Fs) error { @@ -231,6 +241,8 @@ func readFileFromFs(t *testing.T, fs afero.Fs, filename string) string { func newTestCfg(assert *require.Assertions) (*viper.Viper, *hugofs.Fs) { cfg := ` + +theme = "mytheme" [languages] [languages.en] diff --git a/hugolib/filesystems/basefs.go b/hugolib/filesystems/basefs.go index 77a68a8ae29..ee1c870d9fb 100644 --- a/hugolib/filesystems/basefs.go +++ b/hugolib/filesystems/basefs.go @@ -433,6 +433,9 @@ func (b *sourceFilesystemsBuilder) createFs( } if b.hasTheme { + if !strings.HasPrefix(themeFolder, filePathSeparator) { + themeFolder = filePathSeparator + themeFolder + } themeFolderFs := newRealBase(afero.NewBasePathFs(b.themeFs, themeFolder)) if fs == nil { fs = themeFolderFs diff --git a/hugolib/filesystems/basefs_test.go b/hugolib/filesystems/basefs_test.go index 9f4b512fd07..ec6ccb30c41 100644 --- a/hugolib/filesystems/basefs_test.go +++ b/hugolib/filesystems/basefs_test.go @@ -45,15 +45,16 @@ func TestNewBaseFs(t *testing.T) { // Write some data to the themes for _, theme := range themes { - for _, dir := range []string{"i18n", "data"} { + for _, dir := range []string{"i18n", "data", "archetypes", "layouts"} { base := filepath.Join(workingDir, "themes", theme, dir) + filename := filepath.Join(base, fmt.Sprintf("theme-file-%s.txt", theme)) fs.Source.Mkdir(base, 0755) - afero.WriteFile(fs.Source, filepath.Join(base, fmt.Sprintf("theme-file-%s-%s.txt", theme, dir)), []byte(fmt.Sprintf("content:%s:%s", theme, dir)), 0755) + afero.WriteFile(fs.Source, filename, []byte(fmt.Sprintf("content:%s:%s", theme, dir)), 0755) } // Write some files to the root of the theme base := filepath.Join(workingDir, "themes", theme) afero.WriteFile(fs.Source, filepath.Join(base, fmt.Sprintf("theme-root-%s.txt", theme)), []byte(fmt.Sprintf("content:%s", theme)), 0755) - afero.WriteFile(fs.Source, filepath.Join(base, "file-root.txt"), []byte(fmt.Sprintf("content:%s", theme)), 0755) + afero.WriteFile(fs.Source, filepath.Join(base, "file-theme-root.txt"), []byte(fmt.Sprintf("content:%s", theme)), 0755) } afero.WriteFile(fs.Source, filepath.Join(workingDir, "file-root.txt"), []byte("content-project"), 0755) @@ -102,13 +103,13 @@ theme = ["atheme"] checkFileCount(bfs.Content.Fs, "", assert, 3) checkFileCount(bfs.I18n.Fs, "", assert, 6) // 4 + 2 themes - checkFileCount(bfs.Layouts.Fs, "", assert, 5) + checkFileCount(bfs.Layouts.Fs, "", assert, 7) checkFileCount(bfs.Static[""].Fs, "", assert, 6) - checkFileCount(bfs.Data.Fs, "", assert, 9) // 7 + 2 themes - checkFileCount(bfs.Archetypes.Fs, "", assert, 8) + checkFileCount(bfs.Data.Fs, "", assert, 9) // 7 + 2 themes + checkFileCount(bfs.Archetypes.Fs, "", assert, 10) // 8 + 2 themes checkFileCount(bfs.Assets.Fs, "", assert, 9) checkFileCount(bfs.Resources.Fs, "", assert, 10) - checkFileCount(bfs.Work.Fs, "", assert, 69) + checkFileCount(bfs.Work.Fs, "", assert, 78) assert.Equal([]string{filepath.FromSlash("/my/work/mydata"), filepath.FromSlash("/my/work/themes/btheme/data"), filepath.FromSlash("/my/work/themes/atheme/data")}, bfs.Data.Dirnames) @@ -127,6 +128,18 @@ theme = ["atheme"] checkFileContent(bfs.Work.Fs, "file-root.txt", assert, "content-project") checkFileContent(bfs.Work.Fs, "theme-root-atheme.txt", assert, "content:atheme") + // https://github.com/gohugoio/hugo/issues/5318 + // Check both project and theme. + for _, fs := range []afero.Fs{bfs.Archetypes.Fs, bfs.Layouts.Fs} { + for _, filename := range []string{"/file1.txt", "/theme-file-atheme.txt"} { + filename = filepath.FromSlash(filename) + f, err := fs.Open(filename) + assert.NoError(err) + name := f.Name() + f.Close() + assert.Equal(filename, name) + } + } } func createConfig() *viper.Viper { @@ -344,6 +357,7 @@ func setConfigAndWriteSomeFilesTo(fs afero.Fs, v *viper.Viper, key, val string, v.Set(key, val) fs.Mkdir(val, 0755) for i := 0; i < num; i++ { - afero.WriteFile(fs, filepath.Join(workingDir, val, fmt.Sprintf("file%d.txt", i+1)), []byte(fmt.Sprintf("content:%s:%d", key, i+1)), 0755) + filename := filepath.Join(workingDir, val, fmt.Sprintf("file%d.txt", i+1)) + afero.WriteFile(fs, filename, []byte(fmt.Sprintf("content:%s:%d", key, i+1)), 0755) } }