diff --git a/src/Composer/Repository/ArtifactRepository.php b/src/Composer/Repository/ArtifactRepository.php index a0acb7a61..f8b068218 100644 --- a/src/Composer/Repository/ArtifactRepository.php +++ b/src/Composer/Repository/ArtifactRepository.php @@ -88,7 +88,12 @@ class ArtifactRepository extends ArrayRepository implements ConfigurableReposito private function getComposerInformation(\SplFileInfo $file) { - $json = Zip::getComposerJson($file->getPathname()); + $json = null; + try { + $json = Zip::getComposerJson($file->getPathname()); + } catch (\Exception $exception) { + $this->io->write('Failed loading package '.$file->getPathname().': '.$exception->getMessage(), false, IOInterface::VERBOSE); + } if (null === $json) { return false; diff --git a/src/Composer/Util/Zip.php b/src/Composer/Util/Zip.php index 3ebdcdd85..ad6617edf 100644 --- a/src/Composer/Util/Zip.php +++ b/src/Composer/Util/Zip.php @@ -66,8 +66,9 @@ class Zip * * @param \ZipArchive $zip * @param string $filename + * @throws \RuntimeException * - * @return bool|int + * @return int */ private static function locateFile(\ZipArchive $zip, $filename) { @@ -85,8 +86,7 @@ class Zip if ($dirname === '.') { $topLevelPaths[$name] = true; if (\count($topLevelPaths) > 1) { - // archive can only contain one top level directory - return false; + throw new \RuntimeException('Archive has more than one top level directories, and no composer.json was found on the top level, so it\'s an invalid archive. Top level paths found were: '.implode(',', array_keys($topLevelPaths))); } continue; } @@ -95,8 +95,7 @@ class Zip if (false === strpos('\\', $dirname) && false === strpos('/', $dirname)) { $topLevelPaths[$dirname.'/'] = true; if (\count($topLevelPaths) > 1) { - // archive can only contain one top level directory - return false; + throw new \RuntimeException('Archive has more than one top level directories, and no composer.json was found on the top level, so it\'s an invalid archive. Top level paths found were: '.implode(',', array_keys($topLevelPaths))); } } } @@ -105,7 +104,6 @@ class Zip return $index; } - // no composer.json found either at the top level or within the topmost directory - return false; + throw new \RuntimeException('No composer.json found either at the top level or within the topmost directory'); } } diff --git a/tests/Composer/Test/Util/Fixtures/Zip/multiple_subfolders.zip b/tests/Composer/Test/Util/Fixtures/Zip/multiple_subfolders.zip new file mode 100644 index 000000000..5c5bc5adf Binary files /dev/null and b/tests/Composer/Test/Util/Fixtures/Zip/multiple_subfolders.zip differ diff --git a/tests/Composer/Test/Util/ZipTest.php b/tests/Composer/Test/Util/ZipTest.php index 78c7e9657..ba61e8bf6 100644 --- a/tests/Composer/Test/Util/ZipTest.php +++ b/tests/Composer/Test/Util/ZipTest.php @@ -55,28 +55,30 @@ class ZipTest extends TestCase $this->assertNull($result); } - public function testReturnsNullIfTheZipHasNoComposerJson() + /** + * @expectedException \RuntimeException + */ + public function testThrowsExceptionIfTheZipHasNoComposerJson() { if (!extension_loaded('zip')) { $this->markTestSkipped('The PHP zip extension is not loaded.'); return; } - $result = Zip::getComposerJson(__DIR__.'/Fixtures/Zip/nojson.zip'); - - $this->assertNull($result); + Zip::getComposerJson(__DIR__.'/Fixtures/Zip/nojson.zip'); } - public function testReturnsNullIfTheComposerJsonIsInASubSubfolder() + /** + * @expectedException \RuntimeException + */ + public function testThrowsExceptionIfTheComposerJsonIsInASubSubfolder() { if (!extension_loaded('zip')) { $this->markTestSkipped('The PHP zip extension is not loaded.'); return; } - $result = Zip::getComposerJson(__DIR__.'/Fixtures/Zip/subfolders.zip'); - - $this->assertNull($result); + Zip::getComposerJson(__DIR__.'/Fixtures/Zip/subfolders.zip'); } public function testReturnsComposerJsonInZipRoot() @@ -99,10 +101,12 @@ class ZipTest extends TestCase } $result = Zip::getComposerJson(__DIR__.'/Fixtures/Zip/folder.zip'); - $this->assertEquals("{\n \"name\": \"foo/bar\"\n}\n", $result); } + /** + * @expectedException \RuntimeException + */ public function testMultipleTopLevelDirsIsInvalid() { if (!extension_loaded('zip')) { @@ -110,9 +114,7 @@ class ZipTest extends TestCase return; } - $result = Zip::getComposerJson(__DIR__.'/Fixtures/Zip/multiple.zip'); - - $this->assertNull($result); + Zip::getComposerJson(__DIR__.'/Fixtures/Zip/multiple.zip'); } public function testReturnsComposerJsonFromFirstSubfolder() @@ -126,4 +128,17 @@ class ZipTest extends TestCase $this->assertEquals("{\n \"name\": \"foo/bar\"\n}\n", $result); } + + /** + * @expectedException \RuntimeException + */ + public function testThrowsExceptionIfMultipleComposerInSubFoldersWereFound() + { + if (!extension_loaded('zip')) { + $this->markTestSkipped('The PHP zip extension is not loaded.'); + return; + } + + Zip::getComposerJson(__DIR__.'/Fixtures/Zip/multiple_subfolders.zip'); + } }