mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-03-03 15:02:52 +02:00
Afero is a package that lets you mock out a filesystem with an in-memory filesystem. It allows us to easily create the files required for a given test without worrying about a cleanup step or different tests tripping on eachother when run in parallel. Later on I'll standardise on using afero over the vanilla os package
224 lines
4.3 KiB
Go
224 lines
4.3 KiB
Go
package afero
|
|
|
|
import (
|
|
"os"
|
|
"regexp"
|
|
"syscall"
|
|
"time"
|
|
)
|
|
|
|
// The RegexpFs filters files (not directories) by regular expression. Only
|
|
// files matching the given regexp will be allowed, all others get a ENOENT error (
|
|
// "No such file or directory").
|
|
type RegexpFs struct {
|
|
re *regexp.Regexp
|
|
source Fs
|
|
}
|
|
|
|
func NewRegexpFs(source Fs, re *regexp.Regexp) Fs {
|
|
return &RegexpFs{source: source, re: re}
|
|
}
|
|
|
|
type RegexpFile struct {
|
|
f File
|
|
re *regexp.Regexp
|
|
}
|
|
|
|
func (r *RegexpFs) matchesName(name string) error {
|
|
if r.re == nil {
|
|
return nil
|
|
}
|
|
if r.re.MatchString(name) {
|
|
return nil
|
|
}
|
|
return syscall.ENOENT
|
|
}
|
|
|
|
func (r *RegexpFs) dirOrMatches(name string) error {
|
|
dir, err := IsDir(r.source, name)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if dir {
|
|
return nil
|
|
}
|
|
return r.matchesName(name)
|
|
}
|
|
|
|
func (r *RegexpFs) Chtimes(name string, a, m time.Time) error {
|
|
if err := r.dirOrMatches(name); err != nil {
|
|
return err
|
|
}
|
|
return r.source.Chtimes(name, a, m)
|
|
}
|
|
|
|
func (r *RegexpFs) Chmod(name string, mode os.FileMode) error {
|
|
if err := r.dirOrMatches(name); err != nil {
|
|
return err
|
|
}
|
|
return r.source.Chmod(name, mode)
|
|
}
|
|
|
|
func (r *RegexpFs) Chown(name string, uid, gid int) error {
|
|
if err := r.dirOrMatches(name); err != nil {
|
|
return err
|
|
}
|
|
return r.source.Chown(name, uid, gid)
|
|
}
|
|
|
|
func (r *RegexpFs) Name() string {
|
|
return "RegexpFs"
|
|
}
|
|
|
|
func (r *RegexpFs) Stat(name string) (os.FileInfo, error) {
|
|
if err := r.dirOrMatches(name); err != nil {
|
|
return nil, err
|
|
}
|
|
return r.source.Stat(name)
|
|
}
|
|
|
|
func (r *RegexpFs) Rename(oldname, newname string) error {
|
|
dir, err := IsDir(r.source, oldname)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if dir {
|
|
return nil
|
|
}
|
|
if err := r.matchesName(oldname); err != nil {
|
|
return err
|
|
}
|
|
if err := r.matchesName(newname); err != nil {
|
|
return err
|
|
}
|
|
return r.source.Rename(oldname, newname)
|
|
}
|
|
|
|
func (r *RegexpFs) RemoveAll(p string) error {
|
|
dir, err := IsDir(r.source, p)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !dir {
|
|
if err := r.matchesName(p); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return r.source.RemoveAll(p)
|
|
}
|
|
|
|
func (r *RegexpFs) Remove(name string) error {
|
|
if err := r.dirOrMatches(name); err != nil {
|
|
return err
|
|
}
|
|
return r.source.Remove(name)
|
|
}
|
|
|
|
func (r *RegexpFs) OpenFile(name string, flag int, perm os.FileMode) (File, error) {
|
|
if err := r.dirOrMatches(name); err != nil {
|
|
return nil, err
|
|
}
|
|
return r.source.OpenFile(name, flag, perm)
|
|
}
|
|
|
|
func (r *RegexpFs) Open(name string) (File, error) {
|
|
dir, err := IsDir(r.source, name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if !dir {
|
|
if err := r.matchesName(name); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
f, err := r.source.Open(name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &RegexpFile{f: f, re: r.re}, nil
|
|
}
|
|
|
|
func (r *RegexpFs) Mkdir(n string, p os.FileMode) error {
|
|
return r.source.Mkdir(n, p)
|
|
}
|
|
|
|
func (r *RegexpFs) MkdirAll(n string, p os.FileMode) error {
|
|
return r.source.MkdirAll(n, p)
|
|
}
|
|
|
|
func (r *RegexpFs) Create(name string) (File, error) {
|
|
if err := r.matchesName(name); err != nil {
|
|
return nil, err
|
|
}
|
|
return r.source.Create(name)
|
|
}
|
|
|
|
func (f *RegexpFile) Close() error {
|
|
return f.f.Close()
|
|
}
|
|
|
|
func (f *RegexpFile) Read(s []byte) (int, error) {
|
|
return f.f.Read(s)
|
|
}
|
|
|
|
func (f *RegexpFile) ReadAt(s []byte, o int64) (int, error) {
|
|
return f.f.ReadAt(s, o)
|
|
}
|
|
|
|
func (f *RegexpFile) Seek(o int64, w int) (int64, error) {
|
|
return f.f.Seek(o, w)
|
|
}
|
|
|
|
func (f *RegexpFile) Write(s []byte) (int, error) {
|
|
return f.f.Write(s)
|
|
}
|
|
|
|
func (f *RegexpFile) WriteAt(s []byte, o int64) (int, error) {
|
|
return f.f.WriteAt(s, o)
|
|
}
|
|
|
|
func (f *RegexpFile) Name() string {
|
|
return f.f.Name()
|
|
}
|
|
|
|
func (f *RegexpFile) Readdir(c int) (fi []os.FileInfo, err error) {
|
|
var rfi []os.FileInfo
|
|
rfi, err = f.f.Readdir(c)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, i := range rfi {
|
|
if i.IsDir() || f.re.MatchString(i.Name()) {
|
|
fi = append(fi, i)
|
|
}
|
|
}
|
|
return fi, nil
|
|
}
|
|
|
|
func (f *RegexpFile) Readdirnames(c int) (n []string, err error) {
|
|
fi, err := f.Readdir(c)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, s := range fi {
|
|
n = append(n, s.Name())
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
func (f *RegexpFile) Stat() (os.FileInfo, error) {
|
|
return f.f.Stat()
|
|
}
|
|
|
|
func (f *RegexpFile) Sync() error {
|
|
return f.f.Sync()
|
|
}
|
|
|
|
func (f *RegexpFile) Truncate(s int64) error {
|
|
return f.f.Truncate(s)
|
|
}
|
|
|
|
func (f *RegexpFile) WriteString(s string) (int, error) {
|
|
return f.f.WriteString(s)
|
|
}
|