summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2024-12-26 13:47:10 +0100
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2024-12-27 18:55:24 +0100
commit77824d704c124dc43b30352a03f1fbad13e54dfe (patch)
treea2256beb8e3c699c4fbc95eb054c401dd0a4e186
parentec0caaec7ce41ca6236da9d661e92dc433e1951b (diff)
downloadhugo-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.go3
-rw-r--r--resources/resource_cache.go12
-rw-r--r--resources/resource_factories/create/create.go45
-rw-r--r--testscripts/commands/hugo__path-warnings_issue13164.txt15
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 }}