nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: otiai10/copy
Pull request #103 (2023-04-05 09:28:53)

fix files/symlinks/dirs deleted while copy
ref https://github.com/otiai10/copy/issues/72


Patch:
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)


Test patch:
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) {