diff --git a/all_test.go b/all_test.go index 910570a..3c43b2d 100644 --- a/all_test.go +++ b/all_test.go @@ -5,6 +5,7 @@ import ( "io" "io/ioutil" "os" + "path/filepath" "runtime" "strings" "testing" @@ -86,6 +87,48 @@ func TestCopy(t *testing.T) { err = os.Chmod(dest, 0o755) Expect(t, err).ToBe(nil) }) + When(t, "file is deleted while copying", func(t *testing.T) { + src := t.TempDir() + dest := t.TempDir() + + file := filepath.Join(src, "file") + f, err := os.Create(file) + Expect(t, err).ToBe(nil) + f.Close() + + opt := Options{Skip: func(info os.FileInfo, src, dest string) (bool, error) { + os.Remove(src) + return false, nil + }} + err = Copy(src, dest, opt) + Expect(t, err).ToBe(nil) + }) + When(t, "symlink is deleted while copying", func(t *testing.T) { + src := t.TempDir() + dest := t.TempDir() + + Expect(t, os.Symlink(".", filepath.Join(src, "symlink"))).ToBe(nil) + + opt := Options{Skip: func(info os.FileInfo, src, dest string) (bool, error) { + os.Remove(src) + return false, nil + }} + err = Copy(src, dest, opt) + Expect(t, err).ToBe(nil) + }) + When(t, "directory is deleted while copying", func(t *testing.T) { + src := t.TempDir() + dest := t.TempDir() + + Expect(t, os.Mkdir(filepath.Join(src, "dir"), 0755)).ToBe(nil) + + opt := Options{Skip: func(info os.FileInfo, src, dest string) (bool, error) { + os.Remove(src) + return false, nil + }} + err = Copy(src, dest, opt) + Expect(t, err).ToBe(nil) + }) } func TestCopy_NamedPipe(t *testing.T) { diff --git a/copy.go b/copy.go index 60643dd..d0450e7 100644 --- a/copy.go +++ b/copy.go @@ -65,6 +65,14 @@ func copyNextOrSkip(src, dest string, info os.FileInfo, opt Options) error { // with considering existence of parent directory // and file permission. func fcopy(src, dest string, info os.FileInfo, opt Options) (err error) { + s, err := os.Open(src) + if err != nil { + if os.IsNotExist(err) { + return nil + } + return + } + defer fclose(s, &err) if err = os.MkdirAll(filepath.Dir(dest), os.ModePerm); err != nil { return @@ -82,12 +90,6 @@ func fcopy(src, dest string, info os.FileInfo, opt Options) (err error) { } chmodfunc(&err) - s, err := os.Open(src) - if err != nil { - return - } - defer fclose(s, &err) - var buf []byte = nil var w io.Writer = f var r io.Reader = s @@ -146,6 +148,9 @@ func dcopy(srcdir, destdir string, info os.FileInfo, opt Options) (err error) { contents, err := ioutil.ReadDir(srcdir) if err != nil { + if os.IsNotExist(err) { + return nil + } return } @@ -222,6 +227,9 @@ func onsymlink(src, dest string, opt Options) error { func lcopy(src, dest string) error { src, err := os.Readlink(src) if err != nil { + if os.IsNotExist(err) { + return nil + } return err } return os.Symlink(src, dest)