Skip to content

Commit

Permalink
Add FileSystem and WalkFS
Browse files Browse the repository at this point in the history
Closes #1
  • Loading branch information
davecheney authored and kr committed Nov 11, 2013
1 parent 3cce066 commit 2788f0d
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 6 deletions.
36 changes: 36 additions & 0 deletions filesystem.go
@@ -0,0 +1,36 @@
package fs

import (
"io/ioutil"
"os"
"path/filepath"
)

// FileSystem defines the methods of an abstract filesystem.
type FileSystem interface {

// ReadDir reads the directory named by dirname and returns a
// list of directory entries.
ReadDir(dirname string) ([]os.FileInfo, error)

// Lstat returns a FileInfo describing the named file. If the file is a
// symbolic link, the returned FileInfo describes the symbolic link. Lstat
// makes no attempt to follow the link.
Lstat(name string) (os.FileInfo, error)

// Join joins any number of path elements into a single path, adding a
// separator if necessary. The result is Cleaned; in particular, all
// empty strings are ignored.
//
// The separator is FileSystem specific.
Join(elem ...string) string
}

// fs represents a FileSystem provided by the os package.
type fs struct{}

func (f *fs) ReadDir(dirname string) ([]os.FileInfo, error) { return ioutil.ReadDir(dirname) }

func (f *fs) Lstat(name string) (os.FileInfo, error) { return os.Lstat(name) }

func (f *fs) Join(elem ...string) string { return filepath.Join(elem...) }
19 changes: 13 additions & 6 deletions walk.go
Expand Up @@ -2,9 +2,7 @@
package fs

import (
"io/ioutil"
"os"
"path/filepath"
)

// Walker provides a convenient interface for iterating over the
Expand All @@ -15,6 +13,7 @@ import (
// but means that for very large directories Walker can be inefficient.
// Walker does not follow symbolic links.
type Walker struct {
fs FileSystem
cur item
stack []item
descend bool
Expand All @@ -28,8 +27,16 @@ type item struct {

// Walk returns a new Walker rooted at root.
func Walk(root string) *Walker {
info, err := os.Lstat(root)
return &Walker{stack: []item{{root, info, err}}}
return WalkFS(root, new(fs))
}

// WalkFS returns a new Walker rooted at root on the FileSystem fs.
func WalkFS(root string, fs FileSystem) *Walker {
info, err := fs.Lstat(root)
return &Walker{
fs: fs,
stack: []item{{root, info, err}},
}
}

// Step advances the Walker to the next file or directory,
Expand All @@ -38,13 +45,13 @@ func Walk(root string) *Walker {
// It returns false when the walk stops at the end of the tree.
func (w *Walker) Step() bool {
if w.descend && w.cur.err == nil && w.cur.info.IsDir() {
list, err := ioutil.ReadDir(w.cur.path)
list, err := w.fs.ReadDir(w.cur.path)
if err != nil {
w.cur.err = err
w.stack = append(w.stack, w.cur)
} else {
for i := len(list) - 1; i >= 0; i-- {
path := filepath.Join(w.cur.path, list[i].Name())
path := w.fs.Join(w.cur.path, list[i].Name())
w.stack = append(w.stack, item{path, list[i], nil})
}
}
Expand Down

0 comments on commit 2788f0d

Please sign in to comment.