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