From e7da41f9344c197712da3010e456e2cf26f36308 Mon Sep 17 00:00:00 2001 From: kuba-- Date: Mon, 13 Aug 2018 21:28:32 +0200 Subject: [PATCH] Add TempDir Signed-off-by: kuba-- --- .gitignore | 4 ++++ go.mod | 7 +++++++ go.sum | 9 +++++++++ test/fs.go | 3 +++ util/util.go | 39 +++++++++++++++++++++++++++++++++++++++ util/util_test.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 105 insertions(+) create mode 100644 go.mod create mode 100644 go.sum create mode 100644 util/util_test.go 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/go.mod b/go.mod new file mode 100644 index 0000000..eec1581 --- /dev/null +++ b/go.mod @@ -0,0 +1,7 @@ +module gopkg.in/src-d/go-billy.v4 + +require ( + github.com/kr/pretty v0.1.0 // indirect + golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9 + gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..aa96620 --- /dev/null +++ b/go.sum @@ -0,0 +1,9 @@ +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9 h1:lkiLiLBHGoH3XnqSLUIaBsilGMUjI+Uy2Xu2JLUtTas= +golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 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) TestRemoveAllRelative(c *C) { } 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 @@ func TempFile(fs billy.Basic, dir, prefix string) (f billy.File, err error) { 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) + } + } +}