shithub: hugo

Download patch

ref: 78578632f545283741a01f024a6ccedc0b695a30
parent: 6b78b3810a800e315b57e2d907db9040cda36ac0
author: Bjørn Erik Pedersen <[email protected]>
date: Fri Oct 26 05:41:24 EDT 2018

Fix archetype handling of directories in theme

Fixes #5318

--- a/create/content.go
+++ b/create/content.go
@@ -71,6 +71,7 @@
 	siteUsed := false
 
 	if archetypeFilename != "" {
+
 		var err error
 		siteUsed, err = usesSiteVar(archetypeFs, archetypeFilename)
 		if err != nil {
@@ -130,7 +131,7 @@
 		// 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 @@
 
 		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 @@
 	var m archetypeMap
 
 	walkFn := func(filename string, fi os.FileInfo, err error) error {
+
 		if err != nil {
 			return err
 		}
@@ -216,7 +218,7 @@
 	}
 
 	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
--- a/create/content_test.go
+++ b/create/content_test.go
@@ -93,6 +93,9 @@
 	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 @@
 	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 @@
 
 	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 newTestCfg(assert *require.Assertions) (*viper.Viper, *hugofs.Fs) {
 
 	cfg := `
+
+theme = "mytheme"
 	
 [languages]
 [languages.en]
--- a/hugolib/filesystems/basefs.go
+++ b/hugolib/filesystems/basefs.go
@@ -433,6 +433,9 @@
 	}
 
 	if b.hasTheme {
+		if !strings.HasPrefix(themeFolder, filePathSeparator) {
+			themeFolder = filePathSeparator + themeFolder
+		}
 		themeFolderFs := newRealBase(afero.NewBasePathFs(b.themeFs, themeFolder))
 		if fs == nil {
 			fs = themeFolderFs
--- a/hugolib/filesystems/basefs_test.go
+++ b/hugolib/filesystems/basefs_test.go
@@ -45,15 +45,16 @@
 
 	// 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 @@
 
 	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 @@
 	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 @@
 	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)
 	}
 }