1package afero 2 3import ( 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// 14type RegexpFs struct { 15 re *regexp.Regexp 16 source Fs 17} 18 19func NewRegexpFs(source Fs, re *regexp.Regexp) Fs { 20 return &RegexpFs{source: source, re: re} 21} 22 23type RegexpFile struct { 24 f File 25 re *regexp.Regexp 26} 27 28func (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 38func (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 49func (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 56func (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 63func (r *RegexpFs) Name() string { 64 return "RegexpFs" 65} 66 67func (r *RegexpFs) Stat(name string) (os.FileInfo, error) { 68 if err := r.dirOrMatches(name); err != nil { 69 return nil, err 70 } 71 return r.source.Stat(name) 72} 73 74func (r *RegexpFs) Rename(oldname, newname string) error { 75 dir, err := IsDir(r.source, oldname) 76 if err != nil { 77 return err 78 } 79 if dir { 80 return nil 81 } 82 if err := r.matchesName(oldname); err != nil { 83 return err 84 } 85 if err := r.matchesName(newname); err != nil { 86 return err 87 } 88 return r.source.Rename(oldname, newname) 89} 90 91func (r *RegexpFs) RemoveAll(p string) error { 92 dir, err := IsDir(r.source, p) 93 if err != nil { 94 return err 95 } 96 if !dir { 97 if err := r.matchesName(p); err != nil { 98 return err 99 } 100 } 101 return r.source.RemoveAll(p) 102} 103 104func (r *RegexpFs) Remove(name string) error { 105 if err := r.dirOrMatches(name); err != nil { 106 return err 107 } 108 return r.source.Remove(name) 109} 110 111func (r *RegexpFs) OpenFile(name string, flag int, perm os.FileMode) (File, error) { 112 if err := r.dirOrMatches(name); err != nil { 113 return nil, err 114 } 115 return r.source.OpenFile(name, flag, perm) 116} 117 118func (r *RegexpFs) Open(name string) (File, error) { 119 dir, err := IsDir(r.source, name) 120 if err != nil { 121 return nil, err 122 } 123 if !dir { 124 if err := r.matchesName(name); err != nil { 125 return nil, err 126 } 127 } 128 f, err := r.source.Open(name) 129 if err != nil { 130 return nil, err 131 } 132 return &RegexpFile{f: f, re: r.re}, nil 133} 134 135func (r *RegexpFs) Mkdir(n string, p os.FileMode) error { 136 return r.source.Mkdir(n, p) 137} 138 139func (r *RegexpFs) MkdirAll(n string, p os.FileMode) error { 140 return r.source.MkdirAll(n, p) 141} 142 143func (r *RegexpFs) Create(name string) (File, error) { 144 if err := r.matchesName(name); err != nil { 145 return nil, err 146 } 147 return r.source.Create(name) 148} 149 150func (f *RegexpFile) Close() error { 151 return f.f.Close() 152} 153 154func (f *RegexpFile) Read(s []byte) (int, error) { 155 return f.f.Read(s) 156} 157 158func (f *RegexpFile) ReadAt(s []byte, o int64) (int, error) { 159 return f.f.ReadAt(s, o) 160} 161 162func (f *RegexpFile) Seek(o int64, w int) (int64, error) { 163 return f.f.Seek(o, w) 164} 165 166func (f *RegexpFile) Write(s []byte) (int, error) { 167 return f.f.Write(s) 168} 169 170func (f *RegexpFile) WriteAt(s []byte, o int64) (int, error) { 171 return f.f.WriteAt(s, o) 172} 173 174func (f *RegexpFile) Name() string { 175 return f.f.Name() 176} 177 178func (f *RegexpFile) Readdir(c int) (fi []os.FileInfo, err error) { 179 var rfi []os.FileInfo 180 rfi, err = f.f.Readdir(c) 181 if err != nil { 182 return nil, err 183 } 184 for _, i := range rfi { 185 if i.IsDir() || f.re.MatchString(i.Name()) { 186 fi = append(fi, i) 187 } 188 } 189 return fi, nil 190} 191 192func (f *RegexpFile) Readdirnames(c int) (n []string, err error) { 193 fi, err := f.Readdir(c) 194 if err != nil { 195 return nil, err 196 } 197 for _, s := range fi { 198 n = append(n, s.Name()) 199 } 200 return n, nil 201} 202 203func (f *RegexpFile) Stat() (os.FileInfo, error) { 204 return f.f.Stat() 205} 206 207func (f *RegexpFile) Sync() error { 208 return f.f.Sync() 209} 210 211func (f *RegexpFile) Truncate(s int64) error { 212 return f.f.Truncate(s) 213} 214 215func (f *RegexpFile) WriteString(s string) (int, error) { 216 return f.f.WriteString(s) 217} 218