mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-17 21:01:26 +02:00
Make sure that unreferenced but changed bundle resources gets republished
Fixes #13748
This commit is contained in:
@@ -21,7 +21,6 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -1310,7 +1309,6 @@ func (h *HugoSites) resolveAndResetDependententPageOutputs(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
po.renderState = 0
|
po.renderState = 0
|
||||||
po.p.resourcesPublishInit = &sync.Once{}
|
|
||||||
if r == identity.FinderFoundOneOfMany || po.f.Name == output.HTTPStatus404HTMLFormat.Name {
|
if r == identity.FinderFoundOneOfMany || po.f.Name == output.HTTPStatus404HTMLFormat.Name {
|
||||||
// Will force a re-render even in fast render mode.
|
// Will force a re-render even in fast render mode.
|
||||||
po.renderOnce = false
|
po.renderOnce = false
|
||||||
|
@@ -905,7 +905,6 @@ func (h *HugoSites) processPartialFileEvents(ctx context.Context, l logg.LevelLo
|
|||||||
handleChange := func(pathInfo *paths.Path, delete, isDir bool) {
|
handleChange := func(pathInfo *paths.Path, delete, isDir bool) {
|
||||||
switch pathInfo.Component() {
|
switch pathInfo.Component() {
|
||||||
case files.ComponentFolderContent:
|
case files.ComponentFolderContent:
|
||||||
logger.Println("Source changed", pathInfo.Path())
|
|
||||||
isContentDataFile := pathInfo.IsContentData()
|
isContentDataFile := pathInfo.IsContentData()
|
||||||
if !isContentDataFile {
|
if !isContentDataFile {
|
||||||
if ids := h.pageTrees.collectAndMarkStaleIdentities(pathInfo); len(ids) > 0 {
|
if ids := h.pageTrees.collectAndMarkStaleIdentities(pathInfo); len(ids) > 0 {
|
||||||
|
@@ -19,7 +19,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/hugofs"
|
"github.com/gohugoio/hugo/hugofs"
|
||||||
@@ -29,6 +28,7 @@ import (
|
|||||||
"github.com/gohugoio/hugo/media"
|
"github.com/gohugoio/hugo/media"
|
||||||
"github.com/gohugoio/hugo/output"
|
"github.com/gohugoio/hugo/output"
|
||||||
"github.com/gohugoio/hugo/related"
|
"github.com/gohugoio/hugo/related"
|
||||||
|
"github.com/gohugoio/hugo/resources"
|
||||||
"github.com/gohugoio/hugo/tpl/tplimpl"
|
"github.com/gohugoio/hugo/tpl/tplimpl"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
|
|
||||||
@@ -111,7 +111,6 @@ type pageState struct {
|
|||||||
|
|
||||||
resource.Staler
|
resource.Staler
|
||||||
dependencyManager identity.Manager
|
dependencyManager identity.Manager
|
||||||
resourcesPublishInit *sync.Once
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pageState) incrPageOutputTemplateVariation() {
|
func (p *pageState) incrPageOutputTemplateVariation() {
|
||||||
@@ -522,13 +521,17 @@ func (p *pageState) initPage() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *pageState) renderResources() error {
|
func (p *pageState) renderResources() error {
|
||||||
var initErr error
|
|
||||||
|
|
||||||
p.resourcesPublishInit.Do(func() {
|
|
||||||
for _, r := range p.Resources() {
|
for _, r := range p.Resources() {
|
||||||
|
|
||||||
if _, ok := r.(page.Page); ok {
|
if _, ok := r.(page.Page); ok {
|
||||||
|
if p.s.h.buildCounter.Load() == 0 {
|
||||||
// Pages gets rendered with the owning page but we count them here.
|
// Pages gets rendered with the owning page but we count them here.
|
||||||
p.s.PathSpec.ProcessingStats.Incr(&p.s.PathSpec.ProcessingStats.Pages)
|
p.s.PathSpec.ProcessingStats.Incr(&p.s.PathSpec.ProcessingStats.Pages)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if resources.IsPublished(r) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -540,8 +543,7 @@ func (p *pageState) renderResources() error {
|
|||||||
|
|
||||||
src, ok := r.(resource.Source)
|
src, ok := r.(resource.Source)
|
||||||
if !ok {
|
if !ok {
|
||||||
initErr = fmt.Errorf("resource %T does not support resource.Source", r)
|
return fmt.Errorf("resource %T does not support resource.Source", r)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := src.Publish(); err != nil {
|
if err := src.Publish(); err != nil {
|
||||||
@@ -552,9 +554,8 @@ func (p *pageState) renderResources() error {
|
|||||||
p.s.PathSpec.ProcessingStats.Incr(&p.s.PathSpec.ProcessingStats.Files)
|
p.s.PathSpec.ProcessingStats.Incr(&p.s.PathSpec.ProcessingStats.Files)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
return initErr
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pageState) AlternativeOutputFormats() page.OutputFormats {
|
func (p *pageState) AlternativeOutputFormats() page.OutputFormats {
|
||||||
|
@@ -16,7 +16,6 @@ package hugolib
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/hugofs/files"
|
"github.com/gohugoio/hugo/hugofs/files"
|
||||||
@@ -190,7 +189,6 @@ func (h *HugoSites) doNewPage(m *pageMeta) (*pageState, *paths.Path, error) {
|
|||||||
pid: pid,
|
pid: pid,
|
||||||
pageOutput: nopPageOutput,
|
pageOutput: nopPageOutput,
|
||||||
pageOutputTemplateVariationsState: &atomic.Uint32{},
|
pageOutputTemplateVariationsState: &atomic.Uint32{},
|
||||||
resourcesPublishInit: &sync.Once{},
|
|
||||||
Staler: m,
|
Staler: m,
|
||||||
dependencyManager: m.s.Conf.NewIdentityManager(m.Path()),
|
dependencyManager: m.s.Conf.NewIdentityManager(m.Path()),
|
||||||
pageCommon: &pageCommon{
|
pageCommon: &pageCommon{
|
||||||
|
@@ -1946,3 +1946,23 @@ tags: ["tag1"]
|
|||||||
// But that is a harder problem to tackle.
|
// But that is a harder problem to tackle.
|
||||||
b.AssertFileContent("public/tags/index.html", "All. Tag1|Tag2|")
|
b.AssertFileContent("public/tags/index.html", "All. Tag1|Tag2|")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRebuildEditNonReferencedResourceIssue13748(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
files := `
|
||||||
|
-- hugo.toml --
|
||||||
|
baseURL = "https://example.com"
|
||||||
|
disableLiveReload = true
|
||||||
|
-- content/mybundle/index.md --
|
||||||
|
-- content/mybundle/resource.txt --
|
||||||
|
This is a resource file.
|
||||||
|
-- layouts/all.html --
|
||||||
|
All.
|
||||||
|
`
|
||||||
|
b := TestRunning(t, files)
|
||||||
|
|
||||||
|
b.AssertFileContent("public/mybundle/resource.txt", "This is a resource file.")
|
||||||
|
b.EditFileReplaceAll("content/mybundle/resource.txt", "This is a resource file.", "This is an edited resource file.").Build()
|
||||||
|
b.AssertFileContent("public/mybundle/resource.txt", "This is an edited resource file.")
|
||||||
|
}
|
||||||
|
@@ -24,6 +24,7 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/identity"
|
"github.com/gohugoio/hugo/identity"
|
||||||
|
"github.com/gohugoio/hugo/lazy"
|
||||||
"github.com/gohugoio/hugo/resources/internal"
|
"github.com/gohugoio/hugo/resources/internal"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/common/hashing"
|
"github.com/gohugoio/hugo/common/hashing"
|
||||||
@@ -54,6 +55,7 @@ var (
|
|||||||
_ identity.DependencyManagerProvider = (*genericResource)(nil)
|
_ identity.DependencyManagerProvider = (*genericResource)(nil)
|
||||||
_ identity.Identity = (*genericResource)(nil)
|
_ identity.Identity = (*genericResource)(nil)
|
||||||
_ fileInfo = (*genericResource)(nil)
|
_ fileInfo = (*genericResource)(nil)
|
||||||
|
_ isPublishedProvider = (*genericResource)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
type ResourceSourceDescriptor struct {
|
type ResourceSourceDescriptor struct {
|
||||||
@@ -242,6 +244,7 @@ type baseResourceInternal interface {
|
|||||||
fileInfo
|
fileInfo
|
||||||
mediaTypeAssigner
|
mediaTypeAssigner
|
||||||
targetPather
|
targetPather
|
||||||
|
isPublishedProvider
|
||||||
|
|
||||||
ReadSeekCloser() (hugio.ReadSeekCloser, error)
|
ReadSeekCloser() (hugio.ReadSeekCloser, error)
|
||||||
|
|
||||||
@@ -355,7 +358,7 @@ func GetTestInfoForResource(r resource.Resource) GenericResourceTestInfo {
|
|||||||
|
|
||||||
// genericResource represents a generic linkable resource.
|
// genericResource represents a generic linkable resource.
|
||||||
type genericResource struct {
|
type genericResource struct {
|
||||||
publishInit *sync.Once
|
publishInit *lazy.OnceMore
|
||||||
|
|
||||||
key string
|
key string
|
||||||
keyInit *sync.Once
|
keyInit *sync.Once
|
||||||
@@ -536,6 +539,10 @@ func (l *genericResource) Publish() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *genericResource) isPublished() bool {
|
||||||
|
return l.publishInit.Done()
|
||||||
|
}
|
||||||
|
|
||||||
func (l *genericResource) RelPermalink() string {
|
func (l *genericResource) RelPermalink() string {
|
||||||
return l.spec.PathSpec.GetBasePath(false) + paths.PathEscape(l.paths.TargetLink())
|
return l.spec.PathSpec.GetBasePath(false) + paths.PathEscape(l.paths.TargetLink())
|
||||||
}
|
}
|
||||||
@@ -629,7 +636,7 @@ func (rc *genericResource) cloneWithUpdates(u *transformationUpdate) (baseResour
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l genericResource) clone() *genericResource {
|
func (l genericResource) clone() *genericResource {
|
||||||
l.publishInit = &sync.Once{}
|
l.publishInit = &lazy.OnceMore{}
|
||||||
l.keyInit = &sync.Once{}
|
l.keyInit = &sync.Once{}
|
||||||
return &l
|
return &l
|
||||||
}
|
}
|
||||||
@@ -643,6 +650,10 @@ type targetPather interface {
|
|||||||
TargetPath() string
|
TargetPath() string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type isPublishedProvider interface {
|
||||||
|
isPublished() bool
|
||||||
|
}
|
||||||
|
|
||||||
type resourceHash struct {
|
type resourceHash struct {
|
||||||
value uint64
|
value uint64
|
||||||
size int64
|
size int64
|
||||||
@@ -702,6 +713,11 @@ func InternalResourceSourcePathBestEffort(r resource.Resource) string {
|
|||||||
return InternalResourceTargetPath(r)
|
return InternalResourceTargetPath(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isPublished returns true if the resource is published.
|
||||||
|
func IsPublished(r resource.Resource) bool {
|
||||||
|
return r.(isPublishedProvider).isPublished()
|
||||||
|
}
|
||||||
|
|
||||||
type targetPathProvider interface {
|
type targetPathProvider interface {
|
||||||
// targetPath is the relative path to this resource.
|
// targetPath is the relative path to this resource.
|
||||||
// In most cases this will be the same as the RelPermalink(),
|
// In most cases this will be the same as the RelPermalink(),
|
||||||
|
@@ -20,6 +20,7 @@ import (
|
|||||||
|
|
||||||
"github.com/gohugoio/hugo/config"
|
"github.com/gohugoio/hugo/config"
|
||||||
"github.com/gohugoio/hugo/config/allconfig"
|
"github.com/gohugoio/hugo/config/allconfig"
|
||||||
|
"github.com/gohugoio/hugo/lazy"
|
||||||
"github.com/gohugoio/hugo/output"
|
"github.com/gohugoio/hugo/output"
|
||||||
"github.com/gohugoio/hugo/resources/internal"
|
"github.com/gohugoio/hugo/resources/internal"
|
||||||
"github.com/gohugoio/hugo/resources/jsconfig"
|
"github.com/gohugoio/hugo/resources/jsconfig"
|
||||||
@@ -189,7 +190,7 @@ func (r *Spec) NewResource(rd ResourceSourceDescriptor) (resource.Resource, erro
|
|||||||
gr := &genericResource{
|
gr := &genericResource{
|
||||||
Staler: &AtomicStaler{},
|
Staler: &AtomicStaler{},
|
||||||
h: &resourceHash{},
|
h: &resourceHash{},
|
||||||
publishInit: &sync.Once{},
|
publishInit: &lazy.OnceMore{},
|
||||||
keyInit: &sync.Once{},
|
keyInit: &sync.Once{},
|
||||||
includeHashInKey: isImage,
|
includeHashInKey: isImage,
|
||||||
paths: rp,
|
paths: rp,
|
||||||
|
@@ -61,6 +61,7 @@ var (
|
|||||||
_ identity.DependencyManagerProvider = (*resourceAdapter)(nil)
|
_ identity.DependencyManagerProvider = (*resourceAdapter)(nil)
|
||||||
_ identity.IdentityGroupProvider = (*resourceAdapter)(nil)
|
_ identity.IdentityGroupProvider = (*resourceAdapter)(nil)
|
||||||
_ resource.NameNormalizedProvider = (*resourceAdapter)(nil)
|
_ resource.NameNormalizedProvider = (*resourceAdapter)(nil)
|
||||||
|
_ isPublishedProvider = (*resourceAdapter)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
// These are transformations that need special support in Hugo that may not
|
// These are transformations that need special support in Hugo that may not
|
||||||
@@ -325,6 +326,11 @@ func (r *resourceAdapter) Publish() error {
|
|||||||
return r.target.Publish()
|
return r.target.Publish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *resourceAdapter) isPublished() bool {
|
||||||
|
r.init(false, false)
|
||||||
|
return r.target.isPublished()
|
||||||
|
}
|
||||||
|
|
||||||
func (r *resourceAdapter) ReadSeekCloser() (hugio.ReadSeekCloser, error) {
|
func (r *resourceAdapter) ReadSeekCloser() (hugio.ReadSeekCloser, error) {
|
||||||
r.init(false, false)
|
r.init(false, false)
|
||||||
return r.target.ReadSeekCloser()
|
return r.target.ReadSeekCloser()
|
||||||
|
Reference in New Issue
Block a user