Skip to content

Commit

Permalink
add MkdirAll
Browse files Browse the repository at this point in the history
  • Loading branch information
smola committed Feb 20, 2017
1 parent 9c1722d commit 8209194
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 8 deletions.
2 changes: 2 additions & 0 deletions fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ var (
// * Get a temporal file.
// * Rename files.
// * Remove files.
// * Create directories.
// * Join parts of path.
// * Obtain a filesystem starting on a subdirectory in the current filesystem.
// * Get the base path for the filesystem.
Expand All @@ -35,6 +36,7 @@ type Filesystem interface {
TempFile(dir, prefix string) (File, error)
Rename(from, to string) error
Remove(filename string) error
MkdirAll(filename string, perm os.FileMode) error
Join(elem ...string) string
Dir(path string) Filesystem
Base() string
Expand Down
38 changes: 32 additions & 6 deletions memfs/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,19 @@ func (fs *Memory) OpenFile(filename string, flag int, perm os.FileMode) (billy.F
fullpath := fs.Join(fs.base, filename)
f, ok := fs.s.files[fullpath]

if !ok && !isCreate(flag) {
return nil, os.ErrNotExist
}
if !ok {
if !isCreate(flag) {
return nil, os.ErrNotExist
}

if f == nil {
fs.s.files[fullpath] = newFile(fs.base, fullpath, flag)
return fs.s.files[fullpath], nil
}

if f.isDir {
return nil, fmt.Errorf("cannot open directory: %s", filename)
}

n := newFile(fs.base, fullpath, flag)
n.content = f.content

Expand All @@ -73,12 +77,13 @@ func (fs *Memory) OpenFile(filename string, flag int, perm os.FileMode) (billy.F
func (fs *Memory) Stat(filename string) (billy.FileInfo, error) {
fullpath := fs.Join(fs.base, filename)

if _, ok := fs.s.files[fullpath]; ok {
f, ok := fs.s.files[fullpath]
if ok && !f.isDir {
return newFileInfo(fs.base, fullpath, fs.s.files[fullpath].content.Len()), nil
}

info, err := fs.ReadDir(fullpath)
if err == nil && len(info) != 0 {
if err == nil && len(info) != 0 || f != nil && f.isDir {
fi := newFileInfo(fs.base, fullpath, len(info))
fi.isDir = true
return fi, nil
Expand All @@ -101,6 +106,10 @@ func (fs *Memory) ReadDir(base string) (entries []billy.FileInfo, err error) {
parts := strings.Split(fullpath, string(separator))

if len(parts) == 1 {
if f.isDir {
entries = append(entries, &fileInfo{name: parts[0], isDir: true})
}

entries = append(entries, &fileInfo{name: parts[0], size: f.content.Len()})
continue
}
Expand All @@ -116,6 +125,22 @@ func (fs *Memory) ReadDir(base string) (entries []billy.FileInfo, err error) {
return
}

// MkdirAll creates a directory.
func (fs *Memory) MkdirAll(path string, perm os.FileMode) error {
fullpath := fs.Join(fs.base, path)
f, ok := fs.s.files[fullpath]
if ok {
if !f.isDir {
return fmt.Errorf("%s is a file", path)
}

return nil
}

fs.s.files[fullpath] = &file{isDir: true}
return nil
}

var maxTempFiles = 1024 * 4

// TempFile creates a new temporary file.
Expand Down Expand Up @@ -207,6 +232,7 @@ type file struct {
content *content
position int64
flag int
isDir bool
}

func newFile(base, fullpath string, flag int) *file {
Expand Down
15 changes: 13 additions & 2 deletions osfs/os.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import (
"srcd.works/go-billy.v1"
)

const (
defaultDirectoryMode = 0755
defaultCreateMode = 0666
)

// OS is a filesystem based on the os filesystem
type OS struct {
base string
Expand All @@ -25,7 +30,7 @@ func New(baseDir string) *OS {
// Create creates a file and opens it with standard permissions
// and modes O_RDWR, O_CREATE and O_TRUNC.
func (fs *OS) Create(filename string) (billy.File, error) {
return fs.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
return fs.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, defaultCreateMode)
}

// OpenFile is equivalent to standard os.OpenFile.
Expand Down Expand Up @@ -55,7 +60,7 @@ func (fs *OS) OpenFile(filename string, flag int, perm os.FileMode) (billy.File,
func (fs *OS) createDir(fullpath string) error {
dir := filepath.Dir(fullpath)
if dir != "." {
if err := os.MkdirAll(dir, 0755); err != nil {
if err := os.MkdirAll(dir, defaultDirectoryMode); err != nil {
return err
}
}
Expand Down Expand Up @@ -93,6 +98,12 @@ func (fs *OS) Rename(from, to string) error {
return os.Rename(from, to)
}

// MkdirAll creates a directory.
func (fs *OS) MkdirAll(path string, perm os.FileMode) error {
fullpath := fs.Join(fs.base, path)
return os.MkdirAll(fullpath, defaultDirectoryMode)
}

// Open opens a file in read-only mode.
func (fs *OS) Open(filename string) (billy.File, error) {
return fs.OpenFile(filename, os.O_RDONLY, 0)
Expand Down
65 changes: 65 additions & 0 deletions test/fs_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,14 @@ func (s *FilesystemSuite) TestRemoveAllNonExistent(c *C) {
c.Assert(RemoveAll(s.Fs, "non-existent"), IsNil)
}

func (s *FilesystemSuite) TestRemoveAllEmptyDir(c *C) {
c.Assert(s.Fs.MkdirAll("empty", os.FileMode(0755)), IsNil)
c.Assert(RemoveAll(s.Fs, "empty"), IsNil)
_, err := s.Fs.Stat("empty")
c.Assert(err, NotNil)
c.Assert(os.IsNotExist(err), Equals, true)
}

func (s *FilesystemSuite) TestRemoveAll(c *C) {
fnames := []string{
"foo/1",
Expand Down Expand Up @@ -569,3 +577,60 @@ func (s *FilesystemSuite) TestRemoveAllRelative(c *C) {
c.Assert(os.IsNotExist(err), Equals, true, comment)
}
}

func (s *FilesystemSuite) TestMkdirAll(c *C) {
err := s.Fs.MkdirAll("empty", os.FileMode(0755))
c.Assert(err, IsNil)
fi, err := s.Fs.Stat("empty")
c.Assert(err, IsNil)
c.Assert(fi.IsDir(), Equals, true)
}

func (s *FilesystemSuite) TestMkdirAllNested(c *C) {
err := s.Fs.MkdirAll("foo/bar/baz", os.FileMode(0755))
c.Assert(err, IsNil)
fi, err := s.Fs.Stat("foo/bar/baz")
c.Assert(err, IsNil)
c.Assert(fi.IsDir(), Equals, true)
}

func (s *FilesystemSuite) TestMkdirAllIdempotent(c *C) {
err := s.Fs.MkdirAll("empty", os.FileMode(0755))
c.Assert(err, IsNil)
fi, err := s.Fs.Stat("empty")
c.Assert(err, IsNil)
c.Assert(fi.IsDir(), Equals, true)

// idempotent
err = s.Fs.MkdirAll("empty", os.FileMode(0755))
c.Assert(err, IsNil)
fi, err = s.Fs.Stat("empty")
c.Assert(err, IsNil)
c.Assert(fi.IsDir(), Equals, true)
}

func (s *FilesystemSuite) TestMkdirAllAndOpenFile(c *C) {
err := s.Fs.MkdirAll("dir", os.FileMode(0755))
c.Assert(err, IsNil)

f, err := s.Fs.Create("dir/bar/foo")
c.Assert(err, IsNil)
c.Assert(f.Close(), IsNil)

fi, err := s.Fs.Stat("dir/bar/foo")
c.Assert(err, IsNil)
c.Assert(fi.IsDir(), Equals, false)
}

func (s *FilesystemSuite) TestMkdirAllWithExistingFile(c *C) {
f, err := s.Fs.Create("dir/foo")
c.Assert(err, IsNil)
c.Assert(f.Close(), IsNil)

err = s.Fs.MkdirAll("dir/foo", os.FileMode(0755))
c.Assert(err, NotNil)

fi, err := s.Fs.Stat("dir/foo")
c.Assert(err, IsNil)
c.Assert(fi.IsDir(), Equals, false)
}

0 comments on commit 8209194

Please sign in to comment.