diff options
author | Bjørn Erik Pedersen <[email protected]> | 2022-05-24 09:34:36 +0200 |
---|---|---|
committer | Bjørn Erik Pedersen <[email protected]> | 2022-05-25 10:35:31 +0200 |
commit | cd0112a05a9ddb7043c9808284f93d8099c48473 (patch) | |
tree | 92da50996ede587f3683fdcfc851ed0325b64998 /resources | |
parent | 6f7fbe03b1a70733f00da6556a89250a29e53ec8 (diff) | |
download | hugo-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.go | 11 | ||||
-rw-r--r-- | resources/resource.go | 27 | ||||
-rw-r--r-- | resources/resource/resourcetypes.go | 3 | ||||
-rw-r--r-- | resources/resource_factories/create/create.go | 7 | ||||
-rw-r--r-- | resources/transform.go | 15 |
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 { |