diff --git a/src/Composer/Downloader/ArchiveDownloader.php b/src/Composer/Downloader/ArchiveDownloader.php index ed113e0d4..5da9350ea 100644 --- a/src/Composer/Downloader/ArchiveDownloader.php +++ b/src/Composer/Downloader/ArchiveDownloader.php @@ -50,12 +50,12 @@ abstract class ArchiveDownloader extends FileDownloader // Rename the content directory to avoid error when moving up // a child folder with the same name $temporaryName = md5(time().rand()); - rename($contentDir, $temporaryName); + $this->filesystem->rename($contentDir, $temporaryName); $contentDir = $temporaryName; foreach (array_merge(glob($contentDir . '/.*'), glob($contentDir . '/*')) as $file) { if (trim(basename($file), '.')) { - rename($file, $path . '/' . basename($file)); + $this->filesystem->rename($file, $path . '/' . basename($file)); } } rmdir($contentDir); diff --git a/src/Composer/Util/Filesystem.php b/src/Composer/Util/Filesystem.php index 9ffb923da..4b91d78fa 100644 --- a/src/Composer/Util/Filesystem.php +++ b/src/Composer/Util/Filesystem.php @@ -14,9 +14,17 @@ namespace Composer\Util; /** * @author Jordi Boggiano + * @author Johannes M. Schmitt */ class Filesystem { + private $processExecutor; + + public function __construct(ProcessExecutor $executor = null) + { + $this->processExecutor = $executor ?: new ProcessExecutor(); + } + public function removeDirectory($directory) { if (!is_dir($directory)) { @@ -53,6 +61,25 @@ class Filesystem } } + public function rename($source, $target) + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + rename($source, $target); + + return; + } + + // We do not use PHP's "rename" function here since it does not support + // the case where $source, and $target are located on different partitions. + if (0 !== $this->processExecutor->execute('mv '.escapeshellarg($source).' '.escapeshellarg($target))) { + if (true === @rename($source, $target)) { + return; + } + + throw new \RuntimeException(sprintf('Could not rename "%s" to "%s".', $source, $target)); + } + } + /** * Returns the shortest path from $from to $to *