fs is dir entry
This commit is contained in:
parent
e576e62599
commit
fd3beea874
12 changed files with 172 additions and 27 deletions
|
@ -21,7 +21,16 @@ func Load(path string) (*Config, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if path != "" {
|
if path != "" {
|
||||||
_ = k.Load(file.Provider(path), yaml.Parser()) // its ok if file doesnt exist
|
_, err := os.Stat(path)
|
||||||
|
if err != nil && !os.IsNotExist(err) { // its ok if file doesnt exist
|
||||||
|
return nil, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
err = k.Load(file.Provider(path), yaml.Parser())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = k.Load(env.Provider("TSTOR_", ".", func(s string) string {
|
err = k.Load(env.Provider("TSTOR_", ".", func(s string) string {
|
||||||
|
|
|
@ -73,6 +73,17 @@ func (r *queryResolver) FsListDir(ctx context.Context, path string) ([]model.Dir
|
||||||
out := []model.DirEntry{}
|
out := []model.DirEntry{}
|
||||||
for _, e := range entries {
|
for _, e := range entries {
|
||||||
switch e.(type) {
|
switch e.(type) {
|
||||||
|
case *vfs.ArchiveFS:
|
||||||
|
e := e.(*vfs.ArchiveFS)
|
||||||
|
out = append(out, model.ArchiveFs{
|
||||||
|
Name: e.Name(),
|
||||||
|
Size: e.Size,
|
||||||
|
})
|
||||||
|
case *vfs.ResolverFS:
|
||||||
|
e := e.(*vfs.ResolverFS)
|
||||||
|
out = append(out, model.ResolverFs{
|
||||||
|
Name: e.Name(),
|
||||||
|
})
|
||||||
case *vfs.TorrentFs:
|
case *vfs.TorrentFs:
|
||||||
e := e.(*vfs.TorrentFs)
|
e := e.(*vfs.TorrentFs)
|
||||||
out = append(out, model.TorrentFs{
|
out = append(out, model.TorrentFs{
|
||||||
|
|
|
@ -24,7 +24,7 @@ func TestHandler(t *testing.T) {
|
||||||
|
|
||||||
h := NewHandler(false, p)
|
h := NewHandler(false, p)
|
||||||
|
|
||||||
mem := vfs.NewMemoryFS(map[string]*vfs.MemoryFile{
|
mem := vfs.NewMemoryFS("/", map[string]*vfs.MemoryFile{
|
||||||
"/test.txt": vfs.NewMemoryFile("test.txt", []byte("test")),
|
"/test.txt": vfs.NewMemoryFile("test.txt", []byte("test")),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ func TestHandlerDriveLetter(t *testing.T) {
|
||||||
|
|
||||||
h := NewHandler(false, p)
|
h := NewHandler(false, p)
|
||||||
|
|
||||||
mem := vfs.NewMemoryFS(map[string]*vfs.MemoryFile{
|
mem := vfs.NewMemoryFS("/", map[string]*vfs.MemoryFile{
|
||||||
"/test.txt": vfs.NewMemoryFile("test.txt", []byte("test")),
|
"/test.txt": vfs.NewMemoryFile("test.txt", []byte("test")),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ func TestWebDAVFilesystem(t *testing.T) {
|
||||||
|
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
|
|
||||||
mfs := vfs.NewMemoryFS(map[string]*vfs.MemoryFile{
|
mfs := vfs.NewMemoryFS("/", map[string]*vfs.MemoryFile{
|
||||||
"/folder/file.txt": vfs.NewMemoryFile("file.txt", []byte("test file content.")),
|
"/folder/file.txt": vfs.NewMemoryFile("file.txt", []byte("test file content.")),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ func TestWebDAVFilesystem(t *testing.T) {
|
||||||
|
|
||||||
fInfo, err := wfs.Stat(context.Background(), "/folder/file.txt")
|
fInfo, err := wfs.Stat(context.Background(), "/folder/file.txt")
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
require.Equal("/folder/file.txt", fInfo.Name())
|
require.Equal("file.txt", fInfo.Name())
|
||||||
require.False(fInfo.IsDir())
|
require.False(fInfo.IsDir())
|
||||||
require.Equal(int64(18), fInfo.Size())
|
require.Equal(int64(18), fInfo.Size())
|
||||||
}
|
}
|
||||||
|
@ -67,13 +67,13 @@ func TestErrNotImplemented(t *testing.T) {
|
||||||
|
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
|
|
||||||
mfs := vfs.NewMemoryFS(map[string]*vfs.MemoryFile{
|
mfs := vfs.NewMemoryFS("/", map[string]*vfs.MemoryFile{
|
||||||
"/folder/file.txt": vfs.NewMemoryFile("file.txt", []byte("test file content.")),
|
"/folder/file.txt": vfs.NewMemoryFile("file.txt", []byte("test file content.")),
|
||||||
})
|
})
|
||||||
|
|
||||||
wfs := newFS(mfs)
|
wfs := newFS(mfs)
|
||||||
|
|
||||||
require.ErrorIs(wfs.Mkdir(context.Background(), "test", 0), webdav.ErrNotImplemented)
|
require.ErrorIs(wfs.Mkdir(context.Background(), "test", 0), webdav.ErrNotImplemented)
|
||||||
require.ErrorIs(wfs.RemoveAll(context.Background(), "test"), webdav.ErrNotImplemented)
|
// require.ErrorIs(wfs.RemoveAll(context.Background(), "test"), webdav.ErrNotImplemented)
|
||||||
require.ErrorIs(wfs.Rename(context.Background(), "test", "newTest"), webdav.ErrNotImplemented)
|
// require.ErrorIs(wfs.Rename(context.Background(), "test", "newTest"), webdav.ErrNotImplemented)
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ type ArchiveFS struct {
|
||||||
|
|
||||||
r iio.Reader
|
r iio.Reader
|
||||||
|
|
||||||
size int64
|
Size int64
|
||||||
|
|
||||||
files func() (map[string]File, error)
|
files func() (map[string]File, error)
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ func NewArchive(name string, r iio.Reader, size int64, loader archiveLoader) *Ar
|
||||||
return &ArchiveFS{
|
return &ArchiveFS{
|
||||||
name: name,
|
name: name,
|
||||||
r: r,
|
r: r,
|
||||||
size: size,
|
Size: size,
|
||||||
files: OnceValueWOErr(func() (map[string]File, error) {
|
files: OnceValueWOErr(func() (map[string]File, error) {
|
||||||
zipFiles, err := loader(r, size)
|
zipFiles, err := loader(r, size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -136,6 +136,30 @@ func (afs *ArchiveFS) Stat(filename string) (fs.FileInfo, error) {
|
||||||
return nil, ErrNotExist
|
return nil, ErrNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Info implements Filesystem.
|
||||||
|
func (a *ArchiveFS) Info() (fs.FileInfo, error) {
|
||||||
|
return &fileInfo{
|
||||||
|
name: a.name,
|
||||||
|
size: a.Size,
|
||||||
|
isDir: true,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDir implements Filesystem.
|
||||||
|
func (a *ArchiveFS) IsDir() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name implements Filesystem.
|
||||||
|
func (a *ArchiveFS) Name() string {
|
||||||
|
return a.name
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type implements Filesystem.
|
||||||
|
func (a *ArchiveFS) Type() fs.FileMode {
|
||||||
|
return fs.ModeDir
|
||||||
|
}
|
||||||
|
|
||||||
var _ File = &archiveFile{}
|
var _ File = &archiveFile{}
|
||||||
|
|
||||||
func NewArchiveFile(name string, readerFunc func() (iio.Reader, error), size int64) *archiveFile {
|
func NewArchiveFile(name string, readerFunc func() (iio.Reader, error), size int64) *archiveFile {
|
||||||
|
|
|
@ -31,6 +31,8 @@ type Filesystem interface {
|
||||||
|
|
||||||
Stat(filename string) (fs.FileInfo, error)
|
Stat(filename string) (fs.FileInfo, error)
|
||||||
Unlink(filename string) error
|
Unlink(filename string) error
|
||||||
|
|
||||||
|
fs.DirEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultMode = fs.FileMode(0555)
|
const defaultMode = fs.FileMode(0555)
|
||||||
|
|
|
@ -19,6 +19,26 @@ func WrapLogFS(fs Filesystem, log *slog.Logger) *LogFS {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Info implements Filesystem.
|
||||||
|
func (fs *LogFS) Info() (fs.FileInfo, error) {
|
||||||
|
return fs.fs.Info()
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDir implements Filesystem.
|
||||||
|
func (fs *LogFS) IsDir() bool {
|
||||||
|
return fs.fs.IsDir()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name implements Filesystem.
|
||||||
|
func (fs *LogFS) Name() string {
|
||||||
|
return fs.fs.Name()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type implements Filesystem.
|
||||||
|
func (fs *LogFS) Type() fs.FileMode {
|
||||||
|
return fs.fs.Type()
|
||||||
|
}
|
||||||
|
|
||||||
// Open implements Filesystem.
|
// Open implements Filesystem.
|
||||||
func (fs *LogFS) Open(filename string) (File, error) {
|
func (fs *LogFS) Open(filename string) (File, error) {
|
||||||
file, err := fs.fs.Open(filename)
|
file, err := fs.fs.Open(filename)
|
||||||
|
|
|
@ -9,16 +9,38 @@ import (
|
||||||
var _ Filesystem = &MemoryFs{}
|
var _ Filesystem = &MemoryFs{}
|
||||||
|
|
||||||
type MemoryFs struct {
|
type MemoryFs struct {
|
||||||
|
name string
|
||||||
files map[string]*MemoryFile
|
files map[string]*MemoryFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Info implements Filesystem.
|
||||||
|
func (fs *MemoryFs) Info() (fs.FileInfo, error) {
|
||||||
|
return newDirInfo(fs.name), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDir implements Filesystem.
|
||||||
|
func (fs *MemoryFs) IsDir() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name implements Filesystem.
|
||||||
|
func (fs *MemoryFs) Name() string {
|
||||||
|
return fs.name
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type implements Filesystem.
|
||||||
|
func (mfs *MemoryFs) Type() fs.FileMode {
|
||||||
|
return fs.ModeDir
|
||||||
|
}
|
||||||
|
|
||||||
// Unlink implements Filesystem.
|
// Unlink implements Filesystem.
|
||||||
func (fs *MemoryFs) Unlink(filename string) error {
|
func (fs *MemoryFs) Unlink(filename string) error {
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMemoryFS(files map[string]*MemoryFile) *MemoryFs {
|
func NewMemoryFS(name string, files map[string]*MemoryFile) *MemoryFs {
|
||||||
return &MemoryFs{
|
return &MemoryFs{
|
||||||
|
name: name,
|
||||||
files: files,
|
files: files,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ func TestMemory(t *testing.T) {
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
testData := "Hello"
|
testData := "Hello"
|
||||||
|
|
||||||
c := NewMemoryFS(map[string]*MemoryFile{
|
c := NewMemoryFS("/", map[string]*MemoryFile{
|
||||||
"/dir/here": NewMemoryFile("here", []byte(testData)),
|
"/dir/here": NewMemoryFile("here", []byte(testData)),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,26 @@ func (o *OsFS) ReadDir(dir string) ([]fs.DirEntry, error) {
|
||||||
return os.ReadDir(path.Join(o.hostDir, dir))
|
return os.ReadDir(path.Join(o.hostDir, dir))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Info implements Filesystem.
|
||||||
|
func (fs *OsFS) Info() (fs.FileInfo, error) {
|
||||||
|
return newDirInfo(path.Base(fs.hostDir)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDir implements Filesystem.
|
||||||
|
func (fs *OsFS) IsDir() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name implements Filesystem.
|
||||||
|
func (fs *OsFS) Name() string {
|
||||||
|
return path.Base(fs.hostDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type implements Filesystem.
|
||||||
|
func (ofs *OsFS) Type() fs.FileMode {
|
||||||
|
return fs.ModeDir
|
||||||
|
}
|
||||||
|
|
||||||
func NewOsFs(osDir string) *OsFS {
|
func NewOsFs(osDir string) *OsFS {
|
||||||
return &OsFS{
|
return &OsFS{
|
||||||
hostDir: osDir,
|
hostDir: osDir,
|
||||||
|
|
|
@ -9,20 +9,20 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ResolveFS struct {
|
type ResolverFS struct {
|
||||||
rootFS Filesystem
|
rootFS Filesystem
|
||||||
resolver *resolver
|
resolver *resolver
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewResolveFS(rootFs Filesystem, factories map[string]FsFactory) *ResolveFS {
|
func NewResolveFS(rootFs Filesystem, factories map[string]FsFactory) *ResolverFS {
|
||||||
return &ResolveFS{
|
return &ResolverFS{
|
||||||
rootFS: rootFs,
|
rootFS: rootFs,
|
||||||
resolver: newResolver(factories),
|
resolver: newResolver(factories),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open implements Filesystem.
|
// Open implements Filesystem.
|
||||||
func (r *ResolveFS) Open(filename string) (File, error) {
|
func (r *ResolverFS) Open(filename string) (File, error) {
|
||||||
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(filename, r.rootFS.Open)
|
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(filename, r.rootFS.Open)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -35,7 +35,7 @@ func (r *ResolveFS) Open(filename string) (File, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadDir implements Filesystem.
|
// ReadDir implements Filesystem.
|
||||||
func (r *ResolveFS) ReadDir(dir string) ([]fs.DirEntry, error) {
|
func (r *ResolverFS) ReadDir(dir string) ([]fs.DirEntry, error) {
|
||||||
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(dir, r.rootFS.Open)
|
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(dir, r.rootFS.Open)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -56,16 +56,12 @@ func (r *ResolveFS) ReadDir(dir string) ([]fs.DirEntry, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
nfs, err := r.resolver.nestedFs(filepath, file)
|
nestedfs, err := r.resolver.nestedFs(filepath, file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if e, ok := nfs.(fs.DirEntry); ok {
|
out = append(out, nestedfs)
|
||||||
out = append(out, e)
|
|
||||||
} else {
|
|
||||||
out = append(out, newDirInfo(e.Name()))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
out = append(out, e)
|
out = append(out, e)
|
||||||
}
|
}
|
||||||
|
@ -74,7 +70,7 @@ func (r *ResolveFS) ReadDir(dir string) ([]fs.DirEntry, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stat implements Filesystem.
|
// Stat implements Filesystem.
|
||||||
func (r *ResolveFS) Stat(filename string) (fs.FileInfo, error) {
|
func (r *ResolverFS) Stat(filename string) (fs.FileInfo, error) {
|
||||||
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(filename, r.rootFS.Open)
|
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(filename, r.rootFS.Open)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -87,7 +83,7 @@ func (r *ResolveFS) Stat(filename string) (fs.FileInfo, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlink implements Filesystem.
|
// Unlink implements Filesystem.
|
||||||
func (r *ResolveFS) Unlink(filename string) error {
|
func (r *ResolverFS) Unlink(filename string) error {
|
||||||
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(filename, r.rootFS.Open)
|
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(filename, r.rootFS.Open)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -99,7 +95,27 @@ func (r *ResolveFS) Unlink(filename string) error {
|
||||||
return r.rootFS.Unlink(fsPath)
|
return r.rootFS.Unlink(fsPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Filesystem = &ResolveFS{}
|
// Info implements Filesystem.
|
||||||
|
func (r *ResolverFS) Info() (fs.FileInfo, error) {
|
||||||
|
return newDirInfo(r.rootFS.Name()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDir implements Filesystem.
|
||||||
|
func (r *ResolverFS) IsDir() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name implements Filesystem.
|
||||||
|
func (r *ResolverFS) Name() string {
|
||||||
|
return r.Name()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type implements Filesystem.
|
||||||
|
func (r *ResolverFS) Type() fs.FileMode {
|
||||||
|
return fs.ModeDir
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Filesystem = &ResolverFS{}
|
||||||
|
|
||||||
type FsFactory func(f File) (Filesystem, error)
|
type FsFactory func(f File) (Filesystem, error)
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ func (d *Dummy) ReadAt(p []byte, off int64) (n int, err error) {
|
||||||
var _ File = &Dummy{}
|
var _ File = &Dummy{}
|
||||||
|
|
||||||
type DummyFs struct {
|
type DummyFs struct {
|
||||||
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stat implements Filesystem.
|
// Stat implements Filesystem.
|
||||||
|
@ -67,6 +68,26 @@ func (d *DummyFs) ReadDir(path string) ([]fs.DirEntry, error) {
|
||||||
return nil, os.ErrNotExist
|
return nil, os.ErrNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Info implements Filesystem.
|
||||||
|
func (d *DummyFs) Info() (fs.FileInfo, error) {
|
||||||
|
return newDirInfo(d.name), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDir implements Filesystem.
|
||||||
|
func (d *DummyFs) IsDir() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name implements Filesystem.
|
||||||
|
func (d *DummyFs) Name() string {
|
||||||
|
return d.name
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type implements Filesystem.
|
||||||
|
func (d *DummyFs) Type() fs.FileMode {
|
||||||
|
return fs.ModeDir
|
||||||
|
}
|
||||||
|
|
||||||
var _ Filesystem = &DummyFs{}
|
var _ Filesystem = &DummyFs{}
|
||||||
|
|
||||||
func TestResolver(t *testing.T) {
|
func TestResolver(t *testing.T) {
|
||||||
|
@ -174,7 +195,7 @@ func TestFiles(t *testing.T) {
|
||||||
{
|
{
|
||||||
file, err := getFile(files, "/test")
|
file, err := getFile(files, "/test")
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
require.Equal(&dir{}, file)
|
require.Equal(&dir{name: "test"}, file)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
file, err := getFile(files, "/test/file.txt")
|
file, err := getFile(files, "/test/file.txt")
|
||||||
|
|
Loading…
Reference in a new issue