ソースを参照

Merge pull request #6644 from codekandis/feature/util-filesystem-copy-separation

Introduces a new method `copy()`.
Jordi Boggiano 7 年 前
コミット
1e6854455c

+ 19 - 3
src/Composer/Util/Filesystem.php

@@ -247,27 +247,43 @@ class Filesystem
      */
     public function copyThenRemove($source, $target)
     {
+        $this->copy($source, $target);
         if (!is_dir($source)) {
-            copy($source, $target);
             $this->unlink($source);
 
             return;
         }
 
+        $this->removeDirectoryPhp($source);
+    }
+
+    /**
+     * Copies a file or directory from $source to $target.
+     *
+     * @param $source
+     * @param $target
+     * @return bool
+     */
+    public function copy($source, $target) {
+        if (!is_dir($source)) {
+            return copy($source, $target);
+        }
+
         $it = new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS);
         $ri = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::SELF_FIRST);
         $this->ensureDirectoryExists($target);
 
+        $result=true;
         foreach ($ri as $file) {
             $targetPath = $target . DIRECTORY_SEPARATOR . $ri->getSubPathName();
             if ($file->isDir()) {
                 $this->ensureDirectoryExists($targetPath);
             } else {
-                copy($file->getPathname(), $targetPath);
+                $result = $result && copy($file->getPathname(), $targetPath);
             }
         }
 
-        $this->removeDirectoryPhp($source);
+        return $result;
     }
 
     public function rename($source, $target)

+ 48 - 0
tests/Composer/Test/Util/FilesystemTest.php

@@ -311,4 +311,52 @@ class FilesystemTest extends TestCase
         $this->assertTrue($fs->removeJunction($junction));
         $this->assertFalse(is_dir($junction));
     }
+
+    public function testCopy()
+    {
+        @mkdir($this->workingDir . '/foo/bar', 0777, true);
+        @mkdir($this->workingDir . '/foo/baz', 0777, true);
+        file_put_contents($this->workingDir . '/foo/foo.file', 'foo');
+        file_put_contents($this->workingDir . '/foo/bar/foobar.file', 'foobar');
+        file_put_contents($this->workingDir . '/foo/baz/foobaz.file', 'foobaz');
+        file_put_contents($this->testFile, 'testfile');
+
+        $fs = new Filesystem();
+
+        $result1 = $fs->copy($this->workingDir . '/foo', $this->workingDir . '/foop');
+        $this->assertTrue($result1,'Copying directory failed.');
+        $this->assertTrue(is_dir($this->workingDir . '/foop'), 'Not a directory: ' . $this->workingDir . '/foop');
+        $this->assertTrue(is_dir($this->workingDir . '/foop/bar'), 'Not a directory: ' . $this->workingDir . '/foop/bar');
+        $this->assertTrue(is_dir($this->workingDir . '/foop/baz'), 'Not a directory: ' . $this->workingDir . '/foop/baz');
+        $this->assertTrue(is_file($this->workingDir . '/foop/foo.file'), 'Not a file: ' . $this->workingDir . '/foop/foo.file');
+        $this->assertTrue(is_file($this->workingDir . '/foop/bar/foobar.file'), 'Not a file: ' . $this->workingDir . '/foop/bar/foobar.file');
+        $this->assertTrue(is_file($this->workingDir . '/foop/baz/foobaz.file'), 'Not a file: ' . $this->workingDir . '/foop/baz/foobaz.file');
+
+        $result2 = $fs->copy($this->testFile, $this->workingDir . '/testfile.file');
+        $this->assertTrue($result2);
+        $this->assertTrue(is_file($this->workingDir . '/testfile.file'));
+    }
+
+    public function testCopyThenRemove()
+    {
+        @mkdir($this->workingDir . '/foo/bar', 0777, true);
+        @mkdir($this->workingDir . '/foo/baz', 0777, true);
+        file_put_contents($this->workingDir . '/foo/foo.file', 'foo');
+        file_put_contents($this->workingDir . '/foo/bar/foobar.file', 'foobar');
+        file_put_contents($this->workingDir . '/foo/baz/foobaz.file', 'foobaz');
+        file_put_contents($this->testFile, 'testfile');
+
+        $fs = new Filesystem();
+
+        $fs->copyThenRemove($this->testFile, $this->workingDir . '/testfile.file');
+        $this->assertFalse(is_file($this->testFile), 'Still a file: ' . $this->testFile);
+
+        $fs->copyThenRemove($this->workingDir . '/foo', $this->workingDir . '/foop');
+        $this->assertFalse(is_file($this->workingDir . '/foo/baz/foobaz.file'), 'Still a file: ' . $this->workingDir . '/foo/baz/foobaz.file');
+        $this->assertFalse(is_file($this->workingDir . '/foo/bar/foobar.file'), 'Still a file: ' . $this->workingDir . '/foo/bar/foobar.file');
+        $this->assertFalse(is_file($this->workingDir . '/foo/foo.file'), 'Still a file: ' . $this->workingDir . '/foo/foo.file');
+        $this->assertFalse(is_dir($this->workingDir . '/foo/baz'), 'Still a directory: ' . $this->workingDir . '/foo/baz');
+        $this->assertFalse(is_dir($this->workingDir . '/foo/bar'), 'Still a directory: ' . $this->workingDir . '/foo/bar');
+        $this->assertFalse(is_dir($this->workingDir . '/foo'), 'Still a directory: ' . $this->workingDir . '/foo');
+    }
 }