github.com/kovansky/hugo@v0.92.3-0.20220224232819-63076e4ff19f/source/filesystem.go (about)

     1  // Copyright 2016 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 source
    15  
    16  import (
    17  	"path/filepath"
    18  	"sync"
    19  
    20  	"github.com/pkg/errors"
    21  
    22  	"github.com/gohugoio/hugo/hugofs"
    23  )
    24  
    25  // Filesystem represents a source filesystem.
    26  type Filesystem struct {
    27  	files        []File
    28  	filesInit    sync.Once
    29  	filesInitErr error
    30  
    31  	Base string
    32  
    33  	fi hugofs.FileMetaInfo
    34  
    35  	SourceSpec
    36  }
    37  
    38  // NewFilesystem returns a new filesytem for a given source spec.
    39  func (sp SourceSpec) NewFilesystem(base string) *Filesystem {
    40  	return &Filesystem{SourceSpec: sp, Base: base}
    41  }
    42  
    43  func (sp SourceSpec) NewFilesystemFromFileMetaInfo(fi hugofs.FileMetaInfo) *Filesystem {
    44  	return &Filesystem{SourceSpec: sp, fi: fi}
    45  }
    46  
    47  // Files returns a slice of readable files.
    48  func (f *Filesystem) Files() ([]File, error) {
    49  	f.filesInit.Do(func() {
    50  		err := f.captureFiles()
    51  		if err != nil {
    52  			f.filesInitErr = errors.Wrap(err, "capture files")
    53  		}
    54  	})
    55  	return f.files, f.filesInitErr
    56  }
    57  
    58  // add populates a file in the Filesystem.files
    59  func (f *Filesystem) add(name string, fi hugofs.FileMetaInfo) (err error) {
    60  	var file File
    61  
    62  	file, err = f.SourceSpec.NewFileInfo(fi)
    63  	if err != nil {
    64  		return err
    65  	}
    66  
    67  	f.files = append(f.files, file)
    68  
    69  	return err
    70  }
    71  
    72  func (f *Filesystem) captureFiles() error {
    73  	walker := func(path string, fi hugofs.FileMetaInfo, err error) error {
    74  		if err != nil {
    75  			return err
    76  		}
    77  
    78  		if fi.IsDir() {
    79  			return nil
    80  		}
    81  
    82  		meta := fi.Meta()
    83  		filename := meta.Filename
    84  
    85  		b, err := f.shouldRead(filename, fi)
    86  		if err != nil {
    87  			return err
    88  		}
    89  
    90  		if b {
    91  			err = f.add(filename, fi)
    92  		}
    93  
    94  		return err
    95  	}
    96  
    97  	w := hugofs.NewWalkway(hugofs.WalkwayConfig{
    98  		Fs:     f.SourceFs,
    99  		Info:   f.fi,
   100  		Root:   f.Base,
   101  		WalkFn: walker,
   102  	})
   103  
   104  	return w.Walk()
   105  }
   106  
   107  func (f *Filesystem) shouldRead(filename string, fi hugofs.FileMetaInfo) (bool, error) {
   108  	ignore := f.SourceSpec.IgnoreFile(fi.Meta().Filename)
   109  
   110  	if fi.IsDir() {
   111  		if ignore {
   112  			return false, filepath.SkipDir
   113  		}
   114  		return false, nil
   115  	}
   116  
   117  	if ignore {
   118  		return false, nil
   119  	}
   120  
   121  	return true, nil
   122  }