summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--commands/hugo.go2
-rw-r--r--commands/new.go12
-rw-r--r--commands/new_site.go2
-rw-r--r--create/content.go392
-rw-r--r--create/content_template_handler.go149
-rw-r--r--create/content_test.go205
-rw-r--r--deps/deps.go2
-rw-r--r--hugofs/glob/glob.go168
-rw-r--r--hugofs/glob/glob_test.go35
-rw-r--r--hugolib/content_factory.go181
-rw-r--r--hugolib/content_factory_test.go60
-rw-r--r--hugolib/filesystems/basefs.go36
-rw-r--r--hugolib/hugo_sites.go7
-rw-r--r--hugolib/pages_capture_test.go2
-rw-r--r--hugolib/site.go8
-rw-r--r--langs/i18n/translationProvider.go2
-rw-r--r--source/content_directory_test.go2
-rw-r--r--source/filesystem_test.go2
-rw-r--r--source/sourceSpec.go36
19 files changed, 857 insertions, 446 deletions
diff --git a/commands/hugo.go b/commands/hugo.go
index 4fd20a0f4..c19756008 100644
--- a/commands/hugo.go
+++ b/commands/hugo.go
@@ -870,7 +870,7 @@ func (c *commandeer) newWatcher(pollIntervalStr string, dirList ...string) (*wat
livereload.ForceRefresh()
}
case err := <-watcher.Errors():
- if err != nil {
+ if err != nil && !os.IsNotExist(err) {
c.logger.Errorln("Error while watching:", err)
}
}
diff --git a/commands/new.go b/commands/new.go
index 7affd3547..c5b5cd182 100644
--- a/commands/new.go
+++ b/commands/new.go
@@ -80,17 +80,7 @@ func (n *newCmd) newContent(cmd *cobra.Command, args []string) error {
return newUserError("path needs to be provided")
}
- createPath := args[0]
-
- var kind string
-
- createPath, kind = newContentPathSection(c.hugo(), createPath)
-
- if n.contentType != "" {
- kind = n.contentType
- }
-
- return create.NewContent(c.hugo(), kind, createPath)
+ return create.NewContent(c.hugo(), n.contentType, args[0])
}
func mkdir(x ...string) {
diff --git a/commands/new_site.go b/commands/new_site.go
index 71097b8ff..11e9ce40a 100644
--- a/commands/new_site.go
+++ b/commands/new_site.go
@@ -102,7 +102,7 @@ func (n *newSiteCmd) doNewSite(fs *hugofs.Fs, basepath string, force bool) error
// Create a default archetype file.
helpers.SafeWriteToDisk(filepath.Join(archeTypePath, "default.md"),
- strings.NewReader(create.ArchetypeTemplateTemplate), fs.Source)
+ strings.NewReader(create.DefaultArchetypeTemplateTemplate), fs.Source)
jww.FEEDBACK.Printf("Congratulations! Your new Hugo site is created in %s.\n\n", basepath)
jww.FEEDBACK.Println(nextStepsText())
diff --git a/create/content.go b/create/content.go
index ea065423e..714939f4c 100644
--- a/create/content.go
+++ b/create/content.go
@@ -16,11 +16,14 @@ package create
import (
"bytes"
+ "fmt"
"io"
"os"
"path/filepath"
"strings"
+ "github.com/gohugoio/hugo/hugofs/glob"
+
"github.com/gohugoio/hugo/common/paths"
"github.com/pkg/errors"
@@ -33,125 +36,136 @@ import (
"github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/hugolib"
"github.com/spf13/afero"
- jww "github.com/spf13/jwalterweatherman"
)
-// NewContent creates a new content file in the content directory based upon the
-// given kind, which is used to lookup an archetype.
-func NewContent(
- sites *hugolib.HugoSites, kind, targetPath string) error {
- targetPath = filepath.Clean(targetPath)
- ext := paths.Ext(targetPath)
- ps := sites.PathSpec
- archetypeFs := ps.BaseFs.SourceFilesystems.Archetypes.Fs
- sourceFs := ps.Fs.Source
-
- jww.INFO.Printf("attempting to create %q of %q of ext %q", targetPath, kind, ext)
+const (
+ // DefaultArchetypeTemplateTemplate is the template used in 'hugo new site'
+ // and the template we use as a fall back.
+ DefaultArchetypeTemplateTemplate = `---
+title: "{{ replace .Name "-" " " | title }}"
+date: {{ .Date }}
+draft: true
+---
- archetypeFilename, isDir := findArchetype(ps, kind, ext)
- contentPath, s := resolveContentPath(sites, sourceFs, targetPath)
+`
+)
- if isDir {
+// NewContent creates a new content file in h (or a full bundle if the archetype is a directory)
+// in targetPath.
+func NewContent(h *hugolib.HugoSites, kind, targetPath string) error {
+ cf := hugolib.NewContentFactory(h)
- langFs, err := hugofs.NewLanguageFs(sites.LanguageSet(), archetypeFs)
- if err != nil {
- return err
- }
-
- cm, err := mapArcheTypeDir(ps, langFs, archetypeFilename)
- if err != nil {
- return err
- }
+ if kind == "" {
+ kind = cf.SectionFromFilename(targetPath)
+ }
- if cm.siteUsed {
- if err := sites.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
- return err
- }
- }
+ b := &contentBuilder{
+ archeTypeFs: h.PathSpec.BaseFs.Archetypes.Fs,
+ sourceFs: h.PathSpec.Fs.Source,
+ ps: h.PathSpec,
+ h: h,
+ cf: cf,
- name := filepath.Base(targetPath)
- return newContentFromDir(archetypeFilename, sites, sourceFs, cm, name, contentPath)
+ kind: kind,
+ targetPath: targetPath,
}
- // Building the sites can be expensive, so only do it if really needed.
- siteUsed := false
+ ext := paths.Ext(targetPath)
- if archetypeFilename != "" {
+ b.setArcheTypeFilenameToUse(ext)
- var err error
- siteUsed, err = usesSiteVar(archetypeFs, archetypeFilename)
- if err != nil {
- return err
- }
+ if b.isDir {
+ return b.buildDir()
}
- if siteUsed {
- if err := sites.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
- return err
- }
+ if ext == "" {
+ return errors.Errorf("failed to resolve %q to a archetype template", targetPath)
}
- content, err := executeArcheTypeAsTemplate(s, "", kind, targetPath, archetypeFilename)
- if err != nil {
- return err
- }
+ return b.buildFile()
+
+}
+
+type contentBuilder struct {
+ archeTypeFs afero.Fs
+ sourceFs afero.Fs
+
+ ps *helpers.PathSpec
+ h *hugolib.HugoSites
+ cf hugolib.ContentFactory
- if err := helpers.SafeWriteToDisk(contentPath, bytes.NewReader(content), s.Fs.Source); err != nil {
+ // Builder state
+ archetypeFilename string
+ targetPath string
+ kind string
+ isDir bool
+ dirMap archetypeMap
+}
+
+func (b *contentBuilder) buildDir() error {
+ // Split the dir into content files and the rest.
+ if err := b.mapArcheTypeDir(); err != nil {
return err
}
- jww.FEEDBACK.Println(contentPath, "created")
+ var contentTargetFilenames []string
+ var baseDir string
- editor := s.Cfg.GetString("newContentEditor")
- if editor != "" {
- jww.FEEDBACK.Printf("Editing %s with %q ...\n", targetPath, editor)
-
- editorCmd := append(strings.Fields(editor), contentPath)
- cmd, err := hexec.SafeCommand(editorCmd[0], editorCmd[1:]...)
+ for _, fi := range b.dirMap.contentFiles {
+ targetFilename := filepath.Join(b.targetPath, strings.TrimPrefix(fi.Meta().Path, b.archetypeFilename))
+ abs, err := b.cf.CreateContentPlaceHolder(targetFilename)
if err != nil {
return err
}
- cmd.Stdin = os.Stdin
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
+ if baseDir == "" {
+ baseDir = strings.TrimSuffix(abs, targetFilename)
+ }
- return cmd.Run()
+ contentTargetFilenames = append(contentTargetFilenames, abs)
}
- return nil
-}
+ var contentInclusionFilter *glob.FilenameFilter
+ if !b.dirMap.siteUsed {
+ // We don't need to build everything.
+ contentInclusionFilter = glob.NewFilenameFilterForInclusionFunc(func(filename string) bool {
+ for _, cn := range contentTargetFilenames {
+ if strings.HasPrefix(cn, filename) {
+ return true
+ }
+ }
+ return false
+ })
-func targetSite(sites *hugolib.HugoSites, fi hugofs.FileMetaInfo) *hugolib.Site {
- for _, s := range sites.Sites {
- if fi.Meta().Lang == s.Language().Lang {
- return s
+ }
+
+ if err := b.h.Build(hugolib.BuildCfg{SkipRender: true, ContentInclusionFilter: contentInclusionFilter}); err != nil {
+ return err
+ }
+
+ for i, filename := range contentTargetFilenames {
+ if err := b.applyArcheType(filename, b.dirMap.contentFiles[i].Meta().Path); err != nil {
+ return err
}
}
- return sites.Sites[0]
-}
-func newContentFromDir(
- archetypeDir string,
- sites *hugolib.HugoSites,
- targetFs afero.Fs,
- cm archetypeMap, name, targetPath string) error {
- for _, f := range cm.otherFiles {
+ // Copy the rest as is.
+ for _, f := range b.dirMap.otherFiles {
meta := f.Meta()
filename := meta.Path
- // Just copy the file to destination.
+
in, err := meta.Open()
if err != nil {
return errors.Wrap(err, "failed to open non-content file")
}
- targetFilename := filepath.Join(targetPath, strings.TrimPrefix(filename, archetypeDir))
-
+ targetFilename := filepath.Join(baseDir, b.targetPath, strings.TrimPrefix(filename, b.archetypeFilename))
targetDir := filepath.Dir(targetFilename)
- if err := targetFs.MkdirAll(targetDir, 0777); err != nil && !os.IsExist(err) {
- return errors.Wrapf(err, "failed to create target directory for %s:", targetDir)
+
+ if err := b.sourceFs.MkdirAll(targetDir, 0o777); err != nil && !os.IsExist(err) {
+ return errors.Wrapf(err, "failed to create target directory for %q", targetDir)
}
- out, err := targetFs.Create(targetFilename)
+ out, err := b.sourceFs.Create(targetFilename)
if err != nil {
return err
}
@@ -164,41 +178,81 @@ func newContentFromDir(
in.Close()
out.Close()
}
+ return nil
+}
- for _, f := range cm.contentFiles {
- filename := f.Meta().Path
- s := targetSite(sites, f)
- targetFilename := filepath.Join(targetPath, strings.TrimPrefix(filename, archetypeDir))
+func (b *contentBuilder) buildFile() error {
+ contentPlaceholderAbsFilename, err := b.cf.CreateContentPlaceHolder(b.targetPath)
+ if err != nil {
+ return err
+ }
- content, err := executeArcheTypeAsTemplate(s, name, archetypeDir, targetFilename, filename)
- if err != nil {
- return errors.Wrap(err, "failed to execute archetype template")
- }
+ usesSite, err := b.usesSiteVar(b.archetypeFilename)
+ if err != nil {
+ return err
+ }
- if err := helpers.SafeWriteToDisk(targetFilename, bytes.NewReader(content), targetFs); err != nil {
- return errors.Wrap(err, "failed to save results")
- }
+ var contentInclusionFilter *glob.FilenameFilter
+ if !usesSite {
+ // We don't need to build everything.
+ contentInclusionFilter = glob.NewFilenameFilterForInclusionFunc(func(filename string) bool {
+ return strings.HasPrefix(contentPlaceholderAbsFilename, filename)
+ })
}
- jww.FEEDBACK.Println(targetPath, "created")
+ if err := b.h.Build(hugolib.BuildCfg{SkipRender: true, ContentInclusionFilter: contentInclusionFilter}); err != nil {
+ return err
+ }
- return nil
+ if err := b.applyArcheType(contentPlaceholderAbsFilename, b.archetypeFilename); err != nil {
+ return err
+ }
+
+ b.h.Log.Infof("Content %q created", contentPlaceholderAbsFilename)
+
+ return b.openInEditorIfConfigured(contentPlaceholderAbsFilename)
}
-type archetypeMap struct {
- // These needs to be parsed and executed as Go templates.
- contentFiles []hugofs.FileMetaInfo
- // These are just copied to destination.
- otherFiles []hugofs.FileMetaInfo
- // If the templates needs a fully built site. This can potentially be
- // expensive, so only do when needed.
- siteUsed bool
+func (b *contentBuilder) setArcheTypeFilenameToUse(ext string) {
+ var pathsToCheck []string
+
+ if b.kind != "" {
+ pathsToCheck = append(pathsToCheck, b.kind+ext)
+ }
+ pathsToCheck = append(pathsToCheck, "default"+ext, "default")
+
+ for _, p := range pathsToCheck {
+ fi, err := b.archeTypeFs.Stat(p)
+ if err == nil {
+ b.archetypeFilename = p
+ b.isDir = fi.IsDir()
+ return
+ }
+ }
+
}
-func mapArcheTypeDir(
- ps *helpers.PathSpec,
- fs afero.Fs,
- archetypeDir string) (archetypeMap, error) {
+func (b *contentBuilder) applyArcheType(contentFilename, archetypeFilename string) error {
+ p := b.h.GetContentPage(contentFilename)
+ if p == nil {
+ panic(fmt.Sprintf("[BUG] no Page found for %q", contentFilename))
+ }
+
+ f, err := b.sourceFs.Create(contentFilename)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ if archetypeFilename == "" {
+ return b.cf.AppplyArchetypeTemplate(f, p, b.kind, DefaultArchetypeTemplateTemplate)
+ }
+
+ return b.cf.AppplyArchetypeFilename(f, p, b.kind, archetypeFilename)
+
+}
+
+func (b *contentBuilder) mapArcheTypeDir() error {
var m archetypeMap
walkFn := func(path string, fi hugofs.FileMetaInfo, err error) error {
@@ -215,7 +269,7 @@ func mapArcheTypeDir(
if files.IsContentFile(path) {
m.contentFiles = append(m.contentFiles, fil)
if !m.siteUsed {
- m.siteUsed, err = usesSiteVar(fs, path)
+ m.siteUsed, err = b.usesSiteVar(path)
if err != nil {
return err
}
@@ -230,120 +284,60 @@ func mapArcheTypeDir(
walkCfg := hugofs.WalkwayConfig{
WalkFn: walkFn,
- Fs: fs,
- Root: archetypeDir,
+ Fs: b.archeTypeFs,
+ Root: b.archetypeFilename,
}
w := hugofs.NewWalkway(walkCfg)
if err := w.Walk(); err != nil {
- return m, errors.Wrapf(err, "failed to walk archetype dir %q", archetypeDir)
+ return errors.Wrapf(err, "failed to walk archetype dir %q", b.archetypeFilename)
}
- return m, nil
-}
+ b.dirMap = m
-func usesSiteVar(fs afero.Fs, filename string) (bool, error) {
- f, err := fs.Open(filename)
- if err != nil {
- return false, errors.Wrap(err, "failed to open archetype file")
- }
- defer f.Close()
- return helpers.ReaderContains(f, []byte(".Site")), nil
+ return nil
}
-// Resolve the target content path.
-func resolveContentPath(sites *hugolib.HugoSites, fs afero.Fs, targetPath string) (string, *hugolib.Site) {
- targetDir := filepath.Dir(targetPath)
- first := sites.Sites[0]
-
- var (
- s *hugolib.Site
- siteContentDir string
- )
-
- // Try the filename: my-post.en.md
- for _, ss := range sites.Sites {
- if strings.Contains(targetPath, "."+ss.Language().Lang+".") {
- s = ss
- break
- }
- }
-
- 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 = contentDir
- dirLang = meta.Lang
- break
- }
+func (b *contentBuilder) openInEditorIfConfigured(filename string) error {
+ editor := b.h.Cfg.GetString("newContentEditor")
+ if editor == "" {
+ return nil
}
- if s == nil && dirLang != "" {
- for _, ss := range sites.Sites {
- if ss.Lang() == dirLang {
- s = ss
- break
- }
- }
- }
+ b.h.Log.Infof("Editing %q with %q ...\n", filename, editor)
- if s == nil {
- s = first
+ cmd, err := hexec.SafeCommand(editor, filename)
+ if err != nil {
+ return err
}
- if targetDir != "" && targetDir != "." {
- exists, _ := helpers.Exists(targetDir, fs)
+ cmd.Stdin = os.Stdin
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
- if exists {
- return targetPath, s
- }
- }
+ return cmd.Run()
+}
- if siteContentDir == "" {
+func (b *contentBuilder) usesSiteVar(filename string) (bool, error) {
+ if filename == "" {
+ return false, nil
}
-
- if siteContentDir != "" {
- pp := filepath.Join(siteContentDir, strings.TrimPrefix(targetPath, siteContentDir))
- return s.PathSpec.AbsPathify(pp), s
- } else {
- 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
+ bb, err := afero.ReadFile(b.archeTypeFs, filename)
+ if err != nil {
+ return false, errors.Wrap(err, "failed to open archetype file")
}
-}
-// FindArchetype takes a given kind/archetype of content and returns the path
-// to the archetype in the archetype filesystem, blank if none found.
-func findArchetype(ps *helpers.PathSpec, kind, ext string) (outpath string, isDir bool) {
- fs := ps.BaseFs.Archetypes.Fs
+ return bytes.Contains(bb, []byte(".Site")) || bytes.Contains(bb, []byte("site.")), nil
- var pathsToCheck []string
-
- if kind != "" {
- pathsToCheck = append(pathsToCheck, kind+ext)
- }
- pathsToCheck = append(pathsToCheck, "default"+ext, "default")
-
- for _, p := range pathsToCheck {
- fi, err := fs.Stat(p)
- if err == nil {
- return p, fi.IsDir()
- }
- }
+}
- return "", false
+type archetypeMap struct {
+ // These needs to be parsed and executed as Go templates.
+ contentFiles []hugofs.FileMetaInfo
+ // These are just copied to destination.
+ otherFiles []hugofs.FileMetaInfo
+ // If the templates needs a fully built site. This can potentially be
+ // expensive, so only do when needed.
+ siteUsed bool
}
diff --git a/create/content_template_handler.go b/create/content_template_handler.go
deleted file mode 100644
index 09cf4c0a5..000000000
--- a/create/content_template_handler.go
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2017 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.
-// You may obtain a copy of the License at
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package create
-
-import (
- "bytes"
- "fmt"
- "path/filepath"
- "strings"
- "time"
-
- "github.com/gohugoio/hugo/common/paths"
-
- "github.com/pkg/errors"
-
- "github.com/gohugoio/hugo/helpers"
- "github.com/gohugoio/hugo/source"
-
- "github.com/gohugoio/hugo/hugolib"
- "github.com/gohugoio/hugo/tpl"
- "github.com/spf13/afero"
-)
-
-// ArchetypeFileData represents the data available to an archetype template.
-type ArchetypeFileData struct {
- // The archetype content type, either given as --kind option or extracted
- // from the target path's section, i.e. "blog/mypost.md" will resolve to
- // "blog".
- Type string
-
- // The current date and time as a RFC3339 formatted string, suitable for use in front matter.
- Date string
-
- // The Site, fully equipped with all the pages etc. Note: This will only be set if it is actually
- // used in the archetype template. Also, if this is a multilingual setup,
- // this site is the site that best matches the target content file, based
- // on the presence of language code in the filename.
- Site *hugolib.SiteInfo
-
- // Name will in most cases be the same as TranslationBaseName, e.g. "my-post".
- // But if that value is "index" (bundles), the Name is instead the owning folder.
- // This is the value you in most cases would want to use to construct the title in your
- // archetype template.
- Name string
-
- // The target content file. Note that the .Content will be empty, as that
- // has not been created yet.
- source.File
-}
-
-const (
- // ArchetypeTemplateTemplate is used as initial template when adding an archetype template.
- ArchetypeTemplateTemplate = `---
-title: "{{ replace .Name "-" " " | title }}"
-date: {{ .Date }}
-draft: true
----
-
-`
-)
-
-var (
- archetypeShortcodeReplacementsPre = strings.NewReplacer(
- "{{<", "{x{<",
- "{{%", "{x{%",
- ">}}", ">}x}",
- "%}}", "%}x}")
-
- archetypeShortcodeReplacementsPost = strings.NewReplacer(
- "{x{<", "{{<",
- "{x{%", "{{%",
- ">}x}", ">}}",
- "%}x}", "%}}")
-)
-
-func executeArcheTypeAsTemplate(s *hugolib.Site, name, kind, targetPath, archetypeFilename string) ([]byte, error) {
- var (
- archetypeContent []byte
- archetypeTemplate []byte
- err error
- )
-
- f, err := s.SourceSpec.NewFileInfoFrom(targetPath, targetPath)
- if err != nil {
- return nil, err
- }
-
- if name == "" {
- name = f.TranslationBaseName()
-
- if name == "index" || name == "_index" {
- // Page bundles; the directory name will hopefully have a better name.
- dir := strings.TrimSuffix(f.Dir(), helpers.FilePathSeparator)
- _, name = filepath.Split(dir)
- }
- }
-
- data := ArchetypeFileData{
- Type: kind,
- Date: time.Now().Format(time.RFC3339),
- Name: name,
- File: f,
- Site: s.Info,
- }
-
- if archetypeFilename == "" {
- // TODO(bep) archetype revive the issue about wrong tpl funcs arg order
- archetypeTemplate = []byte(ArchetypeTemplateTemplate)
- } else {
- archetypeTemplate, err = afero.ReadFile(s.BaseFs.Archetypes.Fs, archetypeFilename)
- if err != nil {
- return nil, fmt.Errorf("failed to read archetype file %s", err)
- }
-
- }
-
- // The archetype template may contain shortcodes, and these does not play well
- // with the Go templates. Need to set some temporary delimiters.
- archetypeTemplate = []byte(archetypeShortcodeReplacementsPre.Replace(string(archetypeTemplate)))
-
- // Reuse the Hugo template setup to get the template funcs properly set up.
- templateHandler := s.Deps.Tmpl().(tpl.TemplateManager)
- templateName := paths.Filename(archetypeFilename)
- if err := templateHandler.AddTemplate("_text/"+templateName, string(archetypeTemplate)); err != nil {
- return nil, errors.Wrapf(err, "Failed to parse archetype file %q:", archetypeFilename)
- }
-
- templ, _ := templateHandler.Lookup(templateName)
-
- var buff bytes.Buffer
- if err := templateHandler.Execute(templ, &buff, data); err != nil {
- return nil, errors.Wrapf(err, "Failed to process archetype file %q:", archetypeFilename)
- }
-
- archetypeContent = []byte(archetypeShortcodeReplacementsPost.Replace(buff.String()))
-
- return archetypeContent, nil
-}
diff --git a/create/content_test.go b/create/content_test.go
index 38ff7de8d..d40634083 100644
--- a/create/content_test.go
+++ b/create/content_test.go
@@ -34,27 +34,31 @@ import (
"github.com/spf13/afero"
)
+// TODO(bep) clean this up. Export the test site builder in Hugolib or something.
func TestNewContent(t *testing.T) {
cases := []struct {
+ name string
kind string
path string
expected []string
}{
- {"post", "post/sample-1.md", []string{`title = "Post Arch title"`, `test = "test1"`, "date = \"2015-01-12T19:20:04-07:00\""}},
- {"post", "post/org-1.org", []string{`#+title: ORG-1`}},
- {"emptydate", "post/sample-ed.md", []string{`title = "Empty Date Arch title"`, `test = "test1"`}},
- {"stump", "stump/sample-2.md", []string{`title: "Sample 2"`}}, // no archetype file
- {"", "sample-3.md", []string{`title: "Sample 3"`}}, // no archetype
- {"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", "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", "content/post/my-bundle/index.nn.md", []string{`Site Lang: nn|Name: My Bundle|i18n: Hugo Rokkar!`}},
- {"shortcodes", "shortcodes/go.md", []string{
+ {"Post", "post", "post/sample-1.md", []string{`title = "Post Arch title"`, `test = "test1"`, "date = \"2015-01-12T19:20:04-07:00\""}},
+ {"Post org-mode", "post", "post/org-1.org", []string{`#+title: ORG-1`}},
+ {"Empty date", "emptydate", "post/sample-ed.md", []string{`title = "Empty Date Arch title"`, `test = "test1"`}},
+ {"Archetype file not found", "stump", "stump/sample-2.md", []string{`title: "Sample 2"`}}, // no archetype file
+ {"No archetype", "", "sample-3.md", []string{`title: "Sample 3"`}}, // no archetype
+ {"Empty archetype", "product", "product/sample-4.md", []string{`title = "SAMPLE-4"`}}, // empty archetype front matter
+ {"Filenames", "filenames", "content/mypage/index.md", []string{"title = \"INDEX\"\n+++\n\n\nContentBaseName: mypage"}},
+ {"Lang 1", "lang", "post/lang-1.md", []string{`Site Lang: en|Name: Lang 1|i18n: Hugo Rocks!`}},
+ {"Lang 2", "lang", "post/lang-2.en.md", []string{`Site Lang: en|Name: Lang 2|i18n: Hugo Rocks!`}},
+ {"Lang nn file", "lang", "content/post/lang-3.nn.md", []string{`Site Lang: nn|Name: Lang 3|i18n: Hugo Rokkar!`}},
+ {"Lang nn dir", "lang", "content_nn/post/lang-4.md", []string{`Site Lang: nn|Name: Lang 4|i18n: Hugo Rokkar!`}},
+ {"Lang en in nn dir", "lang", "content_nn/post/lang-5.en.md", []string{`Site Lang: en|Name: Lang 5|i18n: Hugo Rocks!`}},
+ {"Lang en default", "lang", "post/my-bundle/index.md", []string{`Site Lang: en|Name: My Bundle|i18n: Hugo Rocks!`}},
+ {"Lang en file", "lang", "post/my-bundle/index.en.md", []string{`Site Lang: en|Name: My Bundle|i18n: Hugo Rocks!`}},
+ {"Lang nn bundle", "lang", "content/post/my-bundle/index.nn.md", []string{`Site Lang: nn|Name: My Bundle|i18n: Hugo Rokkar!`}},
+ {"Site", "site", "content/mypage/index.md", []string{"RegularPages .Site: 10", "RegularPages site: 10"}},
+ {"Shortcodes", "shortcodes", "shortcodes/go.md", []string{
`title = "GO"`,
"{{< myshortcode >}}",
"{{% myshortcode %}}",
@@ -62,11 +66,14 @@ func TestNewContent(t *testing.T) {
}}, // shortcodes
}
+ c := qt.New(t)
+
for i, cas := range cases {
cas := cas
- t.Run(fmt.Sprintf("%s-%d", cas.kind, i), func(t *testing.T) {
- t.Parallel()
- c := qt.New(t)
+
+ c.Run(cas.name, func(c *qt.C) {
+ c.Parallel()
+
mm := afero.NewMemMapFs()
c.Assert(initFs(mm), qt.IsNil)
cfg, fs := newTestCfg(c, mm)
@@ -79,11 +86,11 @@ func TestNewContent(t *testing.T) {
if !strings.HasPrefix(fname, "content") {
fname = filepath.Join("content", fname)
}
- content := readFileFromFs(t, fs.Source, fname)
+ content := readFileFromFs(c, fs.Source, fname)
for _, v := range cas.expected {
found :=