diff --git a/tools/file/file.go b/tools/file/file.go new file mode 100644 index 0000000000..c69a9be161 --- /dev/null +++ b/tools/file/file.go @@ -0,0 +1,31 @@ +package file + +import ( + "io" + "os" + "path/filepath" + "runtime" + + "github.com/attic-labs/noms/d" +) + +// DumbCopy copies the contents of a regular file at srcPath (following symlinks) to a new regular file at dstPath. New file is created with mode 0644. +func DumbCopy(srcPath, dstPath string) { + chkClose := func(c io.Closer) { d.Exp.NoError(c.Close()) } + src, err := os.Open(srcPath) + d.Exp.NoError(err) + defer chkClose(src) + + dst, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) + d.Exp.NoError(err) + defer chkClose(dst) + _, err = io.Copy(dst, src) + d.Exp.NoError(err) +} + +// MyDir returns the directory in which the file containing the calling source code resides. +func MyDir() string { + _, path, _, ok := runtime.Caller(0) + d.Chk.True(ok, "Should have been able to get Caller.") + return filepath.Dir(path) +} diff --git a/tools/file/file_test.go b/tools/file/file_test.go new file mode 100644 index 0000000000..bc79f0420a --- /dev/null +++ b/tools/file/file_test.go @@ -0,0 +1,69 @@ +package file + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" + + "github.com/attic-labs/noms/Godeps/_workspace/src/github.com/stretchr/testify/suite" + "github.com/attic-labs/noms/d" +) + +const ( + contents = "hey" +) + +func TestSerialRunnerTestSuite(t *testing.T) { + suite.Run(t, &FileTestSuite{}) +} + +type FileTestSuite struct { + suite.Suite + dir, src string +} + +func (suite *FileTestSuite) SetupTest() { + var err error + suite.dir, err = ioutil.TempDir(os.TempDir(), "") + suite.NoError(err) + suite.src = filepath.Join(suite.dir, "srcfile") + suite.NoError(ioutil.WriteFile(suite.src, []byte(contents), 0644)) +} + +func (suite *FileTestSuite) TearDownTest() { + os.Remove(suite.dir) +} + +func (suite *FileTestSuite) TestCopyFile() { + dst := filepath.Join(suite.dir, "dstfile") + suite.NoError(d.Try(func() { DumbCopy(suite.src, dst) })) + + out, err := ioutil.ReadFile(dst) + suite.NoError(err) + suite.Equal(contents, string(out)) +} + +func (suite *FileTestSuite) TestCopyLink() { + link := filepath.Join(suite.dir, "link") + suite.NoError(os.Symlink(suite.src, link)) + + dst := filepath.Join(suite.dir, "dstfile") + suite.NoError(d.Try(func() { DumbCopy(link, dst) })) + + info, err := os.Lstat(dst) + suite.NoError(err) + suite.True(info.Mode().IsRegular()) + + out, err := ioutil.ReadFile(dst) + suite.NoError(err) + suite.Equal(contents, string(out)) +} + +func (suite *FileTestSuite) TestNoCopyDir() { + dir, err := ioutil.TempDir(suite.dir, "") + suite.NoError(err) + + dst := filepath.Join(suite.dir, "dst") + suite.Error(d.Try(func() { DumbCopy(dir, dst) })) +}