Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

memfs OpenFile does not work on directories #47

Open
progrium opened this issue Nov 16, 2017 · 2 comments
Open

memfs OpenFile does not work on directories #47

progrium opened this issue Nov 16, 2017 · 2 comments

Comments

@progrium
Copy link

progrium commented Nov 16, 2017

After finally getting a wrapper basically working, I run into an issue because memfs's OpenFile won't open directories. That's not how anything works.

I would strongly encourage you to replace all usage of go-billy with afero, as it fully and properly implements an os "compatible" filesystem abstraction. That said, thank you for your time and effort in this library (though more so with go-git).

@progrium
Copy link
Author

progrium commented Nov 16, 2017

I found a workaround for the wrapper, but I still think y'all should release yourself from this project.

package main

import (
	"errors"
	"io"
	"os"
	"time"

	"github.com/spf13/afero"
	billy "gopkg.in/src-d/go-billy.v3"
	"gopkg.in/src-d/go-billy.v3/memfs"
)

var ErrNotImplemented = errors.New("not implemented")

type billyToAferoFile struct {
	billy.File

	fs   billy.Filesystem
	path string
}

func (f *billyToAferoFile) WriteAt(p []byte, off int64) (n int, err error) {
	return 0, ErrNotImplemented
}

func (f *billyToAferoFile) Readdir(n int) ([]os.FileInfo, error) {
	// TODO: implement n
	return f.fs.ReadDir(f.path)
}

func (f *billyToAferoFile) Readdirnames(n int) ([]string, error) {
	// TODO: implement n
	files, err := f.fs.ReadDir(f.path)
	if err != nil {
		return nil, err
	}
	var names []string
	for _, info := range files {
		names = append(names, info.Name())
	}
	return names, nil
}

func (f *billyToAferoFile) Stat() (os.FileInfo, error) {
	return f.fs.Stat(f.path)
}

func (f *billyToAferoFile) Sync() error {
	return nil
}

func (f *billyToAferoFile) Truncate(size int64) error {
	return ErrNotImplemented
}

func (f *billyToAferoFile) WriteString(s string) (ret int, err error) {
	return io.WriteString(f, s)
}

type billyToAferoFs struct {
	billy.Filesystem
}

func (fs *billyToAferoFs) Name() string {
	return "billy.Filesystem"
}
func (fs *billyToAferoFs) RemoveAll(path string) error {
	return fs.Remove(path)
}
func (fs *billyToAferoFs) Mkdir(name string, perm os.FileMode) error {
	return fs.MkdirAll(name, perm)
}

func (fs *billyToAferoFs) Chmod(name string, mode os.FileMode) error {
	return nil
}

func (fs *billyToAferoFs) Chtimes(name string, atime time.Time, mtime time.Time) error {
	return nil
}

func (fs *billyToAferoFs) Create(name string) (afero.File, error) {
	f, err := fs.Filesystem.Create(name)
	return &billyToAferoFile{f, fs.Filesystem, name}, err
}

func (fs *billyToAferoFs) Open(name string) (afero.File, error) {
	info, _ := fs.Filesystem.Stat(name)
	if info.IsDir() {
		f, err := memfs.New().Create(name)
		return &billyToAferoFile{f, fs.Filesystem, name}, err
	}
	f, err := fs.Filesystem.Open(name)
	return &billyToAferoFile{f, fs.Filesystem, name}, err
}

func (fs *billyToAferoFs) OpenFile(name string, flag int, perm os.FileMode) (afero.File, error) {
	info, _ := fs.Filesystem.Stat(name)
	if info.IsDir() {
		f, err := memfs.New().Create(name)
		return &billyToAferoFile{f, fs.Filesystem, name}, err
	}
	f, err := fs.Filesystem.OpenFile(name, flag, perm)
	return &billyToAferoFile{f, fs.Filesystem, name}, err
}

@smola smola changed the title Broken memfs, broken library? memfs OpenFile does not work on directories Aug 1, 2018
@smola
Copy link
Contributor

smola commented Aug 1, 2018

@progrium Thanks for sharing the wrapper, that might be useful to others.

Contributions are welcome, so if anyone is willing to work on improving memfs, that will be welcome. I have changed the title of the issue accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants