github.com/graemephi/kahugo@v0.62.3-0.20211121071557-d78c0423784d/resources/resource_factories/create/create.go (about) 1 // Copyright 2019 The Hugo Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 // Package create contains functions for to create Resource objects. This will 15 // typically non-files. 16 package create 17 18 import ( 19 "path" 20 "path/filepath" 21 "strings" 22 23 "github.com/gohugoio/hugo/hugofs/glob" 24 25 "github.com/gohugoio/hugo/hugofs" 26 27 "github.com/gohugoio/hugo/common/hugio" 28 "github.com/gohugoio/hugo/resources" 29 "github.com/gohugoio/hugo/resources/resource" 30 ) 31 32 // Client contains methods to create Resource objects. 33 // tasks to Resource objects. 34 type Client struct { 35 rs *resources.Spec 36 } 37 38 // New creates a new Client with the given specification. 39 func New(rs *resources.Spec) *Client { 40 return &Client{rs: rs} 41 } 42 43 // Get creates a new Resource by opening the given filename in the assets filesystem. 44 func (c *Client) Get(filename string) (resource.Resource, error) { 45 filename = filepath.Clean(filename) 46 return c.rs.ResourceCache.GetOrCreate(resources.ResourceCacheKey(filename), func() (resource.Resource, error) { 47 return c.rs.New(resources.ResourceSourceDescriptor{ 48 Fs: c.rs.BaseFs.Assets.Fs, 49 LazyPublish: true, 50 SourceFilename: filename, 51 }) 52 }) 53 } 54 55 // Match gets the resources matching the given pattern from the assets filesystem. 56 func (c *Client) Match(pattern string) (resource.Resources, error) { 57 return c.match(pattern, false) 58 } 59 60 // GetMatch gets first resource matching the given pattern from the assets filesystem. 61 func (c *Client) GetMatch(pattern string) (resource.Resource, error) { 62 res, err := c.match(pattern, true) 63 if err != nil || len(res) == 0 { 64 return nil, err 65 } 66 return res[0], err 67 } 68 69 func (c *Client) match(pattern string, firstOnly bool) (resource.Resources, error) { 70 var name string 71 if firstOnly { 72 name = "__get-match" 73 } else { 74 name = "__match" 75 } 76 77 pattern = glob.NormalizePath(pattern) 78 partitions := glob.FilterGlobParts(strings.Split(pattern, "/")) 79 if len(partitions) == 0 { 80 partitions = []string{resources.CACHE_OTHER} 81 } 82 key := path.Join(name, path.Join(partitions...)) 83 key = path.Join(key, pattern) 84 85 return c.rs.ResourceCache.GetOrCreateResources(key, func() (resource.Resources, error) { 86 var res resource.Resources 87 88 handle := func(info hugofs.FileMetaInfo) (bool, error) { 89 meta := info.Meta() 90 r, err := c.rs.New(resources.ResourceSourceDescriptor{ 91 LazyPublish: true, 92 FileInfo: info, 93 OpenReadSeekCloser: func() (hugio.ReadSeekCloser, error) { 94 return meta.Open() 95 }, 96 RelTargetFilename: meta.Path, 97 }) 98 if err != nil { 99 return true, err 100 } 101 102 res = append(res, r) 103 104 return firstOnly, nil 105 } 106 107 if err := hugofs.Glob(c.rs.BaseFs.Assets.Fs, pattern, handle); err != nil { 108 return nil, err 109 } 110 111 return res, nil 112 }) 113 } 114 115 // FromString creates a new Resource from a string with the given relative target path. 116 func (c *Client) FromString(targetPath, content string) (resource.Resource, error) { 117 return c.rs.ResourceCache.GetOrCreate(path.Join(resources.CACHE_OTHER, targetPath), func() (resource.Resource, error) { 118 return c.rs.New( 119 resources.ResourceSourceDescriptor{ 120 Fs: c.rs.FileCaches.AssetsCache().Fs, 121 LazyPublish: true, 122 OpenReadSeekCloser: func() (hugio.ReadSeekCloser, error) { 123 return hugio.NewReadSeekerNoOpCloserFromString(content), nil 124 }, 125 RelTargetFilename: filepath.Clean(targetPath), 126 }) 127 }) 128 }