mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
parent
e9c7b6205f
commit
93e24a03ce
4 changed files with 95 additions and 14 deletions
42
hugolib/hugo_sites_build_failures_test.go
Normal file
42
hugolib/hugo_sites_build_failures_test.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
package hugolib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// https://github.com/gohugoio/hugo/issues/4526
|
||||
func TestSiteBuildFailureInvalidPageMetadata(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
validContentFile := `
|
||||
---
|
||||
title = "This is good"
|
||||
---
|
||||
|
||||
Some content.
|
||||
`
|
||||
|
||||
invalidContentFile := `
|
||||
---
|
||||
title = "PDF EPUB: Anne Bradstreet: Poems "The Prologue Summary And Analysis EBook Full Text "
|
||||
---
|
||||
|
||||
Some content.
|
||||
`
|
||||
|
||||
var contentFiles []string
|
||||
for i := 0; i <= 30; i++ {
|
||||
name := fmt.Sprintf("valid%d.md", i)
|
||||
contentFiles = append(contentFiles, name, validContentFile)
|
||||
if i%5 == 0 {
|
||||
name = fmt.Sprintf("invalid%d.md", i)
|
||||
contentFiles = append(contentFiles, name, invalidContentFile)
|
||||
}
|
||||
}
|
||||
|
||||
b := newTestSitesBuilder(t)
|
||||
b.WithSimpleConfigFile().WithContent(contentFiles...)
|
||||
b.CreateSites().BuildFail(BuildCfg{})
|
||||
|
||||
}
|
|
@ -32,6 +32,8 @@ type siteContentProcessor struct {
|
|||
|
||||
handleContent contentHandler
|
||||
|
||||
ctx context.Context
|
||||
|
||||
// The input file bundles.
|
||||
fileBundlesChan chan *bundleDir
|
||||
|
||||
|
@ -51,7 +53,28 @@ type siteContentProcessor struct {
|
|||
partialBuild bool
|
||||
}
|
||||
|
||||
func newSiteContentProcessor(baseDir string, partialBuild bool, s *Site) *siteContentProcessor {
|
||||
func (s *siteContentProcessor) processBundle(b *bundleDir) {
|
||||
select {
|
||||
case s.fileBundlesChan <- b:
|
||||
case <-s.ctx.Done():
|
||||
}
|
||||
}
|
||||
|
||||
func (s *siteContentProcessor) processSingle(fi *fileInfo) {
|
||||
select {
|
||||
case s.fileSinglesChan <- fi:
|
||||
case <-s.ctx.Done():
|
||||
}
|
||||
}
|
||||
|
||||
func (s *siteContentProcessor) processAssets(assets []string) {
|
||||
select {
|
||||
case s.fileAssetsChan <- assets:
|
||||
case <-s.ctx.Done():
|
||||
}
|
||||
}
|
||||
|
||||
func newSiteContentProcessor(ctx context.Context, baseDir string, partialBuild bool, s *Site) *siteContentProcessor {
|
||||
numWorkers := 12
|
||||
if n := runtime.NumCPU() * 3; n > numWorkers {
|
||||
numWorkers = n
|
||||
|
@ -60,6 +83,7 @@ func newSiteContentProcessor(baseDir string, partialBuild bool, s *Site) *siteCo
|
|||
numWorkers = int(math.Ceil(float64(numWorkers) / float64(len(s.owner.Sites))))
|
||||
|
||||
return &siteContentProcessor{
|
||||
ctx: ctx,
|
||||
partialBuild: partialBuild,
|
||||
baseDir: baseDir,
|
||||
site: s,
|
||||
|
@ -80,7 +104,7 @@ func (s *siteContentProcessor) closeInput() {
|
|||
|
||||
func (s *siteContentProcessor) process(ctx context.Context) error {
|
||||
g1, ctx := errgroup.WithContext(ctx)
|
||||
g2, _ := errgroup.WithContext(ctx)
|
||||
g2, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
// There can be only one of these per site.
|
||||
g1.Go(func() error {
|
||||
|
@ -161,12 +185,14 @@ func (s *siteContentProcessor) process(ctx context.Context) error {
|
|||
})
|
||||
}
|
||||
|
||||
if err := g2.Wait(); err != nil {
|
||||
return err
|
||||
}
|
||||
err := g2.Wait()
|
||||
|
||||
close(s.pagesChan)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := g1.Wait(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1281,19 +1281,19 @@ func (c *contentCaptureResultHandler) getContentProcessor(lang string) *siteCont
|
|||
func (c *contentCaptureResultHandler) handleSingles(fis ...*fileInfo) {
|
||||
for _, fi := range fis {
|
||||
proc := c.getContentProcessor(fi.Lang())
|
||||
proc.fileSinglesChan <- fi
|
||||
proc.processSingle(fi)
|
||||
}
|
||||
}
|
||||
func (c *contentCaptureResultHandler) handleBundles(d *bundleDirs) {
|
||||
for _, b := range d.bundles {
|
||||
proc := c.getContentProcessor(b.fi.Lang())
|
||||
proc.fileBundlesChan <- b
|
||||
proc.processBundle(b)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *contentCaptureResultHandler) handleCopyFiles(filenames ...string) {
|
||||
for _, proc := range c.contentProcessors {
|
||||
proc.fileAssetsChan <- filenames
|
||||
proc.processAssets(filenames)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1309,7 +1309,7 @@ func (s *Site) readAndProcessContent(filenames ...string) error {
|
|||
var defaultContentProcessor *siteContentProcessor
|
||||
sites := s.owner.langSite()
|
||||
for k, v := range sites {
|
||||
proc := newSiteContentProcessor(baseDir, len(filenames) > 0, v)
|
||||
proc := newSiteContentProcessor(ctx, baseDir, len(filenames) > 0, v)
|
||||
contentProcessors[k] = proc
|
||||
if k == defaultContentLanguage {
|
||||
defaultContentProcessor = proc
|
||||
|
@ -1337,15 +1337,18 @@ func (s *Site) readAndProcessContent(filenames ...string) error {
|
|||
|
||||
c := newCapturer(s.Log, sourceSpec, handler, bundleMap, baseDir, filenames...)
|
||||
|
||||
if err := c.capture(); err != nil {
|
||||
return err
|
||||
}
|
||||
err1 := c.capture()
|
||||
|
||||
for _, proc := range contentProcessors {
|
||||
proc.closeInput()
|
||||
}
|
||||
|
||||
return g.Wait()
|
||||
err2 := g.Wait()
|
||||
|
||||
if err1 != nil {
|
||||
return err1
|
||||
}
|
||||
return err2
|
||||
}
|
||||
|
||||
func (s *Site) buildSiteMeta() (err error) {
|
||||
|
|
|
@ -272,12 +272,22 @@ func (s *sitesBuilder) CreateSites() *sitesBuilder {
|
|||
}
|
||||
|
||||
func (s *sitesBuilder) Build(cfg BuildCfg) *sitesBuilder {
|
||||
return s.build(cfg, false)
|
||||
}
|
||||
|
||||
func (s *sitesBuilder) BuildFail(cfg BuildCfg) *sitesBuilder {
|
||||
return s.build(cfg, true)
|
||||
}
|
||||
|
||||
func (s *sitesBuilder) build(cfg BuildCfg, shouldFail bool) *sitesBuilder {
|
||||
if s.H == nil {
|
||||
s.CreateSites()
|
||||
}
|
||||
err := s.H.Build(cfg)
|
||||
if err != nil {
|
||||
if err != nil && !shouldFail {
|
||||
s.Fatalf("Build failed: %s", err)
|
||||
} else if err == nil && shouldFail {
|
||||
s.Fatalf("Expected error")
|
||||
}
|
||||
|
||||
return s
|
||||
|
|
Loading…
Reference in a new issue