Browse Source

pkg/fileutil: fix TouchDirAll, add CreateDirAll

os.MkdirAll never returns os.ErrExist.
And add another function to ensure deepest
directory is empty.
Gyu-Ho Lee 9 years ago
parent
commit
187faba3e0
2 changed files with 45 additions and 1 deletions
  1. 23 1
      pkg/fileutil/fileutil.go
  2. 22 0
      pkg/fileutil/fileutil_test.go

+ 23 - 1
pkg/fileutil/fileutil.go

@@ -16,6 +16,7 @@
 package fileutil
 package fileutil
 
 
 import (
 import (
+	"fmt"
 	"io/ioutil"
 	"io/ioutil"
 	"os"
 	"os"
 	"path"
 	"path"
@@ -63,13 +64,34 @@ func ReadDir(dirpath string) ([]string, error) {
 // TouchDirAll is similar to os.MkdirAll. It creates directories with 0700 permission if any directory
 // TouchDirAll is similar to os.MkdirAll. It creates directories with 0700 permission if any directory
 // does not exists. TouchDirAll also ensures the given directory is writable.
 // does not exists. TouchDirAll also ensures the given directory is writable.
 func TouchDirAll(dir string) error {
 func TouchDirAll(dir string) error {
+	// If path is already a directory, MkdirAll does nothing
+	// and returns nil.
 	err := os.MkdirAll(dir, PrivateDirMode)
 	err := os.MkdirAll(dir, PrivateDirMode)
-	if err != nil && err != os.ErrExist {
+	if err != nil {
+		// if mkdirAll("a/text") and "text" is not
+		// a directory, this will return syscall.ENOTDIR
 		return err
 		return err
 	}
 	}
 	return IsDirWriteable(dir)
 	return IsDirWriteable(dir)
 }
 }
 
 
+// CreateDirAll is similar to TouchDirAll but returns error
+// if the deepest directory was not empty.
+func CreateDirAll(dir string) error {
+	err := TouchDirAll(dir)
+	if err == nil {
+		var ns []string
+		ns, err = ReadDir(dir)
+		if err != nil {
+			return err
+		}
+		if len(ns) != 0 {
+			err = fmt.Errorf("expected %q to be empty, got %q", dir, ns)
+		}
+	}
+	return err
+}
+
 func Exist(name string) bool {
 func Exist(name string) bool {
 	_, err := os.Stat(name)
 	_, err := os.Stat(name)
 	return err == nil
 	return err == nil

+ 22 - 0
pkg/fileutil/fileutil_test.go

@@ -21,6 +21,7 @@ import (
 	"path/filepath"
 	"path/filepath"
 	"reflect"
 	"reflect"
 	"runtime"
 	"runtime"
+	"strings"
 	"testing"
 	"testing"
 )
 )
 
 
@@ -80,6 +81,27 @@ func TestReadDir(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestCreateDirAll(t *testing.T) {
+	tmpdir, err := ioutil.TempDir(os.TempDir(), "foo")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tmpdir)
+
+	tmpdir2 := filepath.Join(tmpdir, "testdir")
+	if err = CreateDirAll(tmpdir2); err != nil {
+		t.Fatal(err)
+	}
+
+	if err = ioutil.WriteFile(filepath.Join(tmpdir2, "text.txt"), []byte("test text"), PrivateFileMode); err != nil {
+		t.Fatal(err)
+	}
+
+	if err = CreateDirAll(tmpdir2); err == nil || !strings.Contains(err.Error(), "to be empty, got") {
+		t.Fatalf("unexpected error %v", err)
+	}
+}
+
 func TestExist(t *testing.T) {
 func TestExist(t *testing.T) {
 	f, err := ioutil.TempFile(os.TempDir(), "fileutil")
 	f, err := ioutil.TempFile(os.TempDir(), "fileutil")
 	if err != nil {
 	if err != nil {