diff --git a/CHANGELOG.md b/CHANGELOG.md index 36ceddfc9..c079b6922 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +### [1.8.5] 2019-04-09 + + * HHVM 4.0 is no longer compatible with Composer. Please use PHP instead going forward. + * Added forward compatibility with upcoming 2.0 changes + * Fixed support for PHP 7.3-style heredoc/nowdoc syntax changes in autoload generation + * Fixed require command usage when combined with --ignore-platform-reqs + * Fixed and cleaned up various Windows junctions handling issues + ### [1.8.4] 2019-02-11 * Fixed long standing solver bug leading to odd solving issues in edge cases, see #7946 @@ -737,6 +745,7 @@ * Initial release +[1.8.5]: https://github.com/composer/composer/compare/1.8.4...1.8.5 [1.8.4]: https://github.com/composer/composer/compare/1.8.3...1.8.4 [1.8.3]: https://github.com/composer/composer/compare/1.8.2...1.8.3 [1.8.2]: https://github.com/composer/composer/compare/1.8.1...1.8.2 diff --git a/composer.lock b/composer.lock index 44b30fa22..cad214081 100644 --- a/composer.lock +++ b/composer.lock @@ -126,24 +126,23 @@ }, { "name": "composer/spdx-licenses", - "version": "1.5.0", + "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2" + "reference": "a1aa51cf3ab838b83b0867b14e56fc20fbd55b3d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/7a9556b22bd9d4df7cad89876b00af58ef20d3a2", - "reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/a1aa51cf3ab838b83b0867b14e56fc20fbd55b3d", + "reference": "a1aa51cf3ab838b83b0867b14e56fc20fbd55b3d", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0" + "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5", - "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 7" }, "type": "library", "extra": { @@ -183,7 +182,7 @@ "spdx", "validator" ], - "time": "2018-11-01T09:45:54+00:00" + "time": "2019-03-26T10:23:26+00:00" }, { "name": "composer/xdebug-handler", diff --git a/src/Composer/Autoload/ClassMapGenerator.php b/src/Composer/Autoload/ClassMapGenerator.php index 5d937433b..1ecf96bfe 100644 --- a/src/Composer/Autoload/ClassMapGenerator.php +++ b/src/Composer/Autoload/ClassMapGenerator.php @@ -162,7 +162,7 @@ class ClassMapGenerator } // strip heredocs/nowdocs - $contents = preg_replace('{<<<\s*(\'?)(\w+)\\1(?:\r\n|\n|\r)(?:.*?)(?:\r\n|\n|\r)\\2(?=\r\n|\n|\r|;)}s', 'null', $contents); + $contents = preg_replace('{<<<[ \t]*([\'"]?)(\w+)\\1(?:\r\n|\n|\r)(?:.*?)(?:\r\n|\n|\r)(?:\s*)\\2(?=\s+|[;,.)])}s', 'null', $contents); // strip strings $contents = preg_replace('{"[^"\\\\]*+(\\\\.[^"\\\\]*+)*+"|\'[^\'\\\\]*+(\\\\.[^\'\\\\]*+)*+\'}s', 'null', $contents); // strip leading non-php code if needed diff --git a/src/Composer/Command/RequireCommand.php b/src/Composer/Command/RequireCommand.php index 4cad91023..508514eb4 100644 --- a/src/Composer/Command/RequireCommand.php +++ b/src/Composer/Command/RequireCommand.php @@ -25,6 +25,7 @@ use Composer\Plugin\CommandEvent; use Composer\Plugin\PluginEvents; use Composer\Repository\CompositeRepository; use Composer\Repository\PlatformRepository; +use Composer\IO\IOInterface; /** * @author Jérémy Romey @@ -160,16 +161,27 @@ EOT if ($input->getOption('no-update')) { return 0; } - $updateDevMode = !$input->getOption('update-no-dev'); - $optimize = $input->getOption('optimize-autoloader') || $composer->getConfig()->get('optimize-autoloader'); - $authoritative = $input->getOption('classmap-authoritative') || $composer->getConfig()->get('classmap-authoritative'); - $apcu = $input->getOption('apcu-autoloader') || $composer->getConfig()->get('apcu-autoloader'); + try { + return $this->doUpdate($input, $output, $io, $requirements); + } catch (\Exception $e) { + $this->revertComposerFile(false); + throw $e; + } + } + + private function doUpdate(InputInterface $input, OutputInterface $output, IOInterface $io, array $requirements) + { // Update packages $this->resetComposer(); $composer = $this->getComposer(true, $input->getOption('no-plugins')); $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress')); + $updateDevMode = !$input->getOption('update-no-dev'); + $optimize = $input->getOption('optimize-autoloader') || $composer->getConfig()->get('optimize-autoloader'); + $authoritative = $input->getOption('classmap-authoritative') || $composer->getConfig()->get('classmap-authoritative'); + $apcu = $input->getOption('apcu-autoloader') || $composer->getConfig()->get('apcu-autoloader'); + $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'require', $input, $output); $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent); diff --git a/src/Composer/Config.php b/src/Composer/Config.php index 4d8199ccc..7abca7dfa 100644 --- a/src/Composer/Config.php +++ b/src/Composer/Config.php @@ -16,6 +16,7 @@ use Composer\Config\ConfigSourceInterface; use Composer\Downloader\TransportException; use Composer\IO\IOInterface; use Composer\Util\Platform; +use Composer\Util\ProcessExecutor; /** * @author Jordi Boggiano @@ -459,4 +460,20 @@ class Config } } } + + /** + * Used by long-running custom scripts in composer.json + * + * "scripts": { + * "watch": [ + * "Composer\\Config::disableProcessTimeout", + * "vendor/bin/long-running-script --watch" + * ] + * } + */ + public static function disableProcessTimeout() + { + // Override global timeout set earlier by environment or config + ProcessExecutor::setTimeout(0); + } } diff --git a/src/Composer/DependencyResolver/Problem.php b/src/Composer/DependencyResolver/Problem.php index 0dcc938fd..bb497b549 100644 --- a/src/Composer/DependencyResolver/Problem.php +++ b/src/Composer/DependencyResolver/Problem.php @@ -81,8 +81,11 @@ class Problem $job = $reason['job']; - if (isset($job['constraint'])) { - $packages = $this->pool->whatProvides($job['packageName'], $job['constraint']); + $packageName = $job['packageName']; + $constraint = $job['constraint']; + + if (isset($constraint)) { + $packages = $this->pool->whatProvides($packageName, $constraint); } else { $packages = array(); } @@ -90,9 +93,9 @@ class Problem if ($job && $job['cmd'] === 'install' && empty($packages)) { // handle php/hhvm - if ($job['packageName'] === 'php' || $job['packageName'] === 'php-64bit' || $job['packageName'] === 'hhvm') { + if ($packageName === 'php' || $packageName === 'php-64bit' || $packageName === 'hhvm') { $version = phpversion(); - $available = $this->pool->whatProvides($job['packageName']); + $available = $this->pool->whatProvides($packageName); if (count($available)) { $firstAvailable = reset($available); @@ -103,13 +106,13 @@ class Problem } } - $msg = "\n - This package requires ".$job['packageName'].$this->constraintToText($job['constraint']).' but '; + $msg = "\n - This package requires ".$packageName.$this->constraintToText($constraint).' but '; if (defined('HHVM_VERSION') || count($available)) { return $msg . 'your HHVM version does not satisfy that requirement.'; } - if ($job['packageName'] === 'hhvm') { + if ($packageName === 'hhvm') { return $msg . 'you are running this with PHP and not HHVM.'; } @@ -117,43 +120,43 @@ class Problem } // handle php extensions - if (0 === stripos($job['packageName'], 'ext-')) { - if (false !== strpos($job['packageName'], ' ')) { - return "\n - The requested PHP extension ".$job['packageName'].' should be required as '.str_replace(' ', '-', $job['packageName']).'.'; + if (0 === stripos($packageName, 'ext-')) { + if (false !== strpos($packageName, ' ')) { + return "\n - The requested PHP extension ".$packageName.' should be required as '.str_replace(' ', '-', $packageName).'.'; } - $ext = substr($job['packageName'], 4); + $ext = substr($packageName, 4); $error = extension_loaded($ext) ? 'has the wrong version ('.(phpversion($ext) ?: '0').') installed' : 'is missing from your system'; - return "\n - The requested PHP extension ".$job['packageName'].$this->constraintToText($job['constraint']).' '.$error.'. Install or enable PHP\'s '.$ext.' extension.'; + return "\n - The requested PHP extension ".$packageName.$this->constraintToText($constraint).' '.$error.'. Install or enable PHP\'s '.$ext.' extension.'; } // handle linked libs - if (0 === stripos($job['packageName'], 'lib-')) { - if (strtolower($job['packageName']) === 'lib-icu') { + if (0 === stripos($packageName, 'lib-')) { + if (strtolower($packageName) === 'lib-icu') { $error = extension_loaded('intl') ? 'has the wrong version installed, try upgrading the intl extension.' : 'is missing from your system, make sure the intl extension is loaded.'; - return "\n - The requested linked library ".$job['packageName'].$this->constraintToText($job['constraint']).' '.$error; + return "\n - The requested linked library ".$packageName.$this->constraintToText($constraint).' '.$error; } - return "\n - The requested linked library ".$job['packageName'].$this->constraintToText($job['constraint']).' has the wrong version installed or is missing from your system, make sure to load the extension providing it.'; + return "\n - The requested linked library ".$packageName.$this->constraintToText($constraint).' has the wrong version installed or is missing from your system, make sure to load the extension providing it.'; } - if (!preg_match('{^[A-Za-z0-9_./-]+$}', $job['packageName'])) { - $illegalChars = preg_replace('{[A-Za-z0-9_./-]+}', '', $job['packageName']); + if (!preg_match('{^[A-Za-z0-9_./-]+$}', $packageName)) { + $illegalChars = preg_replace('{[A-Za-z0-9_./-]+}', '', $packageName); - return "\n - The requested package ".$job['packageName'].' could not be found, it looks like its name is invalid, "'.$illegalChars.'" is not allowed in package names.'; + return "\n - The requested package ".$packageName.' could not be found, it looks like its name is invalid, "'.$illegalChars.'" is not allowed in package names.'; } - if ($providers = $this->pool->whatProvides($job['packageName'], $job['constraint'], true, true)) { - return "\n - The requested package ".$job['packageName'].$this->constraintToText($job['constraint']).' is satisfiable by '.$this->getPackageList($providers).' but these conflict with your requirements or minimum-stability.'; + if ($providers = $this->pool->whatProvides($packageName, $constraint, true, true)) { + return "\n - The requested package ".$packageName.$this->constraintToText($constraint).' is satisfiable by '.$this->getPackageList($providers).' but these conflict with your requirements or minimum-stability.'; } - if ($providers = $this->pool->whatProvides($job['packageName'], null, true, true)) { - return "\n - The requested package ".$job['packageName'].$this->constraintToText($job['constraint']).' exists as '.$this->getPackageList($providers).' but these are rejected by your constraint.'; + if ($providers = $this->pool->whatProvides($packageName, null, true, true)) { + return "\n - The requested package ".$packageName.$this->constraintToText($constraint).' exists as '.$this->getPackageList($providers).' but these are rejected by your constraint.'; } - return "\n - The requested package ".$job['packageName'].' could not be found in any version, there may be a typo in the package name.'; + return "\n - The requested package ".$packageName.' could not be found in any version, there may be a typo in the package name.'; } } @@ -202,27 +205,29 @@ class Problem */ protected function jobToText($job) { + $packageName = $job['packageName']; + $constraint = $job['constraint']; switch ($job['cmd']) { case 'install': - $packages = $this->pool->whatProvides($job['packageName'], $job['constraint']); + $packages = $this->pool->whatProvides($packageName, $constraint); if (!$packages) { - return 'No package found to satisfy install request for '.$job['packageName'].$this->constraintToText($job['constraint']); + return 'No package found to satisfy install request for '.$packageName.$this->constraintToText($constraint); } - return 'Installation request for '.$job['packageName'].$this->constraintToText($job['constraint']).' -> satisfiable by '.$this->getPackageList($packages).'.'; + return 'Installation request for '.$packageName.$this->constraintToText($constraint).' -> satisfiable by '.$this->getPackageList($packages).'.'; case 'update': - return 'Update request for '.$job['packageName'].$this->constraintToText($job['constraint']).'.'; + return 'Update request for '.$packageName.$this->constraintToText($constraint).'.'; case 'remove': - return 'Removal request for '.$job['packageName'].$this->constraintToText($job['constraint']).''; + return 'Removal request for '.$packageName.$this->constraintToText($constraint).''; } - if (isset($job['constraint'])) { - $packages = $this->pool->whatProvides($job['packageName'], $job['constraint']); + if (isset($constraint)) { + $packages = $this->pool->whatProvides($packageName, $constraint); } else { $packages = array(); } - return 'Job(cmd='.$job['cmd'].', target='.$job['packageName'].', packages=['.$this->getPackageList($packages).'])'; + return 'Job(cmd='.$job['cmd'].', target='.$packageName.', packages=['.$this->getPackageList($packages).'])'; } protected function getPackageList($packages) diff --git a/src/Composer/Repository/PlatformRepository.php b/src/Composer/Repository/PlatformRepository.php index 50cbb4649..3126f860a 100644 --- a/src/Composer/Repository/PlatformRepository.php +++ b/src/Composer/Repository/PlatformRepository.php @@ -166,8 +166,14 @@ class PlatformRepository extends ArrayRepository case 'imagick': $imagick = new \Imagick(); $imageMagickVersion = $imagick->getVersion(); - preg_match('/^ImageMagick ([\d.]+)-(\d+)/', $imageMagickVersion['versionString'], $matches); - $prettyVersion = "{$matches[1]}.{$matches[2]}"; + // 6.x: ImageMagick 6.2.9 08/24/06 Q16 http://www.imagemagick.org + // 7.x: ImageMagick 7.0.8-34 Q16 x86_64 2019-03-23 https://imagemagick.org + preg_match('/^ImageMagick ([\d.]+)(?:-(\d+))?/', $imageMagickVersion['versionString'], $matches); + if (isset($matches[2])) { + $prettyVersion = "{$matches[1]}.{$matches[2]}"; + } else { + $prettyVersion = $matches[1]; + } break; case 'libxml': diff --git a/tests/Composer/Test/Autoload/Fixtures/classmap/StripNoise.php b/tests/Composer/Test/Autoload/Fixtures/classmap/StripNoise.php index 4c344089b..8944360ee 100644 --- a/tests/Composer/Test/Autoload/Fixtures/classmap/StripNoise.php +++ b/tests/Composer/Test/Autoload/Fixtures/classmap/StripNoise.php @@ -7,42 +7,81 @@ namespace Foo; */ class StripNoise { - public function test() + public function test_heredoc() { - return <<'; } - public function test2() + public function test_simple_string() { - $class = 'class Fail4 {}'; + return 'class FailSimpleString {}'; } }