linuxkit/pkg/metadata/vendor/github.com/diskfs/go-diskfs/filesystem/compatibility.go
Avi Deitcher 3aeac872a0 update pkg/metadata with better logging
Signed-off-by: Avi Deitcher <avi@deitcher.net>
2023-06-13 12:10:48 +03:00

117 lines
2.4 KiB
Go
Vendored

package filesystem
import (
"io/fs"
"os"
"path"
"time"
)
type fsCompatible struct {
fs FileSystem
}
type fsFileWrapper struct {
File
stat os.FileInfo
}
type fakeRootDir struct{}
func (d *fakeRootDir) Name() string { return "/" }
func (d *fakeRootDir) Size() int64 { return 0 }
func (d *fakeRootDir) Mode() fs.FileMode { return 0 }
func (d *fakeRootDir) ModTime() time.Time { return time.Now() }
func (d *fakeRootDir) IsDir() bool { return true }
func (d *fakeRootDir) Sys() any { return nil }
type fsDirWrapper struct {
name string
compat *fsCompatible
stat os.FileInfo
}
func (f *fsDirWrapper) Close() error {
return nil
}
func (f *fsDirWrapper) Read([]byte) (int, error) {
return 0, fs.ErrInvalid
}
func (f *fsDirWrapper) ReadDir(n int) ([]fs.DirEntry, error) {
entries, err := f.compat.ReadDir(f.name)
if err != nil {
return nil, err
}
if n < 0 || n >= len(entries) {
n = len(entries)
}
return entries[:n], nil
}
func (f *fsDirWrapper) Stat() (fs.FileInfo, error) {
return f.stat, nil
}
func (f *fsFileWrapper) Stat() (fs.FileInfo, error) {
return f.stat, nil
}
// Converts the relative path name to an absolute one
func absoluteName(name string) string {
if name == "." {
name = "/"
}
if name[0] != '/' {
name = "/" + name
}
return name
}
func (f *fsCompatible) Open(name string) (fs.File, error) {
var stat os.FileInfo
name = absoluteName(name)
if name == "/" {
return &fsDirWrapper{name: name, compat: f, stat: &fakeRootDir{}}, nil
}
dirname := path.Dir(name)
if info, err := f.fs.ReadDir(dirname); err == nil {
for i := range info {
if info[i].Name() == path.Base(name) {
stat = info[i]
break
}
}
}
if stat == nil {
return nil, fs.ErrNotExist
}
if stat.IsDir() {
return &fsDirWrapper{name: name, compat: f, stat: stat}, nil
}
file, err := f.fs.OpenFile(name, os.O_RDONLY)
if err != nil {
return nil, err
}
return &fsFileWrapper{File: file, stat: stat}, nil
}
func (f *fsCompatible) ReadDir(name string) ([]fs.DirEntry, error) {
entries, err := f.fs.ReadDir(name)
if err != nil {
return nil, err
}
direntries := make([]fs.DirEntry, len(entries))
for i := range entries {
direntries[i] = fs.FileInfoToDirEntry(entries[i])
}
return direntries, nil
}
// FS converts a diskfs FileSystem to a fs.FS for compatibility with
// other utilities
func FS(f FileSystem) fs.ReadDirFS {
return &fsCompatible{f}
}