github.com/gohugoio/hugo@v0.88.1/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 }