diff --git a/src/Composer/Installer/LibraryInstaller.php b/src/Composer/Installer/LibraryInstaller.php index 281ffa11a..cb3808295 100644 --- a/src/Composer/Installer/LibraryInstaller.php +++ b/src/Composer/Installer/LibraryInstaller.php @@ -41,15 +41,16 @@ class LibraryInstaller implements InstallerInterface * @param IOInterface $io * @param Composer $composer * @param string $type + * @param Filesystem $filesystem */ - public function __construct(IOInterface $io, Composer $composer, $type = 'library') + public function __construct(IOInterface $io, Composer $composer, $type = 'library', Filesystem $filesystem = null) { $this->composer = $composer; $this->downloadManager = $composer->getDownloadManager(); $this->io = $io; $this->type = $type; - $this->filesystem = new Filesystem(); + $this->filesystem = $filesystem ?: new Filesystem(); $this->vendorDir = rtrim($composer->getConfig()->get('vendor-dir'), '/'); $this->binDir = rtrim($composer->getConfig()->get('bin-dir'), '/'); } @@ -157,8 +158,12 @@ class LibraryInstaller implements InstallerInterface protected function updateCode(PackageInterface $initial, PackageInterface $target) { - $downloadPath = $this->getInstallPath($initial); - $this->downloadManager->update($initial, $target, $downloadPath); + $initialDownloadPath = $this->getInstallPath($initial); + $targetDownloadPath = $this->getInstallPath($target); + if ($targetDownloadPath !== $initialDownloadPath) { + $this->filesystem->copyThenRemove($initialDownloadPath, $targetDownloadPath); + } + $this->downloadManager->update($initial, $target, $targetDownloadPath); } protected function removeCode(PackageInterface $package) diff --git a/src/Composer/Util/Filesystem.php b/src/Composer/Util/Filesystem.php index 3dade2ce9..bdef6e402 100644 --- a/src/Composer/Util/Filesystem.php +++ b/src/Composer/Util/Filesystem.php @@ -129,15 +129,12 @@ class Filesystem { $it = new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS); $ri = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::SELF_FIRST); - - if (!file_exists($target)) { - mkdir($target, 0777, true); - } + $this->ensureDirectoryExists($target); foreach ($ri as $file) { $targetPath = $target . DIRECTORY_SEPARATOR . $ri->getSubPathName(); if ($file->isDir()) { - mkdir($targetPath); + $this->ensureDirectoryExists($targetPath); } else { copy($file->getPathname(), $targetPath); } diff --git a/tests/Composer/Test/Installer/LibraryInstallerTest.php b/tests/Composer/Test/Installer/LibraryInstallerTest.php index 5ea4f076b..245969618 100644 --- a/tests/Composer/Test/Installer/LibraryInstallerTest.php +++ b/tests/Composer/Test/Installer/LibraryInstallerTest.php @@ -131,15 +131,31 @@ class LibraryInstallerTest extends TestCase */ public function testUpdate() { - $library = new LibraryInstaller($this->io, $this->composer); + $filesystem = $this->getMockBuilder('Composer\Util\Filesystem') + ->getMock(); + $filesystem + ->expects($this->once()) + ->method('copyThenRemove') + ->with($this->vendorDir.'/package1', $this->vendorDir.'/package1/newtarget'); + $initial = $this->createPackageMock(); $target = $this->createPackageMock(); $initial - ->expects($this->any()) + ->expects($this->once()) ->method('getPrettyName') ->will($this->returnValue('package1')); + $target + ->expects($this->once()) + ->method('getPrettyName') + ->will($this->returnValue('package1')); + + $target + ->expects($this->once()) + ->method('getTargetDir') + ->will($this->returnValue('newtarget')); + $this->repository ->expects($this->exactly(3)) ->method('hasPackage') @@ -148,7 +164,7 @@ class LibraryInstallerTest extends TestCase $this->dm ->expects($this->once()) ->method('update') - ->with($initial, $target, $this->vendorDir.'/package1'); + ->with($initial, $target, $this->vendorDir.'/package1/newtarget'); $this->repository ->expects($this->once()) @@ -160,6 +176,7 @@ class LibraryInstallerTest extends TestCase ->method('addPackage') ->with($target); + $library = new LibraryInstaller($this->io, $this->composer, 'library', $filesystem); $library->update($this->repository, $initial, $target); $this->assertFileExists($this->vendorDir, 'Vendor dir should be created'); $this->assertFileExists($this->binDir, 'Bin dir should be created'); diff --git a/tests/Composer/Test/Plugin/PluginInstallerTest.php b/tests/Composer/Test/Plugin/PluginInstallerTest.php index 3b64f2699..2502dded9 100644 --- a/tests/Composer/Test/Plugin/PluginInstallerTest.php +++ b/tests/Composer/Test/Plugin/PluginInstallerTest.php @@ -20,6 +20,7 @@ use Composer\Package\Loader\ArrayLoader; use Composer\Package\PackageInterface; use Composer\Plugin\PluginManager; use Composer\Autoload\AutoloadGenerator; +use Composer\Util\Filesystem; class PluginInstallerTest extends \PHPUnit_Framework_TestCase { @@ -30,13 +31,17 @@ class PluginInstallerTest extends \PHPUnit_Framework_TestCase protected $repository; protected $io; protected $autoloadGenerator; + protected $directory; protected function setUp() { $loader = new JsonLoader(new ArrayLoader()); $this->packages = array(); + $this->directory = sys_get_temp_dir() . '/' . uniqid(); for ($i = 1; $i <= 4; $i++) { - $this->packages[] = $loader->load(__DIR__.'/Fixtures/plugin-v'.$i.'/composer.json'); + $filename = '/Fixtures/plugin-v'.$i.'/composer.json'; + mkdir(dirname($this->directory . $filename), 0777, TRUE); + $this->packages[] = $loader->load(__DIR__ . $filename); } $dm = $this->getMockBuilder('Composer\Downloader\DownloadManager') @@ -77,13 +82,19 @@ class PluginInstallerTest extends \PHPUnit_Framework_TestCase $config->merge(array( 'config' => array( - 'vendor-dir' => __DIR__.'/Fixtures/', - 'home' => __DIR__.'/Fixtures', - 'bin-dir' => __DIR__.'/Fixtures/bin', + 'vendor-dir' => $this->directory.'/Fixtures/', + 'home' => $this->directory.'/Fixtures', + 'bin-dir' => $this->directory.'/Fixtures/bin', ), )); } + protected function tearDown() + { + $filesystem = new Filesystem(); + $filesystem->removeDirectory($this->directory); + } + public function testInstallNewPlugin() { $this->repository