github.com/assistd/afero@v1.1.1/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) Name() string {
    64  	return "RegexpFs"
    65  }
    66  
    67  func (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  
    74  func (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  
    91  func (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  
   104  func (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  
   111  func (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  
   118  func (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  	return &RegexpFile{f: f, re: r.re}, nil
   130  }
   131  
   132  func (r *RegexpFs) Mkdir(n string, p os.FileMode) error {
   133  	return r.source.Mkdir(n, p)
   134  }
   135  
   136  func (r *RegexpFs) MkdirAll(n string, p os.FileMode) error {
   137  	return r.source.MkdirAll(n, p)
   138  }
   139  
   140  func (r *RegexpFs) Create(name string) (File, error) {
   141  	if err := r.matchesName(name); err != nil {
   142  		return nil, err
   143  	}
   144  	return r.source.Create(name)
   145  }
   146  
   147  func (f *RegexpFile) Close() error {
   148  	return f.f.Close()
   149  }
   150  
   151  func (f *RegexpFile) Read(s []byte) (int, error) {
   152  	return f.f.Read(s)
   153  }
   154  
   155  func (f *RegexpFile) ReadAt(s []byte, o int64) (int, error) {
   156  	return f.f.ReadAt(s, o)
   157  }
   158  
   159  func (f *RegexpFile) Seek(o int64, w int) (int64, error) {
   160  	return f.f.Seek(o, w)
   161  }
   162  
   163  func (f *RegexpFile) Write(s []byte) (int, error) {
   164  	return f.f.Write(s)
   165  }
   166  
   167  func (f *RegexpFile) WriteAt(s []byte, o int64) (int, error) {
   168  	return f.f.WriteAt(s, o)
   169  }
   170  
   171  func (f *RegexpFile) Name() string {
   172  	return f.f.Name()
   173  }
   174  
   175  func (f *RegexpFile) Readdir(c int) (fi []os.FileInfo, err error) {
   176  	var rfi []os.FileInfo
   177  	rfi, err = f.f.Readdir(c)
   178  	if err != nil {
   179  		return nil, err
   180  	}
   181  	for _, i := range rfi {
   182  		if i.IsDir() || f.re.MatchString(i.Name()) {
   183  			fi = append(fi, i)
   184  		}
   185  	}
   186  	return fi, nil
   187  }
   188  
   189  func (f *RegexpFile) Readdirnames(c int) (n []string, err error) {
   190  	fi, err := f.Readdir(c)
   191  	if err != nil {
   192  		return nil, err
   193  	}
   194  	for _, s := range fi {
   195  		n = append(n, s.Name())
   196  	}
   197  	return n, nil
   198  }
   199  
   200  func (f *RegexpFile) Stat() (os.FileInfo, error) {
   201  	return f.f.Stat()
   202  }
   203  
   204  func (f *RegexpFile) Sync() error {
   205  	return f.f.Sync()
   206  }
   207  
   208  func (f *RegexpFile) Truncate(s int64) error {
   209  	return f.f.Truncate(s)
   210  }
   211  
   212  func (f *RegexpFile) WriteString(s string) (int, error) {
   213  	return f.f.WriteString(s)
   214  }