]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
Fix same resource file published more than once
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Thu, 26 Dec 2024 12:47:10 +0000 (13:47 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Fri, 27 Dec 2024 17:55:24 +0000 (18:55 +0100)
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

hugofs/rootmapping_fs.go
resources/resource_cache.go
resources/resource_factories/create/create.go
testscripts/commands/hugo__path-warnings_issue13164.txt [new file with mode: 0644]

index 02e541a05b1003a937a6fad21228313b77010d1d..3884931749272dfdb69055759bb9d4d659f93555 100644 (file)
@@ -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 {
index a3ba9aa260d6b5b1e1b2dde08e375c54befbc3c4..898cd4c31690a97f0297147f850532350718e163 100644 (file)
@@ -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()
index 7dd26f4c0f70865710cc240c71d858086c0409ee..581c0a8541d662d7097602d66a9d64884595bf53 100644 (file)
@@ -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 (file)
index 0000000..1342c28
--- /dev/null
@@ -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 }}