github.com/MRtecno98/afero@v1.9.3/regexpfs.go (about) 1 package afero 2 3 import ( 4 "os" 5 "regexp" 6 "syscall" 7 "time" 8 ) 9 10 // The RegexpFs filters files (not directories) by regular expression. Only 11 // files matching the given regexp will be allowed, all others get a ENOENT error ( 12 // "No such file or directory"). 13 // 14 type RegexpFs struct { 15 re *regexp.Regexp 16 source Fs 17 } 18 19 func NewRegexpFs(source Fs, re *regexp.Regexp) Fs { 20 return &RegexpFs{source: source, re: re} 21 } 22 23 type RegexpFile struct { 24 f File 25 re *regexp.Regexp 26 } 27 28 func (r *RegexpFs) matchesName(name string) error { 29 if r.re == nil { 30 return nil 31 } 32 if r.re.MatchString(name) { 33 return nil 34 } 35 return syscall.ENOENT 36 } 37 38 func (r *RegexpFs) dirOrMatches(name string) error { 39 dir, err := IsDir(r.source, name) 40 if err != nil { 41 return err 42 } 43 if dir { 44 return nil 45 } 46 return r.matchesName(name) 47 } 48 49 func (r *RegexpFs) Chtimes(name string, a, m time.Time) error { 50 if err := r.dirOrMatches(name); err != nil { 51 return err 52 } 53 return r.source.Chtimes(name, a, m) 54 } 55 56 func (r *RegexpFs) Chmod(name string, mode os.FileMode) error { 57 if err := r.dirOrMatches(name); err != nil { 58 return err 59 } 60 return r.source.Chmod(name, mode) 61 } 62 63 func (r *RegexpFs) Chown(name string, uid, gid int) error { 64 if err := r.dirOrMatches(name); err != nil { 65 return err 66 } 67 return r.source.Chown(name, uid, gid) 68 } 69 70 func (r *RegexpFs) Name() string { 71 return "RegexpFs" 72 } 73 74 func (r *RegexpFs) Close() { 75 r.source.Close() 76 } 77 78 func (r *RegexpFs) Stat(name string) (os.FileInfo, error) { 79 if err := r.dirOrMatches(name); err != nil { 80 return nil, err 81 } 82 return r.source.Stat(name) 83 } 84 85 func (r *RegexpFs) Rename(oldname, newname string) error { 86 dir, err := IsDir(r.source, oldname) 87 if err != nil { 88 return err 89 } 90 if dir { 91 return nil 92 } 93 if err := r.matchesName(oldname); err != nil { 94 return err 95 } 96 if err := r.matchesName(newname); err != nil { 97 return err 98 } 99 return r.source.Rename(oldname, newname) 100 } 101 102 func (r *RegexpFs) RemoveAll(p string) error { 103 dir, err := IsDir(r.source, p) 104 if err != nil { 105 return err 106 } 107 if !dir { 108 if err := r.matchesName(p); err != nil { 109 return err 110 } 111 } 112 return r.source.RemoveAll(p) 113 } 114 115 func (r *RegexpFs) Remove(name string) error { 116 if err := r.dirOrMatches(name); err != nil { 117 return err 118 } 119 return r.source.Remove(name) 120 } 121 122 func (r *RegexpFs) OpenFile(name string, flag int, perm os.FileMode) (File, error) { 123 if err := r.dirOrMatches(name); err != nil { 124 return nil, err 125 } 126 return r.source.OpenFile(name, flag, perm) 127 } 128 129 func (r *RegexpFs) Open(name string) (File, error) { 130 dir, err := IsDir(r.source, name) 131 if err != nil { 132 return nil, err 133 } 134 if !dir { 135 if err := r.matchesName(name); err != nil { 136 return nil, err 137 } 138 } 139 f, err := r.source.Open(name) 140 if err != nil { 141 return nil, err 142 } 143 return &RegexpFile{f: f, re: r.re}, nil 144 } 145 146 func (r *RegexpFs) Mkdir(n string, p os.FileMode) error { 147 return r.source.Mkdir(n, p) 148 } 149 150 func (r *RegexpFs) MkdirAll(n string, p os.FileMode) error { 151 return r.source.MkdirAll(n, p) 152 } 153 154 func (r *RegexpFs) Create(name string) (File, error) { 155 if err := r.matchesName(name); err != nil { 156 return nil, err 157 } 158 return r.source.Create(name) 159 } 160 161 func (f *RegexpFile) Close() error { 162 return f.f.Close() 163 } 164 165 func (f *RegexpFile) Read(s []byte) (int, error) { 166 return f.f.Read(s) 167 } 168 169 func (f *RegexpFile) ReadAt(s []byte, o int64) (int, error) { 170 return f.f.ReadAt(s, o) 171 } 172 173 func (f *RegexpFile) Seek(o int64, w int) (int64, error) { 174 return f.f.Seek(o, w) 175 } 176 177 func (f *RegexpFile) Write(s []byte) (int, error) { 178 return f.f.Write(s) 179 } 180 181 func (f *RegexpFile) WriteAt(s []byte, o int64) (int, error) { 182 return f.f.WriteAt(s, o) 183 } 184 185 func (f *RegexpFile) Name() string { 186 return f.f.Name() 187 } 188 189 func (f *RegexpFile) Readdir(c int) (fi []os.FileInfo, err error) { 190 var rfi []os.FileInfo 191 rfi, err = f.f.Readdir(c) 192 if err != nil { 193 return nil, err 194 } 195 for _, i := range rfi { 196 if i.IsDir() || f.re.MatchString(i.Name()) { 197 fi = append(fi, i) 198 } 199 } 200 return fi, nil 201 } 202 203 func (f *RegexpFile) Readdirnames(c int) (n []string, err error) { 204 fi, err := f.Readdir(c) 205 if err != nil { 206 return nil, err 207 } 208 for _, s := range fi { 209 n = append(n, s.Name()) 210 } 211 return n, nil 212 } 213 214 func (f *RegexpFile) Stat() (os.FileInfo, error) { 215 return f.f.Stat() 216 } 217 218 func (f *RegexpFile) Sync() error { 219 return f.f.Sync() 220 } 221 222 func (f *RegexpFile) Truncate(s int64) error { 223 return f.f.Truncate(s) 224 } 225 226 func (f *RegexpFile) WriteString(s string) (int, error) { 227 return f.f.WriteString(s) 228 }