Add js.Batch

Fixes #12626
Closes #7499
Closes #9978
Closes #12879
Closes #13113
Fixes #13116
This commit is contained in:
Bjørn Erik Pedersen
2024-12-10 16:22:08 +01:00
parent 157d86414d
commit e293e7ca6d
61 changed files with 4520 additions and 1003 deletions

View File

@@ -1754,6 +1754,11 @@ func (sa *sitePagesAssembler) assembleResources() error {
mt = rs.rc.ContentMediaType
}
var filename string
if rs.fi != nil {
filename = rs.fi.Meta().Filename
}
rd := resources.ResourceSourceDescriptor{
OpenReadSeekCloser: rs.opener,
Path: rs.path,
@@ -1762,6 +1767,7 @@ func (sa *sitePagesAssembler) assembleResources() error {
TargetBasePaths: targetBasePaths,
BasePathRelPermalink: targetPaths.SubResourceBaseLink,
BasePathTargetPath: baseTarget,
SourceFilenameOrPath: filename,
NameNormalized: relPath,
NameOriginal: relPathOriginal,
MediaType: mt,

View File

@@ -111,6 +111,10 @@ func (h *HugoSites) ShouldSkipFileChangeEvent(ev fsnotify.Event) bool {
return h.skipRebuildForFilenames[ev.Name]
}
func (h *HugoSites) Close() error {
return h.Deps.Close()
}
func (h *HugoSites) isRebuild() bool {
return h.buildCounter.Load() > 0
}

View File

@@ -520,8 +520,9 @@ func (s *Site) executeDeferredTemplates(de *deps.DeferredExecutions) error {
},
})
de.FilenamesWithPostPrefix.ForEeach(func(filename string, _ bool) {
de.FilenamesWithPostPrefix.ForEeach(func(filename string, _ bool) bool {
g.Enqueue(filename)
return true
})
return g.Wait()
@@ -1058,6 +1059,8 @@ func (h *HugoSites) processPartialFileEvents(ctx context.Context, l logg.LevelLo
}
}
h.Deps.OnChangeListeners.Notify(changed.Changes()...)
if err := h.resolveAndClearStateForIdentities(ctx, l, cacheBusterOr, changed.Drain()); err != nil {
return err
}

View File

@@ -554,8 +554,6 @@ toc line 3
toc line 4
`
t.Run("base template", func(t *testing.T) {
@@ -569,7 +567,7 @@ toc line 4
).BuildE()
b.Assert(err, qt.IsNotNil)
b.Assert(err.Error(), qt.Contains, filepath.FromSlash(`render of "home" failed: "/layouts/baseof.html:4:6"`))
b.Assert(err.Error(), qt.Contains, `baseof.html:4:6`)
})
t.Run("index template", func(t *testing.T) {
@@ -583,7 +581,7 @@ toc line 4
).BuildE()
b.Assert(err, qt.IsNotNil)
b.Assert(err.Error(), qt.Contains, filepath.FromSlash(`render of "home" failed: "/layouts/index.html:3:7"`))
b.Assert(err.Error(), qt.Contains, `index.html:3:7"`)
})
t.Run("partial from define", func(t *testing.T) {
@@ -597,8 +595,7 @@ toc line 4
).BuildE()
b.Assert(err, qt.IsNotNil)
b.Assert(err.Error(), qt.Contains, filepath.FromSlash(`render of "home" failed: "/layouts/index.html:7:8": execute of template failed`))
b.Assert(err.Error(), qt.Contains, `execute of template failed: template: partials/toc.html:2:8: executing "partials/toc.html"`)
b.Assert(err.Error(), qt.Contains, `toc.html:2:8"`)
})
}

View File

@@ -69,6 +69,13 @@ func TestOptDebug() TestOpt {
}
}
// TestOptInfo will enable info logging in integration tests.
func TestOptInfo() TestOpt {
return func(c *IntegrationTestConfig) {
c.LogLevel = logg.LevelInfo
}
}
// TestOptWarn will enable warn logging in integration tests.
func TestOptWarn() TestOpt {
return func(c *IntegrationTestConfig) {
@@ -90,6 +97,13 @@ func TestOptWithNFDOnDarwin() TestOpt {
}
}
// TestOptWithOSFs enables the real file system.
func TestOptWithOSFs() TestOpt {
return func(c *IntegrationTestConfig) {
c.NeedsOsFS = true
}
}
// TestOptWithWorkingDir allows setting any config optiona as a function al option.
func TestOptWithConfig(fn func(c *IntegrationTestConfig)) TestOpt {
return func(c *IntegrationTestConfig) {
@@ -284,8 +298,9 @@ func (s *IntegrationTestBuilder) negate(match string) (string, bool) {
func (s *IntegrationTestBuilder) AssertFileContent(filename string, matches ...string) {
s.Helper()
content := strings.TrimSpace(s.FileContent(filename))
for _, m := range matches {
cm := qt.Commentf("File: %s Match %s", filename, m)
cm := qt.Commentf("File: %s Match %s\nContent:\n%s", filename, m, content)
lines := strings.Split(m, "\n")
for _, match := range lines {
match = strings.TrimSpace(match)
@@ -313,7 +328,8 @@ func (s *IntegrationTestBuilder) AssertFileContentExact(filename string, matches
s.Helper()
content := s.FileContent(filename)
for _, m := range matches {
s.Assert(content, qt.Contains, m, qt.Commentf(m))
cm := qt.Commentf("File: %s Match %s\nContent:\n%s", filename, m, content)
s.Assert(content, qt.Contains, m, cm)
}
}
@@ -450,6 +466,11 @@ func (s *IntegrationTestBuilder) Build() *IntegrationTestBuilder {
return s
}
func (s *IntegrationTestBuilder) Close() {
s.Helper()
s.Assert(s.H.Close(), qt.IsNil)
}
func (s *IntegrationTestBuilder) LogString() string {
return s.lastBuildLog
}

View File

@@ -143,6 +143,10 @@ func (p *pageState) GetDependencyManagerForScope(scope int) identity.Manager {
}
}
func (p *pageState) GetDependencyManagerForScopesAll() []identity.Manager {
return []identity.Manager{p.dependencyManager, p.dependencyManagerOutput}
}
func (p *pageState) Key() string {
return "page-" + strconv.FormatUint(p.pid, 10)
}

View File

@@ -143,13 +143,29 @@ func (c *pagesCollector) Collect() (collectErr error) {
s.pageMap.cfg.isRebuild = true
}
var hasStructuralChange bool
for _, id := range c.ids {
if id.isStructuralChange() {
hasStructuralChange = true
break
}
}
for _, id := range c.ids {
if id.p.IsLeafBundle() {
collectErr = c.collectDir(
id.p,
false,
func(fim hugofs.FileMetaInfo) bool {
return true
if hasStructuralChange {
return true
}
fimp := fim.Meta().PathInfo
if fimp == nil {
return true
}
return fimp.Path() == id.p.Path()
},
)
} else if id.p.IsBranchBundle() {

View File

@@ -245,10 +245,11 @@ func (b *BuildState) resolveDeletedPaths() {
return
}
var paths []string
b.sourceInfosPrevious.ForEeach(func(k string, _ *sourceInfo) {
b.sourceInfosPrevious.ForEeach(func(k string, _ *sourceInfo) bool {
if _, found := b.sourceInfosCurrent.Get(k); !found {
paths = append(paths, k)
}
return true
})
b.DeletedPaths = paths
@@ -287,6 +288,10 @@ func (p *PagesFromTemplate) GetDependencyManagerForScope(scope int) identity.Man
return p.DependencyManager
}
func (p *PagesFromTemplate) GetDependencyManagerForScopesAll() []identity.Manager {
return []identity.Manager{p.DependencyManager}
}
func (p *PagesFromTemplate) Execute(ctx context.Context) (BuildInfo, error) {
defer func() {
p.buildState.PrepareNextBuild()

View File

@@ -98,6 +98,18 @@ My Other Text: {{ $r.Content }}|{{ $r.Permalink }}|
`
func TestRebuildEditLeafBundleHeaderOnly(t *testing.T) {
b := TestRunning(t, rebuildFilesSimple)
b.AssertFileContent("public/mysection/mysectionbundle/index.html",
"My Section Bundle Content Content.")
b.EditFileReplaceAll("content/mysection/mysectionbundle/index.md", "My Section Bundle Content.", "My Section Bundle Content Edited.").Build()
b.AssertFileContent("public/mysection/mysectionbundle/index.html",
"My Section Bundle Content Edited.")
b.AssertRenderCountPage(2) // home (rss) + bundle.
b.AssertRenderCountContent(1)
}
func TestRebuildEditTextFileInLeafBundle(t *testing.T) {
b := TestRunning(t, rebuildFilesSimple)
b.AssertFileContent("public/mysection/mysectionbundle/index.html",
@@ -962,7 +974,7 @@ Single. {{ partial "head.html" . }}$
RelPermalink: {{ $js.RelPermalink }}|
`
b := TestRunning(t, files)
b := TestRunning(t, files, TestOptOsFs())
b.AssertFileContent("public/p1/index.html", "/js/main.712a50b59d0f0dedb4e3606eaa3860b1f1a5305f6c42da30a2985e473ba314eb.js")
b.AssertFileContent("public/index.html", "/js/main.712a50b59d0f0dedb4e3606eaa3860b1f1a5305f6c42da30a2985e473ba314eb.js")
@@ -998,7 +1010,7 @@ Base. {{ partial "common/head.html" . }}$
RelPermalink: {{ $js.RelPermalink }}|
`
b := TestRunning(t, files)
b := TestRunning(t, files, TestOptOsFs())
b.AssertFileContent("public/index.html", "/js/main.712a50b59d0f0dedb4e3606eaa3860b1f1a5305f6c42da30a2985e473ba314eb.js")

View File

@@ -1493,7 +1493,11 @@ func (s *Site) renderForTemplate(ctx context.Context, name, outputFormat string,
}
if err = s.Tmpl().ExecuteWithContext(ctx, templ, w, d); err != nil {
return fmt.Errorf("render of %q failed: %w", name, err)
filename := name
if p, ok := d.(*pageState); ok {
filename = p.String()
}
return fmt.Errorf("render of %q failed: %w", filename, err)
}
return
}