diff options
Diffstat (limited to 'create')
-rw-r--r-- | create/content.go | 80 | ||||
-rw-r--r-- | create/content_template_handler.go | 5 | ||||
-rw-r--r-- | create/content_test.go | 89 |
3 files changed, 113 insertions, 61 deletions
diff --git a/create/content.go b/create/content.go index e48dfc078..0e05adf93 100644 --- a/create/content.go +++ b/create/content.go @@ -25,6 +25,8 @@ import ( "path/filepath" "strings" + "github.com/gohugoio/hugo/hugofs/files" + "github.com/gohugoio/hugo/hugofs" "github.com/gohugoio/hugo/helpers" @@ -50,7 +52,10 @@ func NewContent( if isDir { - langFs := hugofs.NewLanguageFs(s.Language().Lang, sites.LanguageSet(), archetypeFs) + langFs, err := hugofs.NewLanguageFs(sites.LanguageSet(), archetypeFs) + if err != nil { + return err + } cm, err := mapArcheTypeDir(ps, langFs, archetypeFilename) if err != nil { @@ -64,7 +69,7 @@ func NewContent( } name := filepath.Base(targetPath) - return newContentFromDir(archetypeFilename, sites, archetypeFs, sourceFs, cm, name, contentPath) + return newContentFromDir(archetypeFilename, sites, sourceFs, cm, name, contentPath) } // Building the sites can be expensive, so only do it if really needed. @@ -111,9 +116,9 @@ func NewContent( return nil } -func targetSite(sites *hugolib.HugoSites, fi *hugofs.LanguageFileInfo) *hugolib.Site { +func targetSite(sites *hugolib.HugoSites, fi hugofs.FileMetaInfo) *hugolib.Site { for _, s := range sites.Sites { - if fi.Lang() == s.Language().Lang { + if fi.Meta().Lang() == s.Language().Lang { return s } } @@ -123,13 +128,14 @@ func targetSite(sites *hugolib.HugoSites, fi *hugofs.LanguageFileInfo) *hugolib. func newContentFromDir( archetypeDir string, sites *hugolib.HugoSites, - sourceFs, targetFs afero.Fs, + targetFs afero.Fs, cm archetypeMap, name, targetPath string) error { for _, f := range cm.otherFiles { - filename := f.Filename() + meta := f.Meta() + filename := meta.Path() // Just copy the file to destination. - in, err := sourceFs.Open(filename) + in, err := meta.Open() if err != nil { return errors.Wrap(err, "failed to open non-content file") } @@ -156,7 +162,7 @@ func newContentFromDir( } for _, f := range cm.contentFiles { - filename := f.Filename() + filename := f.Meta().Path() s := targetSite(sites, f) targetFilename := filepath.Join(targetPath, strings.TrimPrefix(filename, archetypeDir)) @@ -177,9 +183,9 @@ func newContentFromDir( type archetypeMap struct { // These needs to be parsed and executed as Go templates. - contentFiles []*hugofs.LanguageFileInfo + contentFiles []hugofs.FileMetaInfo // These are just copied to destination. - otherFiles []*hugofs.LanguageFileInfo + otherFiles []hugofs.FileMetaInfo // If the templates needs a fully built site. This can potentially be // expensive, so only do when needed. siteUsed bool @@ -192,7 +198,7 @@ func mapArcheTypeDir( var m archetypeMap - walkFn := func(filename string, fi os.FileInfo, err error) error { + walkFn := func(path string, fi hugofs.FileMetaInfo, err error) error { if err != nil { return err @@ -202,12 +208,12 @@ func mapArcheTypeDir( return nil } - fil := fi.(*hugofs.LanguageFileInfo) + fil := fi.(hugofs.FileMetaInfo) - if hugolib.IsContentFile(filename) { + if files.IsContentFile(path) { m.contentFiles = append(m.contentFiles, fil) if !m.siteUsed { - m.siteUsed, err = usesSiteVar(fs, filename) + m.siteUsed, err = usesSiteVar(fs, path) if err != nil { return err } @@ -220,7 +226,15 @@ func mapArcheTypeDir( return nil } - if err := helpers.SymbolicWalk(fs, archetypeDir, walkFn); err != nil { + walkCfg := hugofs.WalkwayConfig{ + WalkFn: walkFn, + Fs: fs, + Root: archetypeDir, + } + + w := hugofs.NewWalkway(walkCfg) + + if err := w.Walk(); err != nil { return m, errors.Wrapf(err, "failed to walk archetype dir %q", archetypeDir) } @@ -254,17 +268,29 @@ func resolveContentPath(sites *hugolib.HugoSites, fs afero.Fs, targetPath string } } - for _, ss := range sites.Sites { - contentDir := ss.PathSpec.ContentDir + var dirLang string + + for _, dir := range sites.BaseFs.Content.Dirs { + meta := dir.Meta() + contentDir := meta.Filename() + if !strings.HasSuffix(contentDir, helpers.FilePathSeparator) { contentDir += helpers.FilePathSeparator } + if strings.HasPrefix(targetPath, contentDir) { - siteContentDir = ss.PathSpec.ContentDir - if s == nil { + siteContentDir = contentDir + dirLang = meta.Lang() + break + } + } + + if s == nil && dirLang != "" { + for _, ss := range sites.Sites { + if ss.Lang() == dirLang { s = ss + break } - break } } @@ -280,12 +306,22 @@ func resolveContentPath(sites *hugolib.HugoSites, fs afero.Fs, targetPath string } } + if siteContentDir == "" { + + } + if siteContentDir != "" { pp := filepath.Join(siteContentDir, strings.TrimPrefix(targetPath, siteContentDir)) return s.PathSpec.AbsPathify(pp), s - } else { - return s.PathSpec.AbsPathify(filepath.Join(first.PathSpec.ContentDir, targetPath)), s + var contentDir string + for _, dir := range sites.BaseFs.Content.Dirs { + contentDir = dir.Meta().Filename() + if dir.Meta().Lang() == s.Lang() { + break + } + } + return s.PathSpec.AbsPathify(filepath.Join(contentDir, targetPath)), s } } diff --git a/create/content_template_handler.go b/create/content_template_handler.go index 5a8b4f63c..1576fabdb 100644 --- a/create/content_template_handler.go +++ b/create/content_template_handler.go @@ -90,7 +90,10 @@ func executeArcheTypeAsTemplate(s *hugolib.Site, name, kind, targetPath, archety err error ) - f := s.SourceSpec.NewFileInfo("", targetPath, false, nil) + f, err := s.SourceSpec.NewFileInfoFrom(targetPath, targetPath) + if err != nil { + return nil, err + } if name == "" { name = f.TranslationBaseName() diff --git a/create/content_test.go b/create/content_test.go index e321900bc..6a3852d29 100644 --- a/create/content_test.go +++ b/create/content_test.go @@ -35,7 +35,6 @@ import ( ) func TestNewContent(t *testing.T) { - assert := require.New(t) cases := []struct { kind string @@ -50,12 +49,12 @@ func TestNewContent(t *testing.T) { {"product", "product/sample-4.md", []string{`title = "SAMPLE-4"`}}, // empty archetype front matter {"lang", "post/lang-1.md", []string{`Site Lang: en|Name: Lang 1|i18n: Hugo Rocks!`}}, {"lang", "post/lang-2.en.md", []string{`Site Lang: en|Name: Lang 2|i18n: Hugo Rocks!`}}, - {"lang", "post/lang-3.nn.md", []string{`Site Lang: nn|Name: Lang 3|i18n: Hugo Rokkar!`}}, + {"lang", "content/post/lang-3.nn.md", []string{`Site Lang: nn|Name: Lang 3|i18n: Hugo Rokkar!`}}, {"lang", "content_nn/post/lang-4.md", []string{`Site Lang: nn|Name: Lang 4|i18n: Hugo Rokkar!`}}, {"lang", "content_nn/post/lang-5.en.md", []string{`Site Lang: en|Name: Lang 5|i18n: Hugo Rocks!`}}, {"lang", "post/my-bundle/index.md", []string{`Site Lang: en|Name: My Bundle|i18n: Hugo Rocks!`}}, {"lang", "post/my-bundle/index.en.md", []string{`Site Lang: en|Name: My Bundle|i18n: Hugo Rocks!`}}, - {"lang", "post/my-bundle/index.nn.md", []string{`Site Lang: nn|Name: My Bundle|i18n: Hugo Rokkar!`}}, + {"lang", "content/post/my-bundle/index.nn.md", []string{`Site Lang: nn|Name: My Bundle|i18n: Hugo Rokkar!`}}, {"shortcodes", "shortcodes/go.md", []string{ `title = "GO"`, "{{< myshortcode >}}", @@ -64,37 +63,43 @@ func TestNewContent(t *testing.T) { } for i, c := range cases { - cfg, fs := newTestCfg(assert) - assert.NoError(initFs(fs)) - h, err := hugolib.NewHugoSites(deps.DepsCfg{Cfg: cfg, Fs: fs}) - assert.NoError(err) - - assert.NoError(create.NewContent(h, c.kind, c.path)) - - fname := filepath.FromSlash(c.path) - if !strings.HasPrefix(fname, "content") { - fname = filepath.Join("content", fname) - } - content := readFileFromFs(t, fs.Source, fname) - for _, v := range c.expected { - found := strings.Contains(content, v) - if !found { - t.Fatalf("[%d] %q missing from output:\n%q", i, v, content) + c := c + t.Run(fmt.Sprintf("%s-%d", c.kind, i), func(t *testing.T) { + t.Parallel() + assert := require.New(t) + mm := afero.NewMemMapFs() + assert.NoError(initFs(mm)) + cfg, fs := newTestCfg(assert, mm) + h, err := hugolib.NewHugoSites(deps.DepsCfg{Cfg: cfg, Fs: fs}) + assert.NoError(err) + + assert.NoError(create.NewContent(h, c.kind, c.path)) + + fname := filepath.FromSlash(c.path) + if !strings.HasPrefix(fname, "content") { + fname = filepath.Join("content", fname) } - } + content := readFileFromFs(t, fs.Source, fname) + for _, v := range c.expected { + found := strings.Contains(content, v) + if !found { + t.Fatalf("[%d] %q missing from output:\n%q", i, v, content) + } + } + }) + } } func TestNewContentFromDir(t *testing.T) { + mm := afero.NewMemMapFs() assert := require.New(t) - cfg, fs := newTestCfg(assert) - assert.NoError(initFs(fs)) archetypeDir := filepath.Join("archetypes", "my-bundle") - assert.NoError(fs.Source.Mkdir(archetypeDir, 0755)) + assert.NoError(mm.MkdirAll(archetypeDir, 0755)) archetypeThemeDir := filepath.Join("themes", "mytheme", "archetypes", "my-theme-bundle") - assert.NoError(fs.Source.Mkdir(archetypeThemeDir, 0755)) + assert.NoError(mm.MkdirAll(archetypeThemeDir, 0755)) contentFile := ` File: %s @@ -103,15 +108,18 @@ Name: {{ replace .Name "-" " " | title }} i18n: {{ T "hugo" }} ` - assert.NoError(afero.WriteFile(fs.Source, filepath.Join(archetypeDir, "index.md"), []byte(fmt.Sprintf(contentFile, "index.md")), 0755)) - assert.NoError(afero.WriteFile(fs.Source, filepath.Join(archetypeDir, "index.nn.md"), []byte(fmt.Sprintf(contentFile, "index.nn.md")), 0755)) + assert.NoError(afero.WriteFile(mm, filepath.Join(archetypeDir, "index.md"), []byte(fmt.Sprintf(contentFile, "index.md")), 0755)) + assert.NoError(afero.WriteFile(mm, filepath.Join(archetypeDir, "index.nn.md"), []byte(fmt.Sprintf(contentFile, "index.nn.md")), 0755)) - assert.NoError(afero.WriteFile(fs.Source, filepath.Join(archetypeDir, "pages", "bio.md"), []byte(fmt.Sprintf(contentFile, "bio.md")), 0755)) - 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(mm, filepath.Join(archetypeDir, "pages", "bio.md"), []byte(fmt.Sprintf(contentFile, "bio.md")), 0755)) + assert.NoError(afero.WriteFile(mm, filepath.Join(archetypeDir, "resources", "hugo1.json"), []byte(`hugo1: {{ printf "no template handling in here" }}`), 0755)) + assert.NoError(afero.WriteFile(mm, 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)) + assert.NoError(afero.WriteFile(mm, filepath.Join(archetypeThemeDir, "index.md"), []byte(fmt.Sprintf(contentFile, "index.md")), 0755)) + assert.NoError(afero.WriteFile(mm, filepath.Join(archetypeThemeDir, "resources", "hugo1.json"), []byte(`hugo1: {{ printf "no template handling in here" }}`), 0755)) + + assert.NoError(initFs(mm)) + cfg, fs := newTestCfg(assert, mm) h, err := hugolib.NewHugoSites(deps.DepsCfg{Cfg: cfg, Fs: fs}) assert.NoError(err) @@ -135,7 +143,7 @@ i18n: {{ T "hugo" }} } -func initFs(fs *hugofs.Fs) error { +func initFs(fs afero.Fs) error { perm := os.FileMode(0755) var err error @@ -146,8 +154,8 @@ func initFs(fs *hugofs.Fs) error { filepath.Join("themes", "sample", "archetypes"), } for _, dir := range dirs { - err = fs.Source.Mkdir(dir, perm) - if err != nil { + err = fs.Mkdir(dir, perm) + if err != nil && !os.IsExist(err) { return err } } @@ -198,7 +206,7 @@ Some text. `, }, } { - f, err := fs.Source.Create(v.path) + f, err := fs.Create(v.path) if err != nil { return err } @@ -221,6 +229,7 @@ func assertContains(assert *require.Assertions, v interface{}, matches ...string // TODO(bep) extract common testing package with this and some others func readFileFromFs(t *testing.T, fs afero.Fs, filename string) string { + t.Helper() filename = filepath.FromSlash(filename) b, err := afero.ReadFile(fs, filename) if err != nil { @@ -238,12 +247,11 @@ func readFileFromFs(t *testing.T, fs afero.Fs, filename string) string { return string(b) } -func newTestCfg(assert *require.Assertions) (*viper.Viper, *hugofs.Fs) { +func newTestCfg(assert *require.Assertions, mm afero.Fs) (*viper.Viper, *hugofs.Fs) { cfg := ` theme = "mytheme" - [languages] [languages.en] weight = 1 @@ -254,8 +262,13 @@ languageName = "Nynorsk" contentDir = "content_nn" ` + if mm == nil { + mm = afero.NewMemMapFs() + } - mm := afero.NewMemMapFs() + mm.MkdirAll(filepath.FromSlash("content_nn"), 0777) + + mm.MkdirAll(filepath.FromSlash("themes/mytheme"), 0777) assert.NoError(afero.WriteFile(mm, filepath.Join("i18n", "en.toml"), []byte(`[hugo] other = "Hugo Rocks!"`), 0755)) |