From d57e2b9ffb229c3828628253ee06982811f011eb Mon Sep 17 00:00:00 2001 From: Jan Prieser Date: Mon, 13 Jan 2014 17:14:12 +0100 Subject: [PATCH 01/12] added ZipArchiver to actually compress zip files --- src/Composer/Factory.php | 1 + src/Composer/Package/Archiver/ZipArchiver.php | 65 +++++++++++++++++++ .../Test/Package/Archiver/ZipArchiverTest.php | 64 ++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 src/Composer/Package/Archiver/ZipArchiver.php create mode 100644 tests/Composer/Test/Package/Archiver/ZipArchiverTest.php diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index f829cb459..1514dfbc2 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -386,6 +386,7 @@ class Factory } $am = new Archiver\ArchiveManager($dm); + $am->addArchiver(new Archiver\ZipArchiver); $am->addArchiver(new Archiver\PharArchiver); return $am; diff --git a/src/Composer/Package/Archiver/ZipArchiver.php b/src/Composer/Package/Archiver/ZipArchiver.php new file mode 100644 index 000000000..aaf42ed56 --- /dev/null +++ b/src/Composer/Package/Archiver/ZipArchiver.php @@ -0,0 +1,65 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Package\Archiver; + +use ZipArchive; + +/** + * @author Jan Prieser + */ +class ZipArchiver implements ArchiverInterface +{ + protected static $formats = array( + 'zip' => 1 + ); + + /** + * {@inheritdoc} + */ + public function archive($sources, $target, $format, array $excludes = array()) + { + $sources = realpath($sources); + $zip = new ZipArchive(); + $res = $zip->open($target, ZipArchive::CREATE); + if ($res === true) { + $files = new ArchivableFilesFinder($sources, $excludes); + foreach($files as $file) { + /** @var $file \SplFileInfo */ + $filepath = $file->getPath()."/".$file->getFilename(); + $localname = str_replace($sources."/", '', $filepath); + $zip->addFile($filepath, $localname); + } + if ($zip->close()) { + return $target; + } + } + $message = sprintf("Could not create archive '%s' from '%s': %s", + $target, + $sources, + $zip->getStatusString() + ); + throw new \RuntimeException($message); + } + + /** + * {@inheritdoc} + */ + public function supports($format, $sourceType) + { + return isset(static::$formats[$format]) && $this->compressionAvailable(); + } + + private function compressionAvailable() { + return class_exists('ZipArchive'); + } +} diff --git a/tests/Composer/Test/Package/Archiver/ZipArchiverTest.php b/tests/Composer/Test/Package/Archiver/ZipArchiverTest.php new file mode 100644 index 000000000..13168573a --- /dev/null +++ b/tests/Composer/Test/Package/Archiver/ZipArchiverTest.php @@ -0,0 +1,64 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Test\Package\Archiver; + +use Composer\Package\Archiver\ZipArchiver; + +class ZipArchiverTest extends ArchiverTest +{ + + public function testZipArchive() + { + // Set up repository + $this->setupDummyRepo(); + $package = $this->setupPackage(); + $target = sys_get_temp_dir().'/composer_archiver_test.zip'; + + // Test archive + $archiver = new ZipArchiver(); + $archiver->archive($package->getSourceUrl(), $target, 'zip'); + $this->assertFileExists($target); + + unlink($target); + } + + /** + * Create a local dummy repository to run tests against! + */ + protected function setupDummyRepo() + { + $currentWorkDir = getcwd(); + chdir($this->testDir); + + $this->writeFile('file.txt', 'content', $currentWorkDir); + $this->writeFile('foo/bar/baz', 'content', $currentWorkDir); + $this->writeFile('foo/bar/ignoreme', 'content', $currentWorkDir); + $this->writeFile('x/baz', 'content', $currentWorkDir); + $this->writeFile('x/includeme', 'content', $currentWorkDir); + + chdir($currentWorkDir); + } + + protected function writeFile($path, $content, $currentWorkDir) + { + if (!file_exists(dirname($path))) { + mkdir(dirname($path), 0777, true); + } + + $result = file_put_contents($path, 'a'); + if (false === $result) { + chdir($currentWorkDir); + throw new \RuntimeException('Could not save file.'); + } + } +} From 3979abc638796b52edbf754290497a6cc58712f4 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Tue, 26 Jan 2016 22:05:35 +0000 Subject: [PATCH 02/12] Add warning if OpenSSL does not support TLSv1.2 or TLSv1.1 --- src/Composer/Command/DiagnoseCommand.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Composer/Command/DiagnoseCommand.php b/src/Composer/Command/DiagnoseCommand.php index 2306b138a..c78c808e1 100644 --- a/src/Composer/Command/DiagnoseCommand.php +++ b/src/Composer/Command/DiagnoseCommand.php @@ -453,6 +453,10 @@ EOT $errors['openssl'] = true; } + if (extension_loaded('openssl') && OPENSSL_VERSION_NUMBER < 0x1000100f) { + $warnings['openssl_version'] = true; + } + if (!defined('HHVM_VERSION') && !extension_loaded('apcu') && ini_get('apc.enable_cli')) { $warnings['apc_cli'] = true; } @@ -570,6 +574,16 @@ EOT $text .= " Composer works with 5.3.2+ for most people, but there might be edge case issues."; break; + case 'openssl_version': + // Attempt to parse version number out, fallback to whole string value. + $opensslVersion = trim(strstr(OPENSSL_VERSION_TEXT, ' ')); + $opensslVersion = substr($opensslVersion, 0, strpos($opensslVersion, ' ')); + $opensslVersion = $opensslVersion ? $opensslVersion : OPENSSL_VERSION_TEXT; + + $text = "The OpenSSL library ({$opensslVersion}) used by PHP does not support TLSv1.2 or TLSv1.1.".PHP_EOL; + $text .= "If possible you should upgrade OpenSSL to version 1.0.1 or above."; + break; + case 'xdebug_loaded': $text = "The xdebug extension is loaded, this can slow down Composer a little.".PHP_EOL; $text .= " Disabling it when using Composer is recommended."; From 0a25bb0bf39e5dc00edb62b7bae9dfa93c365a88 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Wed, 27 Jan 2016 08:57:28 +0000 Subject: [PATCH 03/12] Simplify for PHP 5.3 --- src/Composer/Command/DiagnoseCommand.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Composer/Command/DiagnoseCommand.php b/src/Composer/Command/DiagnoseCommand.php index c78c808e1..2b1927f6b 100644 --- a/src/Composer/Command/DiagnoseCommand.php +++ b/src/Composer/Command/DiagnoseCommand.php @@ -576,9 +576,8 @@ EOT case 'openssl_version': // Attempt to parse version number out, fallback to whole string value. - $opensslVersion = trim(strstr(OPENSSL_VERSION_TEXT, ' ')); - $opensslVersion = substr($opensslVersion, 0, strpos($opensslVersion, ' ')); - $opensslVersion = $opensslVersion ? $opensslVersion : OPENSSL_VERSION_TEXT; + $opensslVersion = strstr(trim(strstr(OPENSSL_VERSION_TEXT, ' ')), ' ', true); + $opensslVersion = $opensslVersion ?: OPENSSL_VERSION_TEXT; $text = "The OpenSSL library ({$opensslVersion}) used by PHP does not support TLSv1.2 or TLSv1.1.".PHP_EOL; $text .= "If possible you should upgrade OpenSSL to version 1.0.1 or above."; From 94daeca57b87da6762116bd85861adc722bfa0df Mon Sep 17 00:00:00 2001 From: Rob Bast Date: Fri, 5 Feb 2016 11:39:14 +0100 Subject: [PATCH 04/12] add test and adjust rule error message --- src/Composer/DependencyResolver/Rule.php | 4 +- .../installer/github-issues-4319.test | 45 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 tests/Composer/Test/Fixtures/installer/github-issues-4319.test diff --git a/src/Composer/DependencyResolver/Rule.php b/src/Composer/DependencyResolver/Rule.php index 13bbb7e09..32546fd27 100644 --- a/src/Composer/DependencyResolver/Rule.php +++ b/src/Composer/DependencyResolver/Rule.php @@ -207,7 +207,9 @@ class Rule } elseif ($targetName === 'hhvm') { $text .= ' -> you are running this with PHP and not HHVM.'; } else { - $text .= ' -> your PHP version ('. phpversion() .') or value of "config.platform.php" in composer.json does not satisfy that requirement.'; + $available = $pool->whatProvides($targetName); + $version = count($available) ? $available[0]->getPrettyVersion() : phpversion(); + $text .= ' -> your PHP version or "config.platform.php" value ('.$version.') does not satisfy that requirement.'; } } elseif (0 === strpos($targetName, 'ext-')) { // handle php extensions diff --git a/tests/Composer/Test/Fixtures/installer/github-issues-4319.test b/tests/Composer/Test/Fixtures/installer/github-issues-4319.test new file mode 100644 index 000000000..5bfc17af6 --- /dev/null +++ b/tests/Composer/Test/Fixtures/installer/github-issues-4319.test @@ -0,0 +1,45 @@ +--TEST-- + +See Github issue #4319 ( github.com/composer/composer/issues/4319 ). + +Present a clear error message when config.platform.php version results in a conflict rule. + +--CONDITION-- +!defined('HHVM_VERSION') + +--COMPOSER-- +{ + "repositories": [ + { + "type": "package", + "package": [ + { "name": "a", "version": "1.0.0", "require": { "php": "5.5" } } + ] + } + ], + "require": { + "a": "~1.0" + }, + "config": { + "platform": { + "php": "5.3" + } + } +} + +--RUN-- +install + +--EXPECT-OUTPUT-- +Loading composer repositories with package information +Installing dependencies (including require-dev) +Your requirements could not be resolved to an installable set of packages. + + Problem 1 + - Installation request for a ~1.0 -> satisfiable by a[1.0.0]. + - a 1.0.0 requires php 5.5 -> your PHP version or "config.platform.php" value (5.3) does not satisfy that requirement. + +--EXPECT-- + +--EXPECT-EXIT-CODE-- +2 From baabc612f672b45eb74d6884e835360bbaabcc2e Mon Sep 17 00:00:00 2001 From: Rob Bast Date: Fri, 5 Feb 2016 13:21:30 +0100 Subject: [PATCH 05/12] adjust message, skip test currently we have no way to put dynamic values or wildcards in EXPECT-OUTPUT --- src/Composer/DependencyResolver/Rule.php | 31 ++++++++++++++----- .../Repository/PlatformRepository.php | 1 + ...9.test => github-issues-4319.test.skipped} | 2 +- 3 files changed, 25 insertions(+), 9 deletions(-) rename tests/Composer/Test/Fixtures/installer/{github-issues-4319.test => github-issues-4319.test.skipped} (85%) diff --git a/src/Composer/DependencyResolver/Rule.php b/src/Composer/DependencyResolver/Rule.php index 32546fd27..54a002203 100644 --- a/src/Composer/DependencyResolver/Rule.php +++ b/src/Composer/DependencyResolver/Rule.php @@ -12,6 +12,8 @@ namespace Composer\DependencyResolver; +use Composer\Package\CompletePackage; + /** * @author Nils Adermann */ @@ -203,27 +205,40 @@ class Rule if ($targetName === 'php' || $targetName === 'php-64bit' || $targetName === 'hhvm') { // handle php/hhvm if (defined('HHVM_VERSION')) { - $text .= ' -> your HHVM version does not satisfy that requirement.'; + return $text . ' -> your HHVM version does not satisfy that requirement.'; } elseif ($targetName === 'hhvm') { - $text .= ' -> you are running this with PHP and not HHVM.'; + return $text . ' -> you are running this with PHP and not HHVM.'; } else { - $available = $pool->whatProvides($targetName); - $version = count($available) ? $available[0]->getPrettyVersion() : phpversion(); - $text .= ' -> your PHP version or "config.platform.php" value ('.$version.') does not satisfy that requirement.'; + $packages = $pool->whatProvides($targetName); + $package = count($packages) ? current($packages) : phpversion(); + + if (!($package instanceof CompletePackage)) { + return $text . ' -> your PHP version ('.phpversion().') does not satisfy that requirement.'; + } + + $extra = $package->getExtra(); + + if (!empty($extra['config.platform'])) { + $text .= ' -> your PHP version ('.phpversion().') overriden by "config.platform.php" version ('.$package->getPrettyVersion().') does not satisfy that requirement.'; + } else { + $text .= ' -> your PHP version ('.$package->getPrettyVersion().') does not satisfy that requirement.'; + } + + return $text; } } elseif (0 === strpos($targetName, 'ext-')) { // handle php extensions $ext = substr($targetName, 4); $error = extension_loaded($ext) ? 'has the wrong version ('.(phpversion($ext) ?: '0').') installed' : 'is missing from your system'; - $text .= ' -> the requested PHP extension '.$ext.' '.$error.'.'; + return $text . ' -> the requested PHP extension '.$ext.' '.$error.'.'; } elseif (0 === strpos($targetName, 'lib-')) { // handle linked libs $lib = substr($targetName, 4); - $text .= ' -> the requested linked library '.$lib.' has the wrong version installed or is missing from your system, make sure to have the extension providing it.'; + return $text . ' -> the requested linked library '.$lib.' has the wrong version installed or is missing from your system, make sure to have the extension providing it.'; } else { - $text .= ' -> no matching package found.'; + return $text . ' -> no matching package found.'; } } diff --git a/src/Composer/Repository/PlatformRepository.php b/src/Composer/Repository/PlatformRepository.php index 27f52aa65..5016335b0 100644 --- a/src/Composer/Repository/PlatformRepository.php +++ b/src/Composer/Repository/PlatformRepository.php @@ -59,6 +59,7 @@ class PlatformRepository extends ArrayRepository $version = $versionParser->normalize($override['version']); $package = new CompletePackage($override['name'], $version, $override['version']); $package->setDescription('Package overridden via config.platform'); + $package->setExtra(array('config.platform' => true)); parent::addPackage($package); } diff --git a/tests/Composer/Test/Fixtures/installer/github-issues-4319.test b/tests/Composer/Test/Fixtures/installer/github-issues-4319.test.skipped similarity index 85% rename from tests/Composer/Test/Fixtures/installer/github-issues-4319.test rename to tests/Composer/Test/Fixtures/installer/github-issues-4319.test.skipped index 5bfc17af6..3833bcf9b 100644 --- a/tests/Composer/Test/Fixtures/installer/github-issues-4319.test +++ b/tests/Composer/Test/Fixtures/installer/github-issues-4319.test.skipped @@ -37,7 +37,7 @@ Your requirements could not be resolved to an installable set of packages. Problem 1 - Installation request for a ~1.0 -> satisfiable by a[1.0.0]. - - a 1.0.0 requires php 5.5 -> your PHP version or "config.platform.php" value (5.3) does not satisfy that requirement. + - a 1.0.0 requires php 5.5 -> your PHP version (5.6.17) overriden by "config.platform.php" version (5.3) does not satisfy that requirement. --EXPECT-- From baa84d9be1477b2db7d964a6b52aae8302fbfc1d Mon Sep 17 00:00:00 2001 From: Rob Bast Date: Fri, 5 Feb 2016 13:34:21 +0100 Subject: [PATCH 06/12] adjust test and assertion to be more flexible --- .../Test/Fixtures/installer/github-issues-4319.test.skipped | 2 +- tests/Composer/Test/InstallerTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Composer/Test/Fixtures/installer/github-issues-4319.test.skipped b/tests/Composer/Test/Fixtures/installer/github-issues-4319.test.skipped index 3833bcf9b..56536ed72 100644 --- a/tests/Composer/Test/Fixtures/installer/github-issues-4319.test.skipped +++ b/tests/Composer/Test/Fixtures/installer/github-issues-4319.test.skipped @@ -37,7 +37,7 @@ Your requirements could not be resolved to an installable set of packages. Problem 1 - Installation request for a ~1.0 -> satisfiable by a[1.0.0]. - - a 1.0.0 requires php 5.5 -> your PHP version (5.6.17) overriden by "config.platform.php" version (5.3) does not satisfy that requirement. + - a 1.0.0 requires php 5.5 -> your PHP version (%s) overriden by "config.platform.php" version (5.3) does not satisfy that requirement. --EXPECT-- diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php index eaf6caa03..5aa9f862e 100644 --- a/tests/Composer/Test/InstallerTest.php +++ b/tests/Composer/Test/InstallerTest.php @@ -252,7 +252,7 @@ class InstallerTest extends TestCase $this->assertSame(rtrim($expect), implode("\n", $installationManager->getTrace())); if ($expectOutput) { - $this->assertEquals(rtrim($expectOutput), rtrim($output)); + $this->assertStringMatchesFormat(rtrim($expectOutput), rtrim($output)); } } From 5db0f623b01d802b20dc49ad9d430a43b668cbf7 Mon Sep 17 00:00:00 2001 From: Rob Bast Date: Fri, 5 Feb 2016 13:36:53 +0100 Subject: [PATCH 07/12] enable test again --- .../{github-issues-4319.test.skipped => github-issues-4319.test} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/Composer/Test/Fixtures/installer/{github-issues-4319.test.skipped => github-issues-4319.test} (100%) diff --git a/tests/Composer/Test/Fixtures/installer/github-issues-4319.test.skipped b/tests/Composer/Test/Fixtures/installer/github-issues-4319.test similarity index 100% rename from tests/Composer/Test/Fixtures/installer/github-issues-4319.test.skipped rename to tests/Composer/Test/Fixtures/installer/github-issues-4319.test From c2d99608988e7892a4c67f0c57c0fdb68de2d4b1 Mon Sep 17 00:00:00 2001 From: Niels Keurentjes Date: Sat, 6 Feb 2016 02:00:54 +0100 Subject: [PATCH 08/12] Ensure exception is thrown when classmaps are requested for corrupted or binary files. Refs #4885 --- src/Composer/Autoload/ClassMapGenerator.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Composer/Autoload/ClassMapGenerator.php b/src/Composer/Autoload/ClassMapGenerator.php index 3f1243ade..539eb77a0 100644 --- a/src/Composer/Autoload/ClassMapGenerator.php +++ b/src/Composer/Autoload/ClassMapGenerator.php @@ -123,14 +123,14 @@ class ClassMapGenerator } try { - $contents = Silencer::call('php_strip_whitespace', $path); + $contents = @php_strip_whitespace($path); if (!$contents) { if (!file_exists($path)) { - throw new \Exception('File does not exist'); - } - if (!is_readable($path)) { - throw new \Exception('File is not readable'); + throw new \RuntimeException(sprintf('File at "%s" does not exist, check your classmap definitions', $path)); + } elseif (!is_readable($path)) { + throw new \RuntimeException(sprintf('File at "%s" is not readable, check its permissions', $path)); } + throw new \RuntimeException(sprintf('File at "%s" could not be parsed as PHP - it may be binary or corrupted', $path)); } } catch (\Exception $e) { throw new \RuntimeException('Could not scan for classes inside '.$path.": \n".$e->getMessage(), 0, $e); From 86fc85fe56c0cb8336c9628fd719c0134360f27b Mon Sep 17 00:00:00 2001 From: Niels Keurentjes Date: Sat, 6 Feb 2016 02:04:48 +0100 Subject: [PATCH 09/12] Add a comment explaining the use of @ instead of Silencer in this specific situation. --- src/Composer/Autoload/ClassMapGenerator.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Composer/Autoload/ClassMapGenerator.php b/src/Composer/Autoload/ClassMapGenerator.php index 539eb77a0..3ad26f7f2 100644 --- a/src/Composer/Autoload/ClassMapGenerator.php +++ b/src/Composer/Autoload/ClassMapGenerator.php @@ -123,6 +123,8 @@ class ClassMapGenerator } try { + // Use @ here instead of Silencer to actively suppress 'unhelpful' output + // @link https://github.com/composer/composer/pull/4886 $contents = @php_strip_whitespace($path); if (!$contents) { if (!file_exists($path)) { From bb08f76ad99142e4253b7ac90294fe1dbc266579 Mon Sep 17 00:00:00 2001 From: Niels Keurentjes Date: Sat, 6 Feb 2016 02:32:08 +0100 Subject: [PATCH 10/12] Use error_get_last to verify why php_strip_whitespace would return an empty string. --- src/Composer/Autoload/ClassMapGenerator.php | 26 ++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Composer/Autoload/ClassMapGenerator.php b/src/Composer/Autoload/ClassMapGenerator.php index 3ad26f7f2..9bacee580 100644 --- a/src/Composer/Autoload/ClassMapGenerator.php +++ b/src/Composer/Autoload/ClassMapGenerator.php @@ -122,20 +122,20 @@ class ClassMapGenerator $extraTypes .= '|enum'; } - try { - // Use @ here instead of Silencer to actively suppress 'unhelpful' output - // @link https://github.com/composer/composer/pull/4886 - $contents = @php_strip_whitespace($path); - if (!$contents) { - if (!file_exists($path)) { - throw new \RuntimeException(sprintf('File at "%s" does not exist, check your classmap definitions', $path)); - } elseif (!is_readable($path)) { - throw new \RuntimeException(sprintf('File at "%s" is not readable, check its permissions', $path)); - } - throw new \RuntimeException(sprintf('File at "%s" could not be parsed as PHP - it may be binary or corrupted', $path)); + // Use @ here instead of Silencer to actively suppress 'unhelpful' output + // @link https://github.com/composer/composer/pull/4886 + error_clear_last(); + $contents = @php_strip_whitespace($path); + if (!$contents) { + if (is_null(error_get_last())) { + // No error, so the input file was really empty or contained only comments + return array(); + } elseif (!file_exists($path)) { + throw new \RuntimeException(sprintf('File at "%s" does not exist, check your classmap definitions', $path)); + } elseif (!is_readable($path)) { + throw new \RuntimeException(sprintf('File at "%s" is not readable, check its permissions', $path)); } - } catch (\Exception $e) { - throw new \RuntimeException('Could not scan for classes inside '.$path.": \n".$e->getMessage(), 0, $e); + throw new \RuntimeException(sprintf('File at "%s" could not be parsed as PHP - it may be binary or corrupted', $path)); } // return early if there is no chance of matching anything in this file From 6a53b1df42e124a95d12a5e6c953fa28ae0c8235 Mon Sep 17 00:00:00 2001 From: Niels Keurentjes Date: Sat, 6 Feb 2016 02:40:16 +0100 Subject: [PATCH 11/12] Further reorganized messy checking code. --- src/Composer/Autoload/ClassMapGenerator.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Composer/Autoload/ClassMapGenerator.php b/src/Composer/Autoload/ClassMapGenerator.php index 9bacee580..818367c98 100644 --- a/src/Composer/Autoload/ClassMapGenerator.php +++ b/src/Composer/Autoload/ClassMapGenerator.php @@ -127,15 +127,21 @@ class ClassMapGenerator error_clear_last(); $contents = @php_strip_whitespace($path); if (!$contents) { - if (is_null(error_get_last())) { - // No error, so the input file was really empty or contained only comments + $error = error_get_last(); + if (is_null($error)) { + // No error, so the input file was really empty and thus contains no classes return array(); } elseif (!file_exists($path)) { - throw new \RuntimeException(sprintf('File at "%s" does not exist, check your classmap definitions', $path)); + $message = 'File at "%s" does not exist, check your classmap definitions'; } elseif (!is_readable($path)) { - throw new \RuntimeException(sprintf('File at "%s" is not readable, check its permissions', $path)); + $message = 'File at "%s" is not readable, check its permissions'; + } else { + $message = 'File at "%s" could not be parsed as PHP, it may be binary or corrupted'; } - throw new \RuntimeException(sprintf('File at "%s" could not be parsed as PHP - it may be binary or corrupted', $path)); + if (isset($error['message'])) { + $message .= PHP_EOL . 'The following message may be helpful:' . PHP_EOL . $error['message']; + } + throw new \RuntimeException(sprintf($message, $path)); } // return early if there is no chance of matching anything in this file From 0b55a0ca9122abfd7ede51d67f5defe4dfd64daf Mon Sep 17 00:00:00 2001 From: Niels Keurentjes Date: Sat, 6 Feb 2016 02:58:36 +0100 Subject: [PATCH 12/12] Can't use error_clear_last as it was introduced in PHP7. --- src/Composer/Autoload/ClassMapGenerator.php | 11 +++++------ .../Composer/Test/Autoload/ClassMapGeneratorTest.php | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Composer/Autoload/ClassMapGenerator.php b/src/Composer/Autoload/ClassMapGenerator.php index 818367c98..59542a4a7 100644 --- a/src/Composer/Autoload/ClassMapGenerator.php +++ b/src/Composer/Autoload/ClassMapGenerator.php @@ -124,20 +124,19 @@ class ClassMapGenerator // Use @ here instead of Silencer to actively suppress 'unhelpful' output // @link https://github.com/composer/composer/pull/4886 - error_clear_last(); $contents = @php_strip_whitespace($path); if (!$contents) { - $error = error_get_last(); - if (is_null($error)) { - // No error, so the input file was really empty and thus contains no classes - return array(); - } elseif (!file_exists($path)) { + if (!file_exists($path)) { $message = 'File at "%s" does not exist, check your classmap definitions'; } elseif (!is_readable($path)) { $message = 'File at "%s" is not readable, check its permissions'; + } elseif ('' === trim(file_get_contents($path))) { + // The input file was really empty and thus contains no classes + return array(); } else { $message = 'File at "%s" could not be parsed as PHP, it may be binary or corrupted'; } + $error = error_get_last(); if (isset($error['message'])) { $message .= PHP_EOL . 'The following message may be helpful:' . PHP_EOL . $error['message']; } diff --git a/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php b/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php index cd3d43260..13cf7cd83 100644 --- a/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php +++ b/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php @@ -113,7 +113,7 @@ class ClassMapGeneratorTest extends TestCase /** * @expectedException \RuntimeException - * @expectedExceptionMessage Could not scan for classes inside + * @expectedExceptionMessage does not exist */ public function testFindClassesThrowsWhenFileDoesNotExist() {