github.com/dirkolbrich/hugo@v0.47.1/tpl/data/cache.go (about)

     1  // Copyright 2017 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 data
    15  
    16  import (
    17  	"crypto/md5"
    18  	"encoding/hex"
    19  	"errors"
    20  	"sync"
    21  
    22  	"github.com/gohugoio/hugo/config"
    23  	"github.com/gohugoio/hugo/helpers"
    24  	"github.com/spf13/afero"
    25  )
    26  
    27  var cacheMu sync.RWMutex
    28  
    29  // getCacheFileID returns the cache ID for a string.
    30  func getCacheFileID(cfg config.Provider, id string) string {
    31  	hash := md5.Sum([]byte(id))
    32  	return cfg.GetString("cacheDir") + hex.EncodeToString(hash[:])
    33  }
    34  
    35  // getCache returns the content for an ID from the file cache or an error.
    36  // If the ID is not found, return nil,nil.
    37  func getCache(id string, fs afero.Fs, cfg config.Provider, ignoreCache bool) ([]byte, error) {
    38  	if ignoreCache {
    39  		return nil, nil
    40  	}
    41  
    42  	cacheMu.RLock()
    43  	defer cacheMu.RUnlock()
    44  
    45  	fID := getCacheFileID(cfg, id)
    46  	isExists, err := helpers.Exists(fID, fs)
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  	if !isExists {
    51  		return nil, nil
    52  	}
    53  
    54  	return afero.ReadFile(fs, fID)
    55  }
    56  
    57  // writeCache writes bytes associated with an ID into the file cache.
    58  func writeCache(id string, c []byte, fs afero.Fs, cfg config.Provider, ignoreCache bool) error {
    59  	if ignoreCache {
    60  		return nil
    61  	}
    62  
    63  	cacheMu.Lock()
    64  	defer cacheMu.Unlock()
    65  
    66  	fID := getCacheFileID(cfg, id)
    67  	f, err := fs.Create(fID)
    68  	if err != nil {
    69  		return errors.New("Error: " + err.Error() + ". Failed to create file: " + fID)
    70  	}
    71  	defer f.Close()
    72  
    73  	n, err := f.Write(c)
    74  	if err != nil {
    75  		return errors.New("Error: " + err.Error() + ". Failed to write to file: " + fID)
    76  	}
    77  	if n == 0 {
    78  		return errors.New("No bytes written to file: " + fID)
    79  	}
    80  	return nil
    81  }
    82  
    83  func deleteCache(id string, fs afero.Fs, cfg config.Provider) error {
    84  	return fs.Remove(getCacheFileID(cfg, id))
    85  }