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