github.com/graemephi/kahugo@v0.62.3-0.20211121071557-d78c0423784d/hugofs/filename_filter_fs.go (about) 1 // Copyright 2021 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 hugofs 15 16 import ( 17 "os" 18 "strings" 19 "syscall" 20 "time" 21 22 "github.com/gohugoio/hugo/hugofs/glob" 23 "github.com/spf13/afero" 24 ) 25 26 func newFilenameFilterFs(fs afero.Fs, base string, filter *glob.FilenameFilter) afero.Fs { 27 return &filenameFilterFs{ 28 fs: fs, 29 base: base, 30 filter: filter, 31 } 32 } 33 34 // filenameFilterFs is a filesystem that filters by filename. 35 type filenameFilterFs struct { 36 base string 37 fs afero.Fs 38 39 filter *glob.FilenameFilter 40 } 41 42 func (fs *filenameFilterFs) LstatIfPossible(name string) (os.FileInfo, bool, error) { 43 fi, b, err := fs.fs.(afero.Lstater).LstatIfPossible(name) 44 if err != nil { 45 return nil, false, err 46 } 47 if !fs.filter.Match(name, fi.IsDir()) { 48 return nil, false, os.ErrNotExist 49 } 50 return fi, b, nil 51 } 52 53 func (fs *filenameFilterFs) Open(name string) (afero.File, error) { 54 fi, err := fs.fs.Stat(name) 55 if err != nil { 56 return nil, err 57 } 58 59 if !fs.filter.Match(name, fi.IsDir()) { 60 return nil, os.ErrNotExist 61 } 62 63 f, err := fs.fs.Open(name) 64 if err != nil { 65 return nil, err 66 } 67 68 if !fi.IsDir() { 69 return f, nil 70 } 71 72 return &filenameFilterDir{ 73 File: f, 74 base: fs.base, 75 filter: fs.filter, 76 }, nil 77 } 78 79 func (fs *filenameFilterFs) OpenFile(name string, flag int, perm os.FileMode) (afero.File, error) { 80 return fs.Open(name) 81 } 82 83 func (fs *filenameFilterFs) Stat(name string) (os.FileInfo, error) { 84 fi, _, err := fs.LstatIfPossible(name) 85 return fi, err 86 } 87 88 func (fs *filenameFilterFs) getOpener(name string) func() (afero.File, error) { 89 return func() (afero.File, error) { 90 return fs.Open(name) 91 } 92 } 93 94 type filenameFilterDir struct { 95 afero.File 96 base string 97 filter *glob.FilenameFilter 98 } 99 100 func (f *filenameFilterDir) Readdir(count int) ([]os.FileInfo, error) { 101 fis, err := f.File.Readdir(-1) 102 if err != nil { 103 return nil, err 104 } 105 106 var result []os.FileInfo 107 for _, fi := range fis { 108 fim := fi.(FileMetaInfo) 109 if f.filter.Match(strings.TrimPrefix(fim.Meta().Filename, f.base), fim.IsDir()) { 110 result = append(result, fi) 111 } 112 } 113 114 return result, nil 115 } 116 117 func (f *filenameFilterDir) Readdirnames(count int) ([]string, error) { 118 dirsi, err := f.Readdir(count) 119 if err != nil { 120 return nil, err 121 } 122 123 dirs := make([]string, len(dirsi)) 124 for i, d := range dirsi { 125 dirs[i] = d.Name() 126 } 127 return dirs, nil 128 } 129 130 func (fs *filenameFilterFs) Chmod(n string, m os.FileMode) error { 131 return syscall.EPERM 132 } 133 134 func (fs *filenameFilterFs) Chtimes(n string, a, m time.Time) error { 135 return syscall.EPERM 136 } 137 138 func (fs *filenameFilterFs) Chown(n string, uid, gid int) error { 139 return syscall.EPERM 140 } 141 142 func (fs *filenameFilterFs) ReadDir(name string) ([]os.FileInfo, error) { 143 panic("not implemented") 144 } 145 146 func (fs *filenameFilterFs) Remove(n string) error { 147 return syscall.EPERM 148 } 149 150 func (fs *filenameFilterFs) RemoveAll(p string) error { 151 return syscall.EPERM 152 } 153 154 func (fs *filenameFilterFs) Rename(o, n string) error { 155 return syscall.EPERM 156 } 157 func (fs *filenameFilterFs) Create(n string) (afero.File, error) { 158 return nil, syscall.EPERM 159 } 160 func (fs *filenameFilterFs) Name() string { 161 return "FinameFilterFS" 162 } 163 164 func (fs *filenameFilterFs) Mkdir(n string, p os.FileMode) error { 165 return syscall.EPERM 166 } 167 168 func (fs *filenameFilterFs) MkdirAll(n string, p os.FileMode) error { 169 return syscall.EPERM 170 }