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 }