diff options
author | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2024-12-26 13:47:10 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2024-12-27 18:55:24 +0100 |
commit | 77824d704c124dc43b30352a03f1fbad13e54dfe (patch) | |
tree | a2256beb8e3c699c4fbc95eb054c401dd0a4e186 | |
parent | ec0caaec7ce41ca6236da9d661e92dc433e1951b (diff) | |
download | hugo-77824d704c124dc43b30352a03f1fbad13e54dfe.tar.gz hugo-77824d704c124dc43b30352a03f1fbad13e54dfe.zip |
Fix same resource file published more than once
This may still happen, though, in low memory situations or very big sites, but I'm not sure it's worth spending time on fixing that. Writing the same file more than once isn't harmful, the negative effect is the false path warning.
We may find a way to detect that situation if this becomes a real problem.
Fixes #13164
-rw-r--r-- | hugofs/rootmapping_fs.go | 3 | ||||
-rw-r--r-- | resources/resource_cache.go | 12 | ||||
-rw-r--r-- | resources/resource_factories/create/create.go | 45 | ||||
-rw-r--r-- | testscripts/commands/hugo__path-warnings_issue13164.txt | 15 |
4 files changed, 48 insertions, 27 deletions
diff --git a/hugofs/rootmapping_fs.go b/hugofs/rootmapping_fs.go index 02e541a05..388493174 100644 --- a/hugofs/rootmapping_fs.go +++ b/hugofs/rootmapping_fs.go @@ -311,12 +311,13 @@ func (fs *RootMappingFs) Open(name string) (afero.File, error) { // Stat returns the os.FileInfo structure describing a given file. If there is // an error, it will be of type *os.PathError. +// If multiple roots are found, the last one will be used. func (fs *RootMappingFs) Stat(name string) (os.FileInfo, error) { fis, err := fs.doStat(name) if err != nil { return nil, err } - return fis[0], nil + return fis[len(fis)-1], nil } type ComponentPath struct { diff --git a/resources/resource_cache.go b/resources/resource_cache.go index a3ba9aa26..898cd4c31 100644 --- a/resources/resource_cache.go +++ b/resources/resource_cache.go @@ -36,6 +36,11 @@ func newResourceCache(rs *Spec, memCache *dynacache.Cache) *ResourceCache { "/res1", dynacache.OptionsPartition{ClearWhen: dynacache.ClearOnChange, Weight: 40}, ), + cacheResourceFile: dynacache.GetOrCreatePartition[string, resource.Resource]( + memCache, + "/res2", + dynacache.OptionsPartition{ClearWhen: dynacache.ClearOnChange, Weight: 40}, + ), CacheResourceRemote: dynacache.GetOrCreatePartition[string, resource.Resource]( memCache, "/resr", @@ -58,6 +63,7 @@ type ResourceCache struct { sync.RWMutex cacheResource *dynacache.Partition[string, resource.Resource] + cacheResourceFile *dynacache.Partition[string, resource.Resource] CacheResourceRemote *dynacache.Partition[string, resource.Resource] cacheResources *dynacache.Partition[string, resource.Resources] cacheResourceTransformation *dynacache.Partition[string, *resourceAdapterInner] @@ -79,6 +85,12 @@ func (c *ResourceCache) GetOrCreate(key string, f func() (resource.Resource, err }) } +func (c *ResourceCache) GetOrCreateFile(key string, f func() (resource.Resource, error)) (resource.Resource, error) { + return c.cacheResourceFile.GetOrCreate(key, func(key string) (resource.Resource, error) { + return f() + }) +} + func (c *ResourceCache) GetOrCreateResources(key string, f func() (resource.Resources, error)) (resource.Resources, error) { return c.cacheResources.GetOrCreate(key, func(key string) (resource.Resources, error) { return f() diff --git a/resources/resource_factories/create/create.go b/resources/resource_factories/create/create.go index 7dd26f4c0..581c0a854 100644 --- a/resources/resource_factories/create/create.go +++ b/resources/resource_factories/create/create.go @@ -143,19 +143,7 @@ func (c *Client) Get(pathname string) (resource.Resource, error) { return nil, err } - meta := fi.(hugofs.FileMetaInfo).Meta() - pi := meta.PathInfo - - return c.rs.NewResource(resources.ResourceSourceDescriptor{ - LazyPublish: true, - OpenReadSeekCloser: func() (hugio.ReadSeekCloser, error) { - return c.rs.BaseFs.Assets.Fs.Open(filename) - }, - Path: pi, - GroupIdentity: pi, - TargetPath: pathname, - SourceFilenameOrPath: meta.Filename, - }) + return c.getOrCreateFileResource(fi.(hugofs.FileMetaInfo)) }) } @@ -181,6 +169,23 @@ func (c *Client) GetMatch(pattern string) (resource.Resource, error) { return res[0], err } +func (c *Client) getOrCreateFileResource(info hugofs.FileMetaInfo) (resource.Resource, error) { + meta := info.Meta() + return c.rs.ResourceCache.GetOrCreateFile(filepath.ToSlash(meta.Filename), func() (resource.Resource, error) { + return c.rs.NewResource(resources.ResourceSourceDescriptor{ + LazyPublish: true, + OpenReadSeekCloser: func() (hugio.ReadSeekCloser, error) { + return meta.Open() + }, + NameNormalized: meta.PathInfo.Path(), + NameOriginal: meta.PathInfo.Unnormalized().Path(), + GroupIdentity: meta.PathInfo, + TargetPath: meta.PathInfo.Unnormalized().Path(), + SourceFilenameOrPath: meta.Filename, + }) + }) +} + func (c *Client) match(name, pattern string, matchFunc func(r resource.Resource) bool, firstOnly bool) (resource.Resources, error) { pattern = glob.NormalizePath(pattern) partitions := glob.FilterGlobParts(strings.Split(pattern, "/")) @@ -191,19 +196,7 @@ func (c *Client) match(name, pattern string, matchFunc func(r resource.Resource) var res resource.Resources handle := func(info hugofs.FileMetaInfo) (bool, error) { - meta := info.Meta() - - r, err := c.rs.NewResource(resources.ResourceSourceDescriptor{ - LazyPublish: true, - OpenReadSeekCloser: func() (hugio.ReadSeekCloser, error) { - return meta.Open() - }, - NameNormalized: meta.PathInfo.Path(), - NameOriginal: meta.PathInfo.Unnormalized().Path(), - GroupIdentity: meta.PathInfo, - TargetPath: meta.PathInfo.Unnormalized().Path(), - SourceFilenameOrPath: meta.Filename, - }) + r, err := c.getOrCreateFileResource(info) if err != nil { return true, err } diff --git a/testscripts/commands/hugo__path-warnings_issue13164.txt b/testscripts/commands/hugo__path-warnings_issue13164.txt new file mode 100644 index 000000000..1342c287a --- /dev/null +++ b/testscripts/commands/hugo__path-warnings_issue13164.txt @@ -0,0 +1,15 @@ +hugo --printPathWarnings + +! stderr 'Duplicate target paths' + +-- hugo.toml -- +disableKinds = ['page','rss','section','sitemap','taxonomy','term'] +-- assets/foo.txt -- +foo +-- layouts/index.html -- +A: {{ (resources.Get "foo.txt").RelPermalink }} +B: {{ (resources.GetMatch "foo.txt").RelPermalink }} +C: {{ (index (resources.Match "foo.txt") 0).RelPermalink }} +D: {{ (index (resources.ByType "text") 0).RelPermalink }} +-- layouts/unused/single.html -- +{{ .Title }} |