diff --git a/shx/copy.go b/shx/copy.go index d13b411..7473576 100644 --- a/shx/copy.go +++ b/shx/copy.go @@ -28,7 +28,7 @@ func Copy(src string, dest string, opts ...CopyOption) error { } if len(items) == 0 { - return errors.Errorf("no such file or directory %q", src) + return errors.Errorf("no such file or directory '%s'", src) } var combinedOpts CopyOption @@ -36,6 +36,11 @@ func Copy(src string, dest string, opts ...CopyOption) error { combinedOpts |= opt } + // Check if the destination exists, e.g. if we are copying to /tmp/foo, /tmp should already exist + if _, err := os.Stat(filepath.Dir(dest)); err != nil { + return err + } + for _, item := range items { err := copyFileOrDirectory(item, dest, combinedOpts) if err != nil { @@ -71,7 +76,7 @@ func copyFileOrDirectory(src string, dest string, opts CopyOption) error { destPath := filepath.Join(dest, relPath) if srcInfo.IsDir() { - return os.Mkdir(destPath, srcInfo.Mode()) + return os.MkdirAll(destPath, srcInfo.Mode()) } return copyFile(srcPath, destPath, opts) diff --git a/shx/copy_test.go b/shx/copy_test.go index 61b1af4..c8b6067 100644 --- a/shx/copy_test.go +++ b/shx/copy_test.go @@ -27,6 +27,24 @@ func TestCopy(t *testing.T) { assertFile(t, filepath.Join(tmp, "a/ab/ab2.txt")) }) + t.Run("recursively copy directory into populated dest dir", func(t *testing.T) { + tmp, err := ioutil.TempDir("", "magex") + require.NoError(t, err, "could not create temp directory for test") + defer os.RemoveAll(tmp) + + require.NoError(t, os.MkdirAll(filepath.Join(tmp, "a"), 0755)) + + err = Copy("testdata/copy/a", tmp, CopyRecursive) + require.NoError(t, err, "Copy into directory with same directory name") + + assert.DirExists(t, filepath.Join(tmp, "a")) + assertFile(t, filepath.Join(tmp, "a/a1.txt")) + assertFile(t, filepath.Join(tmp, "a/a2.txt")) + assert.DirExists(t, filepath.Join(tmp, "a/ab")) + assertFile(t, filepath.Join(tmp, "a/ab/ab1.txt")) + assertFile(t, filepath.Join(tmp, "a/ab/ab2.txt")) + }) + t.Run("copy glob", func(t *testing.T) { tmp, err := ioutil.TempDir("", "magex") require.NoError(t, err, "could not create temp directory for test")