github.com/shohhei1126/hugo@v0.42.2-0.20180623210752-3d5928889ad7/hugolib/prune_resources.go (about)

     1  // Copyright 2017-present 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 hugolib
    15  
    16  import (
    17  	"fmt"
    18  	"io"
    19  	"os"
    20  	"strings"
    21  
    22  	"github.com/spf13/afero"
    23  )
    24  
    25  // GC requires a build first.
    26  func (h *HugoSites) GC() (int, error) {
    27  	s := h.Sites[0]
    28  	fs := h.PathSpec.BaseFs.ResourcesFs
    29  
    30  	imageCacheDir := s.resourceSpec.GenImagePath
    31  	if len(imageCacheDir) < 10 {
    32  		panic("invalid image cache")
    33  	}
    34  
    35  	isInUse := func(filename string) bool {
    36  		key := strings.TrimPrefix(filename, imageCacheDir)
    37  		for _, site := range h.Sites {
    38  			if site.resourceSpec.IsInCache(key) {
    39  				return true
    40  			}
    41  		}
    42  
    43  		return false
    44  	}
    45  
    46  	counter := 0
    47  
    48  	err := afero.Walk(fs, imageCacheDir, func(path string, info os.FileInfo, err error) error {
    49  		if info == nil {
    50  			return nil
    51  		}
    52  
    53  		if !strings.HasPrefix(path, imageCacheDir) {
    54  			return fmt.Errorf("Invalid state, walk outside of resource dir: %q", path)
    55  		}
    56  
    57  		if info.IsDir() {
    58  			f, err := fs.Open(path)
    59  			if err != nil {
    60  				return nil
    61  			}
    62  			defer f.Close()
    63  			_, err = f.Readdirnames(1)
    64  			if err == io.EOF {
    65  				// Empty dir.
    66  				s.Fs.Source.Remove(path)
    67  			}
    68  
    69  			return nil
    70  		}
    71  
    72  		inUse := isInUse(path)
    73  		if !inUse {
    74  			err := fs.Remove(path)
    75  			if err != nil && !os.IsNotExist(err) {
    76  				s.Log.ERROR.Printf("Failed to remove %q: %s", path, err)
    77  			} else {
    78  				counter++
    79  			}
    80  		}
    81  		return nil
    82  	})
    83  
    84  	return counter, err
    85  
    86  }