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
// 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 {
"/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",
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]
})
}
+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()
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))
})
}
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, "/"))
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
}
--- /dev/null
+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 }}