diff --git a/src/Composer/Downloader/ArchiveDownloader.php b/src/Composer/Downloader/ArchiveDownloader.php index ce1d09691..318e73c6f 100644 --- a/src/Composer/Downloader/ArchiveDownloader.php +++ b/src/Composer/Downloader/ArchiveDownloader.php @@ -91,32 +91,15 @@ abstract class ArchiveDownloader extends FileDownloader } $this->filesystem->removeDirectory($temporaryDir); - if ($this->filesystem->isDirEmpty($this->config->get('vendor-dir').'/composer/')) { - $this->filesystem->removeDirectory($this->config->get('vendor-dir').'/composer/'); - } - if ($this->filesystem->isDirEmpty($this->config->get('vendor-dir'))) { - $this->filesystem->removeDirectory($this->config->get('vendor-dir')); - } } catch (\Exception $e) { // clean up $this->filesystem->removeDirectory($path); $this->filesystem->removeDirectory($temporaryDir); - if (file_exists($fileName)) { - $this->filesystem->unlink($fileName); - } throw $e; } } - /** - * {@inheritdoc} - */ - protected function getFileName(PackageInterface $package, $path) - { - return rtrim($path.'_'.md5($path.spl_object_hash($package)).'.'.pathinfo(parse_url($package->getDistUrl(), PHP_URL_PATH), PATHINFO_EXTENSION), '.'); - } - /** * Extract file to directory * diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index 357c5b59d..f94ec228b 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -101,8 +101,9 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface ); } - $this->filesystem->ensureDirectoryExists($path); $fileName = $this->getFileName($package, $path); + $this->filesystem->ensureDirectoryExists($path); + $this->filesystem->ensureDirectoryExists(dirname($fileName)); $io = $this->io; $cache = $this->cache; @@ -234,6 +235,19 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface */ public function cleanup($type, PackageInterface $package, $path, PackageInterface $prevPackage = null) { + $fileName = $this->getFileName($package, $path); + if (file_exists($fileName)) { + $this->filesystem->unlink($fileName); + } + if ($this->filesystem->isDirEmpty($this->config->get('vendor-dir').'/composer/')) { + $this->filesystem->removeDirectory($this->config->get('vendor-dir').'/composer/'); + } + if ($this->filesystem->isDirEmpty($this->config->get('vendor-dir'))) { + $this->filesystem->removeDirectory($this->config->get('vendor-dir')); + } + if ($this->filesystem->isDirEmpty($path)) { + $this->filesystem->removeDirectory($path); + } } /** @@ -302,7 +316,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface */ protected function getFileName(PackageInterface $package, $path) { - return $path.'_'.pathinfo(parse_url($package->getDistUrl(), PHP_URL_PATH), PATHINFO_BASENAME); + return rtrim($this->config->get('vendor-dir').'/composer/'.md5($package.spl_object_hash($package)).'.'.pathinfo(parse_url($package->getDistUrl(), PHP_URL_PATH), PATHINFO_EXTENSION), '.'); } /** diff --git a/tests/Composer/Test/Downloader/ArchiveDownloaderTest.php b/tests/Composer/Test/Downloader/ArchiveDownloaderTest.php index 360539859..793c5eab5 100644 --- a/tests/Composer/Test/Downloader/ArchiveDownloaderTest.php +++ b/tests/Composer/Test/Downloader/ArchiveDownloaderTest.php @@ -16,6 +16,8 @@ use Composer\Test\TestCase; class ArchiveDownloaderTest extends TestCase { + protected $config; + public function testGetFileName() { $packageMock = $this->getMockBuilder('Composer\Package\PackageInterface')->getMock(); @@ -28,8 +30,13 @@ class ArchiveDownloaderTest extends TestCase $method = new \ReflectionMethod($downloader, 'getFileName'); $method->setAccessible(true); + $this->config->expects($this->any()) + ->method('get') + ->with('vendor-dir') + ->will($this->returnValue('/vendor')); + $first = $method->invoke($downloader, $packageMock, '/path'); - $this->assertRegExp('#/path_[a-z0-9]+\.js#', $first); + $this->assertRegExp('#/vendor/composer/[a-z0-9]+\.js#', $first); $this->assertSame($first, $method->invoke($downloader, $packageMock, '/path')); } @@ -158,8 +165,8 @@ class ArchiveDownloaderTest extends TestCase 'Composer\Downloader\ArchiveDownloader', array( $io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock(), - $config = $this->getMockBuilder('Composer\Config')->getMock(), - new \Composer\Util\HttpDownloader($io, $config), + $this->config = $this->getMockBuilder('Composer\Config')->getMock(), + new \Composer\Util\HttpDownloader($io, $this->config), ) ); } diff --git a/tests/Composer/Test/Downloader/FileDownloaderTest.php b/tests/Composer/Test/Downloader/FileDownloaderTest.php index 2366df770..af5a9da11 100644 --- a/tests/Composer/Test/Downloader/FileDownloaderTest.php +++ b/tests/Composer/Test/Downloader/FileDownloaderTest.php @@ -21,11 +21,12 @@ use Composer\Util\Loop; class FileDownloaderTest extends TestCase { private $httpDownloader; + private $config; protected function getDownloader($io = null, $config = null, $eventDispatcher = null, $cache = null, $httpDownloader = null, $filesystem = null) { $io = $io ?: $this->getMockBuilder('Composer\IO\IOInterface')->getMock(); - $config = $config ?: $this->getMockBuilder('Composer\Config')->getMock(); + $this->config = $config ?: $this->getMockBuilder('Composer\Config')->getMock(); $httpDownloader = $httpDownloader ?: $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock(); $httpDownloader ->expects($this->any()) @@ -33,7 +34,7 @@ class FileDownloaderTest extends TestCase ->will($this->returnValue(\React\Promise\resolve(new Response(array('url' => 'http://example.org/'), 200, array(), 'file~')))); $this->httpDownloader = $httpDownloader; - return new FileDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $filesystem); + return new FileDownloader($io, $this->config, $httpDownloader, $eventDispatcher, $cache, $filesystem); } /** @@ -54,11 +55,11 @@ class FileDownloaderTest extends TestCase public function testDownloadToExistingFile() { $packageMock = $this->getMockBuilder('Composer\Package\PackageInterface')->getMock(); - $packageMock->expects($this->once()) + $packageMock->expects($this->any()) ->method('getDistUrl') ->will($this->returnValue('url')) ; - $packageMock->expects($this->once()) + $packageMock->expects($this->any()) ->method('getDistUrls') ->will($this->returnValue(array('url'))) ; @@ -93,7 +94,12 @@ class FileDownloaderTest extends TestCase $method = new \ReflectionMethod($downloader, 'getFileName'); $method->setAccessible(true); - $this->assertEquals('/path_script.js', $method->invoke($downloader, $packageMock, '/path')); + $this->config->expects($this->once()) + ->method('get') + ->with('vendor-dir') + ->will($this->returnValue('/vendor')); + + $this->assertRegExp('#/vendor/composer/[a-z0-9]+\.js#', $method->invoke($downloader, $packageMock, '/path')); } public function testDownloadButFileIsUnsaved() @@ -126,6 +132,12 @@ class FileDownloaderTest extends TestCase ; $downloader = $this->getDownloader($ioMock); + + $this->config->expects($this->once()) + ->method('get') + ->with('vendor-dir') + ->will($this->returnValue($path.'/vendor')); + try { $promise = $downloader->download($packageMock, $path); $loop = new Loop($this->httpDownloader); @@ -199,8 +211,18 @@ class FileDownloaderTest extends TestCase $path = $this->getUniqueTmpDirectory(); $downloader = $this->getDownloader(null, null, null, null, null, $filesystem); + // make sure the file expected to be downloaded is on disk already - touch($path.'_script.js'); + $this->config->expects($this->any()) + ->method('get') + ->with('vendor-dir') + ->will($this->returnValue($path.'/vendor')); + + $method = new \ReflectionMethod($downloader, 'getFileName'); + $method->setAccessible(true); + $dlFile = $method->invoke($downloader, $packageMock, $path); + mkdir(dirname($dlFile), 0777, true); + touch($dlFile); try { $promise = $downloader->download($packageMock, $path); @@ -255,13 +277,25 @@ class FileDownloaderTest extends TestCase ->with($this->stringContains('Downgrading')); $path = $this->getUniqueTmpDirectory(); - touch($path.'_script.js'); $filesystem = $this->getMockBuilder('Composer\Util\Filesystem')->getMock(); $filesystem->expects($this->once()) ->method('removeDirectory') ->will($this->returnValue(true)); $downloader = $this->getDownloader($ioMock, null, null, null, null, $filesystem); + + // make sure the file expected to be downloaded is on disk already + $this->config->expects($this->any()) + ->method('get') + ->with('vendor-dir') + ->will($this->returnValue($path.'/vendor')); + + $method = new \ReflectionMethod($downloader, 'getFileName'); + $method->setAccessible(true); + $dlFile = $method->invoke($downloader, $newPackage, $path); + mkdir(dirname($dlFile), 0777, true); + touch($dlFile); + $promise = $downloader->download($newPackage, $path, $oldPackage); $loop = new Loop($this->httpDownloader); $loop->wait(array($promise)); diff --git a/tests/Composer/Test/Downloader/XzDownloaderTest.php b/tests/Composer/Test/Downloader/XzDownloaderTest.php index 4c2fdb2af..f770b0d35 100644 --- a/tests/Composer/Test/Downloader/XzDownloaderTest.php +++ b/tests/Composer/Test/Downloader/XzDownloaderTest.php @@ -70,10 +70,10 @@ class XzDownloaderTest extends TestCase $downloader = new XzDownloader($io, $config, $httpDownloader = new HttpDownloader($io, $this->getMockBuilder('Composer\Config')->getMock()), null, null, null); try { - $promise = $downloader->download($packageMock, $this->testDir); + $promise = $downloader->download($packageMock, $this->testDir.'/install-path'); $loop = new Loop($httpDownloader); $loop->wait(array($promise)); - $downloader->install($packageMock, $this->testDir); + $downloader->install($packageMock, $this->testDir.'/install-path'); $this->fail('Download of invalid tarball should throw an exception'); } catch (\RuntimeException $e) { diff --git a/tests/Composer/Test/Downloader/ZipDownloaderTest.php b/tests/Composer/Test/Downloader/ZipDownloaderTest.php index eb57e67df..e3bbe45a8 100644 --- a/tests/Composer/Test/Downloader/ZipDownloaderTest.php +++ b/tests/Composer/Test/Downloader/ZipDownloaderTest.php @@ -69,7 +69,7 @@ class ZipDownloaderTest extends TestCase $this->markTestSkipped('zip extension missing'); } - $this->config->expects($this->at(0)) + $this->config->expects($this->any()) ->method('get') ->with('vendor-dir') ->will($this->returnValue($this->testDir));