helmfile/pkg/filesystem/fs.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)
}