183 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			183 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
	
package filesystem
 | 
						|
 | 
						|
import (
 | 
						|
	"io"
 | 
						|
	"io/fs"
 | 
						|
	"os"
 | 
						|
	"path/filepath"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
type fileStat struct {
 | 
						|
	name    string
 | 
						|
	size    int64
 | 
						|
	mode    fs.FileMode
 | 
						|
	modTime time.Time
 | 
						|
}
 | 
						|
 | 
						|
func (fs fileStat) Name() string       { return fs.name }
 | 
						|
func (fs fileStat) Size() int64        { return fs.size }
 | 
						|
func (fs fileStat) Mode() fs.FileMode  { return fs.mode }
 | 
						|
func (fs fileStat) ModTime() time.Time { return fs.modTime }
 | 
						|
func (fs fileStat) IsDir() bool        { return fs.mode.IsDir() }
 | 
						|
func (fs fileStat) Sys() any           { return nil }
 | 
						|
 | 
						|
type FileSystem struct {
 | 
						|
	ReadFile          func(string) ([]byte, error)
 | 
						|
	ReadDir           func(string) ([]fs.DirEntry, error)
 | 
						|
	DeleteFile        func(string) error
 | 
						|
	FileExists        func(string) (bool, error)
 | 
						|
	Glob              func(string) ([]string, error)
 | 
						|
	FileExistsAt      func(string) bool
 | 
						|
	DirectoryExistsAt func(string) bool
 | 
						|
	Dir               func(string) string
 | 
						|
	Stat              func(string) (os.FileInfo, error)
 | 
						|
	Getwd             func() (string, error)
 | 
						|
	Chdir             func(string) error
 | 
						|
	Abs               func(string) (string, error)
 | 
						|
	EvalSymlinks      func(string) (string, error)
 | 
						|
}
 | 
						|
 | 
						|
func DefaultFileSystem() *FileSystem {
 | 
						|
	dfs := FileSystem{
 | 
						|
		ReadDir:      os.ReadDir,
 | 
						|
		DeleteFile:   os.Remove,
 | 
						|
		Glob:         filepath.Glob,
 | 
						|
		Getwd:        os.Getwd,
 | 
						|
		Chdir:        os.Chdir,
 | 
						|
		EvalSymlinks: filepath.EvalSymlinks,
 | 
						|
		Dir:          filepath.Dir,
 | 
						|
	}
 | 
						|
 | 
						|
	dfs.Stat = dfs.stat
 | 
						|
	dfs.ReadFile = dfs.readFile
 | 
						|
	dfs.FileExistsAt = dfs.fileExistsAtDefault
 | 
						|
	dfs.DirectoryExistsAt = dfs.directoryExistsDefault
 | 
						|
	dfs.FileExists = dfs.fileExistsDefault
 | 
						|
	dfs.Abs = dfs.absDefault
 | 
						|
	return &dfs
 | 
						|
}
 | 
						|
 | 
						|
func FromFileSystem(params FileSystem) *FileSystem {
 | 
						|
	dfs := DefaultFileSystem()
 | 
						|
 | 
						|
	if params.ReadFile != nil {
 | 
						|
		dfs.ReadFile = params.ReadFile
 | 
						|
	}
 | 
						|
	if params.ReadDir != nil {
 | 
						|
		dfs.ReadDir = params.ReadDir
 | 
						|
	}
 | 
						|
	if params.DeleteFile != nil {
 | 
						|
		dfs.DeleteFile = params.DeleteFile
 | 
						|
	}
 | 
						|
	if params.FileExists != nil {
 | 
						|
		dfs.FileExists = params.FileExists
 | 
						|
	}
 | 
						|
	if params.Glob != nil {
 | 
						|
		dfs.Glob = params.Glob
 | 
						|
	}
 | 
						|
	if params.FileExistsAt != nil {
 | 
						|
		dfs.FileExistsAt = params.FileExistsAt
 | 
						|
	}
 | 
						|
	if params.DirectoryExistsAt != nil {
 | 
						|
		dfs.DirectoryExistsAt = params.DirectoryExistsAt
 | 
						|
	}
 | 
						|
	if params.Stat != nil {
 | 
						|
		dfs.Stat = params.Stat
 | 
						|
	}
 | 
						|
	if params.Getwd != nil {
 | 
						|
		dfs.Getwd = params.Getwd
 | 
						|
	}
 | 
						|
	if params.Chdir != nil {
 | 
						|
		dfs.Chdir = params.Chdir
 | 
						|
	}
 | 
						|
	if params.Abs != nil {
 | 
						|
		dfs.Abs = params.Abs
 | 
						|
	}
 | 
						|
	if params.EvalSymlinks != nil {
 | 
						|
		dfs.EvalSymlinks = params.EvalSymlinks
 | 
						|
	}
 | 
						|
	if params.Dir != nil {
 | 
						|
		dfs.Dir = params.Dir
 | 
						|
	}
 | 
						|
	return dfs
 | 
						|
}
 | 
						|
 | 
						|
func (filesystem *FileSystem) stat(name string) (os.FileInfo, error) {
 | 
						|
	if name == "-" {
 | 
						|
		return fileStat{mode: 0}, nil
 | 
						|
	}
 | 
						|
	return os.Stat(name)
 | 
						|
}
 | 
						|
 | 
						|
func (filesystem *FileSystem) readFile(name string) ([]byte, error) {
 | 
						|
	if name == "-" {
 | 
						|
		return io.ReadAll(os.Stdin)
 | 
						|
	}
 | 
						|
	return os.ReadFile(name)
 | 
						|
}
 | 
						|
 | 
						|
func (filesystem *FileSystem) fileExistsAtDefault(path string) bool {
 | 
						|
	path, err := filesystem.resolveSymlinks(path)
 | 
						|
	if err != nil {
 | 
						|
		return false
 | 
						|
	}
 | 
						|
	fileInfo, err := filesystem.Stat(path)
 | 
						|
	return err == nil && fileInfo.Mode().IsRegular()
 | 
						|
}
 | 
						|
 | 
						|
func (filesystem *FileSystem) fileExistsDefault(path string) (bool, error) {
 | 
						|
	path, err := filesystem.resolveSymlinks(path)
 | 
						|
	if err != nil {
 | 
						|
		if os.IsNotExist(err) {
 | 
						|
			return false, nil
 | 
						|
		}
 | 
						|
		return false, err
 | 
						|
	}
 | 
						|
	_, err = filesystem.Stat(path)
 | 
						|
	if err != nil {
 | 
						|
		if os.IsNotExist(err) {
 | 
						|
			return false, nil
 | 
						|
		}
 | 
						|
		return false, err
 | 
						|
	}
 | 
						|
	return true, nil
 | 
						|
}
 | 
						|
 | 
						|
func (filesystem *FileSystem) directoryExistsDefault(path string) bool {
 | 
						|
	path, err := filesystem.resolveSymlinks(path)
 | 
						|
	if err != nil {
 | 
						|
		return false
 | 
						|
	}
 | 
						|
	fileInfo, err := filesystem.Stat(path)
 | 
						|
	return err == nil && fileInfo.Mode().IsDir()
 | 
						|
}
 | 
						|
 | 
						|
func (filesystem *FileSystem) resolveSymlinks(path string) (string, error) {
 | 
						|
	if !filepath.IsAbs(path) && !filepath.IsLocal(path) {
 | 
						|
		basePath, err := filesystem.Getwd()
 | 
						|
		if err != nil {
 | 
						|
			return "", err
 | 
						|
		}
 | 
						|
 | 
						|
		basePath, err = filesystem.EvalSymlinks(basePath)
 | 
						|
		if err != nil {
 | 
						|
			return "", err
 | 
						|
		}
 | 
						|
		path, err := filesystem.EvalSymlinks(filepath.Join(basePath, path))
 | 
						|
		if err != nil {
 | 
						|
			return "", err
 | 
						|
		}
 | 
						|
		return path, nil
 | 
						|
	}
 | 
						|
	return path, nil
 | 
						|
}
 | 
						|
 | 
						|
func (filesystem *FileSystem) absDefault(path string) (string, error) {
 | 
						|
	path, err := filesystem.resolveSymlinks(path)
 | 
						|
	if err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
	return filepath.Abs(path)
 | 
						|
}
 |