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  }