Merge pull request #62 from kuba--/enhancement-tempdir
Add TempDir
diff --git a/.gitignore b/.gitignore
index 3f2bc47..62cdb53 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,5 @@
/coverage.txt
+/vendor
+Gopkg.lock
+Gopkg.toml
+go.sum
diff --git a/test/fs.go b/test/fs.go
index 54f4529..e5d5146 100644
--- a/test/fs.go
+++ b/test/fs.go
@@ -188,6 +188,9 @@
}
func (s *FilesystemSuite) TestReadDir(c *C) {
+ err := s.FS.MkdirAll("qux", 0644)
+ c.Assert(err, IsNil)
+
files := []string{"foo", "bar", "qux/baz", "qux/qux"}
for _, name := range files {
err := util.WriteFile(s.FS, name, nil, 0644)
diff --git a/util/util.go b/util/util.go
index 2876375..cf7fb57 100644
--- a/util/util.go
+++ b/util/util.go
@@ -168,6 +168,45 @@
return
}
+// TempDir creates a new temporary directory in the directory dir
+// with a name beginning with prefix and returns the path of the
+// new directory. If dir is the empty string, TempDir uses the
+// default directory for temporary files (see os.TempDir).
+// Multiple programs calling TempDir simultaneously
+// will not choose the same directory. It is the caller's responsibility
+// to remove the directory when no longer needed.
+func TempDir(fs billy.Dir, dir, prefix string) (name string, err error) {
+ // This implementation is based on stdlib ioutil.TempDir
+
+ if dir == "" {
+ dir = os.TempDir()
+ }
+
+ nconflict := 0
+ for i := 0; i < 10000; i++ {
+ try := filepath.Join(dir, prefix+nextSuffix())
+ err = fs.MkdirAll(try, 0700)
+ if os.IsExist(err) {
+ if nconflict++; nconflict > 10 {
+ randmu.Lock()
+ rand = reseed()
+ randmu.Unlock()
+ }
+ continue
+ }
+ if os.IsNotExist(err) {
+ if _, err := os.Stat(dir); os.IsNotExist(err) {
+ return "", err
+ }
+ }
+ if err == nil {
+ name = try
+ }
+ break
+ }
+ return
+}
+
type underlying interface {
Underlying() billy.Basic
}
diff --git a/util/util_test.go b/util/util_test.go
new file mode 100644
index 0000000..92a8ca0
--- /dev/null
+++ b/util/util_test.go
@@ -0,0 +1,43 @@
+package util_test
+
+import (
+ "os"
+ "path/filepath"
+ "regexp"
+ "testing"
+
+ "gopkg.in/src-d/go-billy.v4/memfs"
+ "gopkg.in/src-d/go-billy.v4/util"
+)
+
+func TestTempFile(t *testing.T) {
+ fs := memfs.New()
+
+ dir, err := util.TempDir(fs, "", "util_test")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer util.RemoveAll(fs, dir)
+
+ f, err := util.TempFile(fs, dir, "foo")
+ if f == nil || err != nil {
+ t.Errorf("TempFile(%q, `foo`) = %v, %v", dir, f, err)
+ }
+}
+
+func TestTempDir(t *testing.T) {
+ fs := memfs.New()
+
+ dir := os.TempDir()
+ name, err := util.TempDir(fs, dir, "util_test")
+ if name == "" || err != nil {
+ t.Errorf("TempDir(dir, `util_test`) = %v, %v", name, err)
+ }
+ if name != "" {
+ util.RemoveAll(fs, name)
+ re := regexp.MustCompile("^" + regexp.QuoteMeta(filepath.Join(dir, "util_test")) + "[0-9]+$")
+ if !re.MatchString(name) {
+ t.Errorf("TempDir(`"+dir+"`, `util_test`) created bad name %s", name)
+ }
+ }
+}