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  }