aboutsummaryrefslogtreecommitdiffhomepage
path: root/resources
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <[email protected]>2022-05-24 09:34:36 +0200
committerBjørn Erik Pedersen <[email protected]>2022-05-25 10:35:31 +0200
commitcd0112a05a9ddb7043c9808284f93d8099c48473 (patch)
tree92da50996ede587f3683fdcfc851ed0325b64998 /resources
parent6f7fbe03b1a70733f00da6556a89250a29e53ec8 (diff)
downloadhugo-cd0112a05a9ddb7043c9808284f93d8099c48473.tar.gz
hugo-cd0112a05a9ddb7043c9808284f93d8099c48473.zip
Add resources.Copy
Implemented by most Resource objects, but not Page (for now). Fixes #9313
Diffstat (limited to 'resources')
-rw-r--r--resources/image.go11
-rw-r--r--resources/resource.go27
-rw-r--r--resources/resource/resourcetypes.go3
-rw-r--r--resources/resource_factories/create/create.go7
-rw-r--r--resources/transform.go15
5 files changed, 59 insertions, 4 deletions
diff --git a/resources/image.go b/resources/image.go
index f431784b4..3eda709d9 100644
--- a/resources/image.go
+++ b/resources/image.go
@@ -134,7 +134,7 @@ func (i *imageResource) getExif() *exif.ExifInfo {
return i.meta.Exif
}
-// Cloneis for internal use.
+// Clone is for internal use.
func (i *imageResource) Clone() resource.Resource {
gr := i.baseResource.Clone().(baseResource)
return &imageResource{
@@ -144,6 +144,15 @@ func (i *imageResource) Clone() resource.Resource {
}
}
+func (i *imageResource) cloneTo(targetPath string) resource.Resource {
+ gr := i.baseResource.cloneTo(targetPath).(baseResource)
+ return &imageResource{
+ root: i.root,
+ Image: i.WithSpec(gr),
+ baseResource: gr,
+ }
+}
+
func (i *imageResource) cloneWithUpdates(u *transformationUpdate) (baseResource, error) {
base, err := i.baseResource.cloneWithUpdates(u)
if err != nil {
diff --git a/resources/resource.go b/resources/resource.go
index ead483d65..e38090dbe 100644
--- a/resources/resource.go
+++ b/resources/resource.go
@@ -1,4 +1,4 @@
-// Copyright 2019 The Hugo Authors. All rights reserved.
+// Copyright 2022 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -120,8 +120,19 @@ func (t transformerNotAvailable) Key() internal.ResourceTransformationKey {
return t.key
}
+// resourceCopier is for internal use.
+type resourceCopier interface {
+ cloneTo(targetPath string) resource.Resource
+}
+
+// Copy copies r to the targetPath given.
+func Copy(r resource.Resource, targetPath string) resource.Resource {
+ return r.(resourceCopier).cloneTo(targetPath)
+}
+
type baseResourceResource interface {
resource.Cloner
+ resourceCopier
resource.ContentProvider
resource.Resource
resource.Identifier
@@ -225,6 +236,20 @@ func (l *genericResource) Clone() resource.Resource {
return l.clone()
}
+func (l *genericResource) cloneTo(targetPath string) resource.Resource {
+ c := l.clone()
+
+ targetPath = helpers.ToSlashTrimLeading(targetPath)
+ dir, file := path.Split(targetPath)
+
+ c.resourcePathDescriptor = &resourcePathDescriptor{
+ relTargetDirFile: dirFile{dir: dir, file: file},
+ }
+
+ return c
+
+}
+
func (l *genericResource) Content() (any, error) {
if err := l.initContent(); err != nil {
return nil, err
diff --git a/resources/resource/resourcetypes.go b/resources/resource/resourcetypes.go
index e3251aabe..4ba95c170 100644
--- a/resources/resource/resourcetypes.go
+++ b/resources/resource/resourcetypes.go
@@ -26,8 +26,7 @@ var (
_ ResourceError = (*resourceError)(nil)
)
-// Cloner is an internal template and not meant for use in the templates. It
-// may change without notice.
+// Cloner is for internal use.
type Cloner interface {
Clone() Resource
}
diff --git a/resources/resource_factories/create/create.go b/resources/resource_factories/create/create.go
index 3827411a9..075d25736 100644
--- a/resources/resource_factories/create/create.go
+++ b/resources/resource_factories/create/create.go
@@ -51,6 +51,13 @@ func New(rs *resources.Spec) *Client {
}
}
+// Copy copies r to the new targetPath.
+func (c *Client) Copy(r resource.Resource, targetPath string) (resource.Resource, error) {
+ return c.rs.ResourceCache.GetOrCreate(resources.ResourceCacheKey(targetPath), func() (resource.Resource, error) {
+ return resources.Copy(r, targetPath), nil
+ })
+}
+
// Get creates a new Resource by opening the given filename in the assets filesystem.
func (c *Client) Get(filename string) (resource.Resource, error) {
filename = filepath.Clean(filename)
diff --git a/resources/transform.go b/resources/transform.go
index a470c94da..bb1608cbd 100644
--- a/resources/transform.go
+++ b/resources/transform.go
@@ -42,6 +42,7 @@ import (
var (
_ resource.ContentResource = (*resourceAdapter)(nil)
+ _ resourceCopier = (*resourceAdapter)(nil)
_ resource.ReadSeekCloserResource = (*resourceAdapter)(nil)
_ resource.Resource = (*resourceAdapter)(nil)
_ resource.Source = (*resourceAdapter)(nil)
@@ -175,6 +176,19 @@ func (r *resourceAdapter) Data() any {
return r.target.Data()
}
+func (r resourceAdapter) cloneTo(targetPath string) resource.Resource {
+ newtTarget := r.target.cloneTo(targetPath)
+ newInner := &resourceAdapterInner{
+ spec: r.spec,
+ target: newtTarget.(transformableResource),
+ }
+ if r.resourceAdapterInner.publishOnce != nil {
+ newInner.publishOnce = &publishOnce{}
+ }
+ r.resourceAdapterInner = newInner
+ return &r
+}
+
func (r *resourceAdapter) Crop(spec string) (images.ImageResource, error) {
return r.getImageOps().Crop(spec)
}
@@ -596,6 +610,7 @@ type transformableResource interface {
resource.ContentProvider
resource.Resource
resource.Identifier
+ resourceCopier
}
type transformationUpdate struct {