From dc81200e1cb0ba55f3bd000384721f2c32baa1e2 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 21 Jan 2022 17:26:36 +0100 Subject: [PATCH 01/23] Update deps --- composer.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/composer.lock b/composer.lock index f0d3b0d95b43..5cb60cb45676 100644 --- a/composer.lock +++ b/composer.lock @@ -224,16 +224,16 @@ }, { "name": "composer/semver", - "version": "3.2.6", + "version": "3.2.7", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "83e511e247de329283478496f7a1e114c9517506" + "reference": "deac27056b57e46faf136fae7b449eeaa71661ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/83e511e247de329283478496f7a1e114c9517506", - "reference": "83e511e247de329283478496f7a1e114c9517506", + "url": "https://api.github.com/repos/composer/semver/zipball/deac27056b57e46faf136fae7b449eeaa71661ee", + "reference": "deac27056b57e46faf136fae7b449eeaa71661ee", "shasum": "" }, "require": { @@ -285,7 +285,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.2.6" + "source": "https://github.com/composer/semver/tree/3.2.7" }, "funding": [ { @@ -301,7 +301,7 @@ "type": "tidelift" } ], - "time": "2021-10-25T11:34:17+00:00" + "time": "2022-01-04T09:57:54+00:00" }, { "name": "composer/spdx-licenses", @@ -385,16 +385,16 @@ }, { "name": "composer/xdebug-handler", - "version": "2.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "6555461e76962fd0379c444c46fd558a0fcfb65e" + "reference": "0c1a3925ec58a4ec98e992b9c7d171e9e184be0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6555461e76962fd0379c444c46fd558a0fcfb65e", - "reference": "6555461e76962fd0379c444c46fd558a0fcfb65e", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/0c1a3925ec58a4ec98e992b9c7d171e9e184be0a", + "reference": "0c1a3925ec58a4ec98e992b9c7d171e9e184be0a", "shasum": "" }, "require": { @@ -431,7 +431,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/2.0.3" + "source": "https://github.com/composer/xdebug-handler/tree/2.0.4" }, "funding": [ { @@ -447,7 +447,7 @@ "type": "tidelift" } ], - "time": "2021-12-08T13:07:32+00:00" + "time": "2022-01-04T17:06:45+00:00" }, { "name": "justinrainbow/json-schema", @@ -682,16 +682,16 @@ }, { "name": "seld/phar-utils", - "version": "1.1.2", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/Seldaek/phar-utils.git", - "reference": "749042a2315705d2dfbbc59234dd9ceb22bf3ff0" + "reference": "9f3452c93ff423469c0d56450431562ca423dcee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/749042a2315705d2dfbbc59234dd9ceb22bf3ff0", - "reference": "749042a2315705d2dfbbc59234dd9ceb22bf3ff0", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/9f3452c93ff423469c0d56450431562ca423dcee", + "reference": "9f3452c93ff423469c0d56450431562ca423dcee", "shasum": "" }, "require": { @@ -724,9 +724,9 @@ ], "support": { "issues": "https://github.com/Seldaek/phar-utils/issues", - "source": "https://github.com/Seldaek/phar-utils/tree/1.1.2" + "source": "https://github.com/Seldaek/phar-utils/tree/1.2.0" }, - "time": "2021-08-19T21:01:38+00:00" + "time": "2021-12-10T11:20:11+00:00" }, { "name": "symfony/console", From 32435a0a60b2d1d2106efb1afa1a241ab1c89ae3 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 21 Jan 2022 17:27:55 +0100 Subject: [PATCH 02/23] Release 2.2.5 --- src/Composer/Composer.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Composer/Composer.php b/src/Composer/Composer.php index 624e0250764e..0b39d123c020 100644 --- a/src/Composer/Composer.php +++ b/src/Composer/Composer.php @@ -52,10 +52,10 @@ class Composer * const RELEASE_DATE = '@release_date@'; * const SOURCE_VERSION = '1.8-dev+source'; */ - const VERSION = '@package_version@'; - const BRANCH_ALIAS_VERSION = '@package_branch_alias_version@'; - const RELEASE_DATE = '@release_date@'; - const SOURCE_VERSION = '2.2.999-dev+source'; + const VERSION = '2.2.5'; + const BRANCH_ALIAS_VERSION = ''; + const RELEASE_DATE = '2022-01-21 17:27:55'; + const SOURCE_VERSION = ''; /** * Version number of the internal composer-runtime-api package From e8a1e25e9dabe3c62952e7eb16b1d7b7b6514eb8 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 21 Jan 2022 17:27:55 +0100 Subject: [PATCH 03/23] Reverting release version changes --- src/Composer/Composer.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Composer/Composer.php b/src/Composer/Composer.php index 0b39d123c020..624e0250764e 100644 --- a/src/Composer/Composer.php +++ b/src/Composer/Composer.php @@ -52,10 +52,10 @@ class Composer * const RELEASE_DATE = '@release_date@'; * const SOURCE_VERSION = '1.8-dev+source'; */ - const VERSION = '2.2.5'; - const BRANCH_ALIAS_VERSION = ''; - const RELEASE_DATE = '2022-01-21 17:27:55'; - const SOURCE_VERSION = ''; + const VERSION = '@package_version@'; + const BRANCH_ALIAS_VERSION = '@package_branch_alias_version@'; + const RELEASE_DATE = '@release_date@'; + const SOURCE_VERSION = '2.2.999-dev+source'; /** * Version number of the internal composer-runtime-api package From 4ce11ab4ab00777c744fd928cd8123f21fcd0074 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Wed, 2 Feb 2022 15:01:55 +0100 Subject: [PATCH 04/23] Support escaping on newer symfony/console versions, fixes #10499 --- .../Test/Installer/SuggestedPackagesReporterTest.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/Composer/Test/Installer/SuggestedPackagesReporterTest.php b/tests/Composer/Test/Installer/SuggestedPackagesReporterTest.php index c6f5b8721357..dd5929d93aaa 100644 --- a/tests/Composer/Test/Installer/SuggestedPackagesReporterTest.php +++ b/tests/Composer/Test/Installer/SuggestedPackagesReporterTest.php @@ -12,7 +12,9 @@ namespace Composer\Test\Installer; +use Composer\InstalledVersions; use Composer\Installer\SuggestedPackagesReporter; +use Composer\Semver\VersionParser; use Composer\Test\TestCase; /** @@ -186,9 +188,12 @@ public function testOutputIgnoresFormatting() ->method('write') ->with(' - target1: [1;37;42m Like us on Facebook [0m'); + $expectedWrite = InstalledVersions::satisfies(new VersionParser(), 'symfony/console', '^4.4.37 || ~5.3.14 || ^5.4.3 || ^6.0.3') + ? ' - target2: \\Like us on Facebook\\' + : ' - target2: \\Like us on Facebook\\'; $this->io->expects($this->at(2)) ->method('write') - ->with(' - target2: \\Like us on Facebook\\'); + ->with($expectedWrite); $this->suggestedPackagesReporter->output(SuggestedPackagesReporter::MODE_BY_PACKAGE); } From 7591ef0084b5e1349824ceb9f2fd3955fee8155d Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Wed, 2 Feb 2022 16:08:36 +0100 Subject: [PATCH 05/23] Attempt fixing usage of InstalledVersions in tests --- tests/Composer/Test/InstalledVersionsTest.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/Composer/Test/InstalledVersionsTest.php b/tests/Composer/Test/InstalledVersionsTest.php index d66005b54c1d..4c27b2e0fbae 100644 --- a/tests/Composer/Test/InstalledVersionsTest.php +++ b/tests/Composer/Test/InstalledVersionsTest.php @@ -17,6 +17,8 @@ class InstalledVersionsTest extends TestCase { + private static $previousRegisteredLoaders; + /** * @var string */ @@ -28,12 +30,16 @@ public static function setUpBeforeClass() // class loaders are registered $prop = new \ReflectionProperty('Composer\Autoload\ClassLoader', 'registeredLoaders'); $prop->setAccessible(true); + self::$previousRegisteredLoaders = $prop->getValue(); $prop->setValue(array()); } public static function tearDownAfterClass() { - self::setUpBeforeClass(); + $prop = new \ReflectionProperty('Composer\Autoload\ClassLoader', 'registeredLoaders'); + $prop->setAccessible(true); + $prop->setValue(self::$previousRegisteredLoaders); + InstalledVersions::reload(null); // @phpstan-ignore-line } public function setUp() From 45bbe43aac609e2b19633e1d838e5aa54567746b Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Wed, 2 Feb 2022 16:59:58 +0100 Subject: [PATCH 06/23] Fix case where symlink:true still can downgrade to a copy on windows, refs #10482 --- src/Composer/Downloader/PathDownloader.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Composer/Downloader/PathDownloader.php b/src/Composer/Downloader/PathDownloader.php index 9f8c62da6585..97de3a6e005c 100644 --- a/src/Composer/Downloader/PathDownloader.php +++ b/src/Composer/Downloader/PathDownloader.php @@ -272,6 +272,9 @@ private function computeAllowedStrategies(array $transportOptions) // Check we can use junctions safely if we are on Windows if (Platform::isWindows() && self::STRATEGY_SYMLINK === $currentStrategy && !$this->safeJunctions()) { + if (!in_array(self::STRATEGY_MIRROR, $allowedStrategies)) { + throw new \RuntimeException('You are on an old Windows / old PHP combo which does not allow Composer to use junctions/symlinks and this path repository has symlink:true in its options so copying is not allowed'); + } $currentStrategy = self::STRATEGY_MIRROR; $allowedStrategies = array(self::STRATEGY_MIRROR); } From 2da8d886cc5e583e3fdf3dbde36057c8a0a4ccf9 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Wed, 2 Feb 2022 17:24:50 +0100 Subject: [PATCH 07/23] Make code a bit more robust --- src/Composer/Repository/PathRepository.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Composer/Repository/PathRepository.php b/src/Composer/Repository/PathRepository.php index 3cb879c5c52c..d2a81cee7727 100644 --- a/src/Composer/Repository/PathRepository.php +++ b/src/Composer/Repository/PathRepository.php @@ -173,8 +173,9 @@ protected function initialize() 'url' => $url, 'reference' => sha1($json . serialize($this->options)), ); - $package['transport-options'] = $this->options; - unset($package['transport-options']['versions']); + + // copy symlink/relative options to transport options + $package['transport-options'] = array_intersect_key($this->options, array('symlink' => true, 'relative' => true)); // use the version provided as option if available if (isset($package['name'], $this->options['versions'][$package['name']])) { From db8ea452959a7d7fc1dbdf810756aae517474919 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Wed, 2 Feb 2022 17:48:45 +0100 Subject: [PATCH 08/23] Fix enum parsing when the syntax is "enum foo:string {}" without space between name and type, fixes #10498 --- src/Composer/Autoload/ClassMapGenerator.php | 11 +++++++++-- .../Test/Autoload/Fixtures/php8.1/enum_backed.php | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Composer/Autoload/ClassMapGenerator.php b/src/Composer/Autoload/ClassMapGenerator.php index 3ac0967725be..cc25985960f7 100644 --- a/src/Composer/Autoload/ClassMapGenerator.php +++ b/src/Composer/Autoload/ClassMapGenerator.php @@ -272,11 +272,18 @@ private static function findClasses($path) // This is an XHP class, https://github.com/facebook/xhp $name = 'xhp'.substr(str_replace(array('-', ':'), array('_', '__'), $name), 1); } elseif ($matches['type'][$i] === 'enum') { - // In Hack, something like: + // something like: // enum Foo: int { HERP = '123'; } // The regex above captures the colon, which isn't part of // the class name. - $name = rtrim($name, ':'); + // or: + // enum Foo:int { HERP = '123'; } + // The regex above captures the colon and type, which isn't part of + // the class name. + $colonPos = strrpos($name, ':'); + if (false !== $colonPos) { + $name = substr($name, 0, $colonPos); + } } $classes[] = ltrim($namespace . $name, '\\'); } diff --git a/tests/Composer/Test/Autoload/Fixtures/php8.1/enum_backed.php b/tests/Composer/Test/Autoload/Fixtures/php8.1/enum_backed.php index d8963e056ed9..bab09e31bb64 100644 --- a/tests/Composer/Test/Autoload/Fixtures/php8.1/enum_backed.php +++ b/tests/Composer/Test/Autoload/Fixtures/php8.1/enum_backed.php @@ -1,6 +1,6 @@ Date: Wed, 2 Feb 2022 21:35:37 +0100 Subject: [PATCH 09/23] update composer/pcre to 1.0.1 (#10496) --- composer.lock | 14 +++++++------- src/Composer/Autoload/PhpFileCleaner.php | 6 +++--- .../IgnoreListPlatformRequirementFilter.php | 4 ++-- .../Package/Archiver/BaseExcludeFilter.php | 8 ++++---- src/Composer/Package/BasePackage.php | 8 ++++---- src/Composer/Plugin/PluginManager.php | 6 +++--- .../Question/StrictConfirmationQuestion.php | 8 ++++---- src/Composer/Repository/ComposerRepository.php | 2 +- src/Composer/Repository/FilterRepository.php | 6 +++++- tests/Composer/Test/Package/BasePackageTest.php | 2 +- 10 files changed, 34 insertions(+), 30 deletions(-) diff --git a/composer.lock b/composer.lock index 5cb60cb45676..a0be49180e47 100644 --- a/composer.lock +++ b/composer.lock @@ -153,23 +153,23 @@ }, { "name": "composer/pcre", - "version": "1.0.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "3d322d715c43a1ac36c7fe215fa59336265500f2" + "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/3d322d715c43a1ac36c7fe215fa59336265500f2", - "reference": "3d322d715c43a1ac36c7fe215fa59336265500f2", + "url": "https://api.github.com/repos/composer/pcre/zipball/67a32d7d6f9f560b726ab25a061b38ff3a80c560", + "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^1", + "phpstan/phpstan": "^1.3", "phpstan/phpstan-strict-rules": "^1.1", "symfony/phpunit-bridge": "^4.2 || ^5" }, @@ -204,7 +204,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/1.0.0" + "source": "https://github.com/composer/pcre/tree/1.0.1" }, "funding": [ { @@ -220,7 +220,7 @@ "type": "tidelift" } ], - "time": "2021-12-06T15:17:27+00:00" + "time": "2022-01-21T20:24:37+00:00" }, { "name": "composer/semver", diff --git a/src/Composer/Autoload/PhpFileCleaner.php b/src/Composer/Autoload/PhpFileCleaner.php index 190d518a68d1..7941f463c260 100644 --- a/src/Composer/Autoload/PhpFileCleaner.php +++ b/src/Composer/Autoload/PhpFileCleaner.php @@ -20,10 +20,10 @@ */ class PhpFileCleaner { - /** @var array */ + /** @var array */ private static $typeConfig; - /** @var string */ + /** @var non-empty-string */ private static $restPattern; /** @@ -266,7 +266,7 @@ private function peek($char) } /** - * @param string $regex + * @param non-empty-string $regex * @param ?array $match * @return bool */ diff --git a/src/Composer/Filter/PlatformRequirementFilter/IgnoreListPlatformRequirementFilter.php b/src/Composer/Filter/PlatformRequirementFilter/IgnoreListPlatformRequirementFilter.php index 4e3ac7f58033..d6d95a287803 100644 --- a/src/Composer/Filter/PlatformRequirementFilter/IgnoreListPlatformRequirementFilter.php +++ b/src/Composer/Filter/PlatformRequirementFilter/IgnoreListPlatformRequirementFilter.php @@ -15,12 +15,12 @@ final class IgnoreListPlatformRequirementFilter implements PlatformRequirementFilterInterface { /** - * @var string + * @var non-empty-string */ private $ignoreRegex; /** - * @var string + * @var non-empty-string */ private $ignoreUpperBoundRegex; diff --git a/src/Composer/Package/Archiver/BaseExcludeFilter.php b/src/Composer/Package/Archiver/BaseExcludeFilter.php index 74efd68f1469..9a9c3b8c2c64 100644 --- a/src/Composer/Package/Archiver/BaseExcludeFilter.php +++ b/src/Composer/Package/Archiver/BaseExcludeFilter.php @@ -26,7 +26,7 @@ abstract class BaseExcludeFilter protected $sourcePath; /** - * @var array array of [$pattern, $negate, $stripLeadingSlash] arrays + * @var array array of [$pattern, $negate, $stripLeadingSlash] arrays */ protected $excludePatterns; @@ -78,7 +78,7 @@ public function filter($relativePath, $exclude) * @param string[] $lines A set of lines to be parsed * @param callable $lineParser The parser to be used on each line * - * @return array Exclude patterns to be used in filter() + * @return array Exclude patterns to be used in filter() */ protected function parseLines(array $lines, $lineParser) { @@ -106,7 +106,7 @@ function ($pattern) { * * @param string[] $rules A list of exclude rules in gitignore syntax * - * @return array Exclude patterns + * @return array Exclude patterns */ protected function generatePatterns($rules) { @@ -123,7 +123,7 @@ protected function generatePatterns($rules) * * @param string $rule An exclude rule in gitignore syntax * - * @return array{0: string, 1: bool, 2: bool} An exclude pattern + * @return array{0: non-empty-string, 1: bool, 2: bool} An exclude pattern */ protected function generatePattern($rule) { diff --git a/src/Composer/Package/BasePackage.php b/src/Composer/Package/BasePackage.php index 2a7a913a620e..a3ec9c570f6b 100644 --- a/src/Composer/Package/BasePackage.php +++ b/src/Composer/Package/BasePackage.php @@ -254,8 +254,8 @@ public function __clone() * Build a regexp from a package name, expanding * globs as required * * @param string $allowPattern - * @param string $wrap Wrap the cleaned string by the given string - * @return string + * @param non-empty-string $wrap Wrap the cleaned string by the given string + * @return non-empty-string */ public static function packageNameToRegexp($allowPattern, $wrap = '{^%s$}i') { @@ -268,8 +268,8 @@ public static function packageNameToRegexp($allowPattern, $wrap = '{^%s$}i') * Build a regexp from package names, expanding * globs as required * * @param string[] $packageNames - * @param string $wrap - * @return string + * @param non-empty-string $wrap + * @return non-empty-string */ public static function packageNamesToRegexp(array $packageNames, $wrap = '{^(?:%s)$}iD') { diff --git a/src/Composer/Plugin/PluginManager.php b/src/Composer/Plugin/PluginManager.php index 0f0257752739..c6073561bfae 100644 --- a/src/Composer/Plugin/PluginManager.php +++ b/src/Composer/Plugin/PluginManager.php @@ -55,12 +55,12 @@ class PluginManager protected $registeredPlugins = array(); /** - * @var array|null + * @var array|null */ private $allowPluginRules; /** - * @var array|null + * @var array|null */ private $allowGlobalPluginRules; @@ -643,7 +643,7 @@ public function getPluginCapabilities($capabilityClassName, array $ctorArgs = ar /** * @param array|bool|null $allowPluginsConfig - * @return array|null + * @return array|null */ private function parseAllowedPlugins($allowPluginsConfig) { diff --git a/src/Composer/Question/StrictConfirmationQuestion.php b/src/Composer/Question/StrictConfirmationQuestion.php index fdd7fcf03825..301bb91b02cc 100644 --- a/src/Composer/Question/StrictConfirmationQuestion.php +++ b/src/Composer/Question/StrictConfirmationQuestion.php @@ -25,9 +25,9 @@ */ class StrictConfirmationQuestion extends Question { - /** @var string */ + /** @var non-empty-string */ private $trueAnswerRegex; - /** @var string */ + /** @var non-empty-string */ private $falseAnswerRegex; /** @@ -35,8 +35,8 @@ class StrictConfirmationQuestion extends Question * * @param string $question The question to ask to the user * @param bool $default The default answer to return, true or false - * @param string $trueAnswerRegex A regex to match the "yes" answer - * @param string $falseAnswerRegex A regex to match the "no" answer + * @param non-empty-string $trueAnswerRegex A regex to match the "yes" answer + * @param non-empty-string $falseAnswerRegex A regex to match the "no" answer */ public function __construct($question, $default = true, $trueAnswerRegex = '/^y(?:es)?$/i', $falseAnswerRegex = '/^no?$/i') { diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index cbe7cb3f97e0..7d0bcab801b3 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -80,7 +80,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito protected $hasAvailablePackageList = false; /** @var ?array */ protected $availablePackages = null; - /** @var ?array */ + /** @var ?array */ protected $availablePackagePatterns = null; /** @var ?string */ protected $lazyProvidersUrl = null; diff --git a/src/Composer/Repository/FilterRepository.php b/src/Composer/Repository/FilterRepository.php index 0ee1ae53d5bc..03fce779f395 100644 --- a/src/Composer/Repository/FilterRepository.php +++ b/src/Composer/Repository/FilterRepository.php @@ -25,7 +25,7 @@ class FilterRepository implements RepositoryInterface { /** @var ?string */ private $only = null; - /** @var ?string */ + /** @var ?non-empty-string */ private $exclude = null; /** @var bool */ private $canonical = true; @@ -206,6 +206,10 @@ private function isAllowed($name) return Preg::isMatch($this->only, $name); } + if ($this->exclude === null) { + return true; + } + return !Preg::isMatch($this->exclude, $name); } } diff --git a/tests/Composer/Test/Package/BasePackageTest.php b/tests/Composer/Test/Package/BasePackageTest.php index 7ecaa5de6b42..f95034d2b606 100644 --- a/tests/Composer/Test/Package/BasePackageTest.php +++ b/tests/Composer/Test/Package/BasePackageTest.php @@ -95,7 +95,7 @@ public function provideFormattedVersions() /** * @param string[] $packageNames - * @param string $wrap + * @param non-empty-string $wrap * @param string $expectedRegexp * * @dataProvider dataPackageNamesToRegexp From 62d5f4f295794e856b69be4e94b3b2edb34e4177 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Wed, 2 Feb 2022 22:18:00 +0100 Subject: [PATCH 10/23] Fix phpstan errors --- phpstan/baseline.neon | 39 ++++++------------- src/Composer/Downloader/PathDownloader.php | 4 +- tests/Composer/Test/InstalledVersionsTest.php | 2 + 3 files changed, 16 insertions(+), 29 deletions(-) diff --git a/phpstan/baseline.neon b/phpstan/baseline.neon index 5c33d1b388e3..3d77449f0b85 100644 --- a/phpstan/baseline.neon +++ b/phpstan/baseline.neon @@ -2740,11 +2740,6 @@ parameters: count: 1 path: ../src/Composer/DependencyResolver/GenericRule.php - - - message: "#^Cannot access offset 0 on array\\{int, Composer\\\\DependencyResolver\\\\Rule\\}\\|false\\.$#" - count: 1 - path: ../src/Composer/DependencyResolver/LockTransaction.php - - message: "#^Only booleans are allowed in &&, DateTime\\|null given on the left side\\.$#" count: 1 @@ -3050,16 +3045,6 @@ parameters: count: 1 path: ../src/Composer/DependencyResolver/RuleWatchGraph.php - - - message: "#^Cannot access offset 0 on array\\{int, Composer\\\\DependencyResolver\\\\Rule\\}\\|false\\.$#" - count: 1 - path: ../src/Composer/DependencyResolver/Solver.php - - - - message: "#^Cannot access offset 1 on array\\{int, Composer\\\\DependencyResolver\\\\Rule\\}\\|false\\.$#" - count: 1 - path: ../src/Composer/DependencyResolver/Solver.php - - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" count: 2 @@ -3526,7 +3511,17 @@ parameters: path: ../src/Composer/Downloader/HgDownloader.php - - message: "#^Call to function in_array\\(\\) requires parameter \\#3 to be set\\.$#" + message: "#^Call to function in_array\\(\\) with arguments 20, array\\{0\\: 10\\|20, 1\\?\\: 20\\} and true will always evaluate to true\\.$#" + count: 1 + path: ../src/Composer/Downloader/PathDownloader.php + + - + message: "#^Call to function in_array\\(\\) with arguments 20, non\\-empty\\-array\\ and true will always evaluate to true\\.$#" + count: 1 + path: ../src/Composer/Downloader/PathDownloader.php + + - + message: "#^Else branch is unreachable because previous condition is always true\\.$#" count: 1 path: ../src/Composer/Downloader/PathDownloader.php @@ -5540,11 +5535,6 @@ parameters: count: 1 path: ../src/Composer/Repository/FilterRepository.php - - - message: "#^Parameter \\#1 \\$pattern of static method Composer\\\\Pcre\\\\Preg\\:\\:isMatch\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: ../src/Composer/Repository/FilterRepository.php - - message: "#^Call to function in_array\\(\\) requires parameter \\#3 to be set\\.$#" count: 7 @@ -5580,11 +5570,6 @@ parameters: count: 2 path: ../src/Composer/Repository/PathRepository.php - - - message: "#^Offset 'versions' does not exist on array\\{symlink\\?\\: bool, relative\\?\\: bool, versions\\?\\: array\\\\}\\.$#" - count: 1 - path: ../src/Composer/Repository/PathRepository.php - - message: "#^Only booleans are allowed in &&, string\\|false given on the right side\\.$#" count: 1 @@ -6997,7 +6982,7 @@ parameters: - message: "#^Offset 'options' does not exist on array\\{url\\: string, options\\?\\: array, copyTo\\?\\: string\\|null\\}\\.$#" - count: 5 + count: 3 path: ../src/Composer/Util/HttpDownloader.php - diff --git a/src/Composer/Downloader/PathDownloader.php b/src/Composer/Downloader/PathDownloader.php index 97de3a6e005c..5482bf43d01d 100644 --- a/src/Composer/Downloader/PathDownloader.php +++ b/src/Composer/Downloader/PathDownloader.php @@ -126,7 +126,7 @@ public function install(PackageInterface $package, $path, $output = true) } } } catch (IOException $e) { - if (in_array(self::STRATEGY_MIRROR, $allowedStrategies)) { + if (in_array(self::STRATEGY_MIRROR, $allowedStrategies, true)) { if ($output) { $this->io->writeError(''); $this->io->writeError(' Symlink failed, fallback to use mirroring!'); @@ -272,7 +272,7 @@ private function computeAllowedStrategies(array $transportOptions) // Check we can use junctions safely if we are on Windows if (Platform::isWindows() && self::STRATEGY_SYMLINK === $currentStrategy && !$this->safeJunctions()) { - if (!in_array(self::STRATEGY_MIRROR, $allowedStrategies)) { + if (!in_array(self::STRATEGY_MIRROR, $allowedStrategies, true)) { throw new \RuntimeException('You are on an old Windows / old PHP combo which does not allow Composer to use junctions/symlinks and this path repository has symlink:true in its options so copying is not allowed'); } $currentStrategy = self::STRATEGY_MIRROR; diff --git a/tests/Composer/Test/InstalledVersionsTest.php b/tests/Composer/Test/InstalledVersionsTest.php index 4c27b2e0fbae..a2c4b17d7cbd 100644 --- a/tests/Composer/Test/InstalledVersionsTest.php +++ b/tests/Composer/Test/InstalledVersionsTest.php @@ -12,11 +12,13 @@ namespace Composer\Test; +use Composer\Autoload\ClassLoader; use Composer\InstalledVersions; use Composer\Semver\VersionParser; class InstalledVersionsTest extends TestCase { + /** @var array */ private static $previousRegisteredLoaders; /** From 7c2954d349163ae1234ccd174295988710183372 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 4 Feb 2022 09:23:00 +0100 Subject: [PATCH 11/23] Minor BC Break! Rename COMPOSER_BIN_DIR available inside binaries to COMPOSER_RUNTIME_BIN_DIR (#10512) This was available to non-PHP binaries as env var since Composer 2.2.2, and the rename is needed to fix a regression due to a name clash. Fixes #10504 --- src/Composer/Installer/BinaryInstaller.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Composer/Installer/BinaryInstaller.php b/src/Composer/Installer/BinaryInstaller.php index 7d5db0d2bcb7..417e9be2b17f 100644 --- a/src/Composer/Installer/BinaryInstaller.php +++ b/src/Composer/Installer/BinaryInstaller.php @@ -235,14 +235,14 @@ protected function generateWindowsProxyCode($bin, $link) return "@ECHO OFF\r\n". "setlocal DISABLEDELAYEDEXPANSION\r\n". "SET BIN_TARGET=%~dp0/".trim(ProcessExecutor::escape(basename($link, '.bat')), '"\'')."\r\n". - "SET COMPOSER_BIN_DIR=%~dp0\r\n". + "SET COMPOSER_RUNTIME_BIN_DIR=%~dp0\r\n". "{$caller} \"%BIN_TARGET%\" %*\r\n"; } return "@ECHO OFF\r\n". "setlocal DISABLEDELAYEDEXPANSION\r\n". "SET BIN_TARGET=%~dp0/".trim(ProcessExecutor::escape($binPath), '"\'')."\r\n". - "SET COMPOSER_BIN_DIR=%~dp0\r\n". + "SET COMPOSER_RUNTIME_BIN_DIR=%~dp0\r\n". "{$caller} \"%BIN_TARGET%\" %*\r\n"; } @@ -434,7 +434,7 @@ public function url_stat(\$path, \$flags) esac fi -export COMPOSER_BIN_DIR=\$(cd "\${self%[/\\\\]*}" > /dev/null; pwd) +export COMPOSER_RUNTIME_BIN_DIR=\$(cd "\${self%[/\\\\]*}" > /dev/null; pwd) # If bash is sourcing this file, we have to source the target as well bashSource="\$BASH_SOURCE" From e7c04e3e128dabf6ba9130e0381cacee8015a942 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 4 Feb 2022 10:17:49 +0100 Subject: [PATCH 12/23] Improve error reporting when a tag was recreated or a commit is missing, fixes #10484 --- src/Composer/Downloader/GitDownloader.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Composer/Downloader/GitDownloader.php b/src/Composer/Downloader/GitDownloader.php index 4575af29b528..a0e69e0b1814 100644 --- a/src/Composer/Downloader/GitDownloader.php +++ b/src/Composer/Downloader/GitDownloader.php @@ -135,7 +135,7 @@ protected function doInstall(PackageInterface $package, $path, $url) $this->setPushUrl($path, $url); } - if ($newRef = $this->updateToCommit($path, $ref, $package->getPrettyVersion(), $package->getReleaseDate())) { + if ($newRef = $this->updateToCommit($package, $path, $ref, $package->getPrettyVersion(), $package->getReleaseDate())) { if ($package->getDistReference() === $package->getSourceReference()) { $package->setDistReference($newRef); } @@ -186,7 +186,7 @@ protected function doUpdate(PackageInterface $initial, PackageInterface $target, }; $this->gitUtil->runCommand($commandCallable, $url, $path); - if ($newRef = $this->updateToCommit($path, $ref, $target->getPrettyVersion(), $target->getReleaseDate())) { + if ($newRef = $this->updateToCommit($target, $path, $ref, $target->getPrettyVersion(), $target->getReleaseDate())) { if ($target->getDistReference() === $target->getSourceReference()) { $target->setDistReference($newRef); } @@ -434,12 +434,12 @@ protected function reapplyChanges($path) * * @param string $path * @param string $reference - * @param string $branch + * @param string $prettyVersion * @param \DateTime $date * @throws \RuntimeException * @return null|string if a string is returned, it is the commit reference that was checked out if the original could not be found */ - protected function updateToCommit($path, $reference, $branch, $date) + protected function updateToCommit(PackageInterface $package, $path, $reference, $prettyVersion, $date) { $force = !empty($this->hasDiscardedChanges[$path]) || !empty($this->hasStashedChanges[$path]) ? '-f ' : ''; @@ -449,7 +449,7 @@ protected function updateToCommit($path, $reference, $branch, $date) // If the non-existent branch is actually the name of a file, the file // is checked out. $template = 'git checkout '.$force.'%s -- && git reset --hard %1$s --'; - $branch = Preg::replace('{(?:^dev-|(?:\.x)?-dev$)}i', '', $branch); + $branch = Preg::replace('{(?:^dev-|(?:\.x)?-dev$)}i', '', $prettyVersion); $branches = null; if (0 === $this->process->execute('git branch -r', $output, $path)) { @@ -489,12 +489,15 @@ protected function updateToCommit($path, $reference, $branch, $date) return null; } + $exceptionExtra = ''; + // reference was not found (prints "fatal: reference is not a tree: $ref") if (false !== strpos($this->process->getErrorOutput(), $reference)) { $this->io->writeError(' '.$reference.' is gone (history was rewritten?)'); + $exceptionExtra = "\nIt looks like the commit hash is not available in the repository, maybe ".($package->isDev() ? 'the commit was removed from the branch' : 'the tag was recreated').'? Run "composer update '.$package->getPrettyName().'" to resolve this.'; } - throw new \RuntimeException(Url::sanitize('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput())); + throw new \RuntimeException(Url::sanitize('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput() . $exceptionExtra)); } /** From 3d82719b70e214ed6205d74c0ce2a4fd4e18367b Mon Sep 17 00:00:00 2001 From: Florian Engelhardt Date: Fri, 4 Feb 2022 10:23:10 +0100 Subject: [PATCH 13/23] Fix package search not urlencoding the input (#10500) --- .../Repository/ComposerRepository.php | 2 +- .../Repository/ComposerRepositoryTest.php | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index 7d0bcab801b3..0154a49a529e 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -540,7 +540,7 @@ public function search($query, $mode = 0, $type = null) $this->loadRootServerFile(600); if ($this->searchUrl && $mode === self::SEARCH_FULLTEXT) { - $url = str_replace(array('%query%', '%type%'), array($query, $type), $this->searchUrl); + $url = str_replace(array('%query%', '%type%'), array(urlencode($query), $type), $this->searchUrl); $search = $this->httpDownloader->get($url, $this->options)->decodeJson(); diff --git a/tests/Composer/Test/Repository/ComposerRepositoryTest.php b/tests/Composer/Test/Repository/ComposerRepositoryTest.php index d2f1ca8ed313..ed5dbf93db03 100644 --- a/tests/Composer/Test/Repository/ComposerRepositoryTest.php +++ b/tests/Composer/Test/Repository/ComposerRepositoryTest.php @@ -202,6 +202,36 @@ public function testSearchWithType() ); } + public function testSearchWithSpecialChars() + { + $repoConfig = array( + 'url' => 'http://example.org', + ); + + $result = array( + 'results' => array( + array( + 'name' => 'foo', + 'description' => null, + ), + ), + ); + + $httpDownloader = new HttpDownloaderMock(array( + 'http://example.org/packages.json' => JsonFile::encode(array('search' => '/search.json?q=%query%&type=%type%')), + 'http://example.org/search.json?q=foo+bar&type=' => JsonFile::encode(array()), + )); + $eventDispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher') + ->disableOriginalConstructor() + ->getMock(); + + $repository = new ComposerRepository($repoConfig, new NullIO, FactoryMock::createConfig(), $httpDownloader, $eventDispatcher); + + $this->assertEmpty( + $repository->search('foo bar', RepositoryInterface::SEARCH_FULLTEXT) + ); + } + public function testSearchWithAbandonedPackages() { $repoConfig = array( From 39cb505d69092596ee135c61f968c3a8cfaf9961 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 4 Feb 2022 13:01:48 +0100 Subject: [PATCH 14/23] Fix phpstan warnings --- src/Composer/Downloader/GitDownloader.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Composer/Downloader/GitDownloader.php b/src/Composer/Downloader/GitDownloader.php index a0e69e0b1814..bb68f8557d83 100644 --- a/src/Composer/Downloader/GitDownloader.php +++ b/src/Composer/Downloader/GitDownloader.php @@ -135,7 +135,7 @@ protected function doInstall(PackageInterface $package, $path, $url) $this->setPushUrl($path, $url); } - if ($newRef = $this->updateToCommit($package, $path, $ref, $package->getPrettyVersion(), $package->getReleaseDate())) { + if ($newRef = $this->updateToCommit($package, $path, (string) $ref, $package->getPrettyVersion(), $package->getReleaseDate())) { if ($package->getDistReference() === $package->getSourceReference()) { $package->setDistReference($newRef); } @@ -186,7 +186,7 @@ protected function doUpdate(PackageInterface $initial, PackageInterface $target, }; $this->gitUtil->runCommand($commandCallable, $url, $path); - if ($newRef = $this->updateToCommit($target, $path, $ref, $target->getPrettyVersion(), $target->getReleaseDate())) { + if ($newRef = $this->updateToCommit($target, $path, (string) $ref, $target->getPrettyVersion(), $target->getReleaseDate())) { if ($target->getDistReference() === $target->getSourceReference()) { $target->setDistReference($newRef); } @@ -435,11 +435,10 @@ protected function reapplyChanges($path) * @param string $path * @param string $reference * @param string $prettyVersion - * @param \DateTime $date * @throws \RuntimeException * @return null|string if a string is returned, it is the commit reference that was checked out if the original could not be found */ - protected function updateToCommit(PackageInterface $package, $path, $reference, $prettyVersion, $date) + protected function updateToCommit(PackageInterface $package, $path, $reference, $prettyVersion) { $force = !empty($this->hasDiscardedChanges[$path]) || !empty($this->hasStashedChanges[$path]) ? '-f ' : ''; From 88171e409d3e515b139566b8de718ed3732e914d Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 4 Feb 2022 13:04:02 +0100 Subject: [PATCH 15/23] Remove superfluous arg --- src/Composer/Downloader/GitDownloader.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Composer/Downloader/GitDownloader.php b/src/Composer/Downloader/GitDownloader.php index bb68f8557d83..33ff7922a839 100644 --- a/src/Composer/Downloader/GitDownloader.php +++ b/src/Composer/Downloader/GitDownloader.php @@ -135,7 +135,7 @@ protected function doInstall(PackageInterface $package, $path, $url) $this->setPushUrl($path, $url); } - if ($newRef = $this->updateToCommit($package, $path, (string) $ref, $package->getPrettyVersion(), $package->getReleaseDate())) { + if ($newRef = $this->updateToCommit($package, $path, (string) $ref, $package->getPrettyVersion())) { if ($package->getDistReference() === $package->getSourceReference()) { $package->setDistReference($newRef); } @@ -186,7 +186,7 @@ protected function doUpdate(PackageInterface $initial, PackageInterface $target, }; $this->gitUtil->runCommand($commandCallable, $url, $path); - if ($newRef = $this->updateToCommit($target, $path, (string) $ref, $target->getPrettyVersion(), $target->getReleaseDate())) { + if ($newRef = $this->updateToCommit($target, $path, (string) $ref, $target->getPrettyVersion())) { if ($target->getDistReference() === $target->getSourceReference()) { $target->setDistReference($newRef); } From 8053d794a84cf93f83173b0109e2d078e59317a4 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 4 Feb 2022 14:08:07 +0100 Subject: [PATCH 16/23] Fix reinstall command not firing pre-install-cmd/post-install-cmd events, fixes #10508 (#10514) --- src/Composer/Command/ReinstallCommand.php | 16 +++++++++++++--- src/Composer/Repository/FilesystemRepository.php | 13 +++++++++++++ .../Repository/InstalledRepositoryInterface.php | 5 +++++ .../Repository/WritableArrayRepository.php | 13 +++++++++++++ 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/Composer/Command/ReinstallCommand.php b/src/Composer/Command/ReinstallCommand.php index 3143fc50c32a..7a1160743ecb 100644 --- a/src/Composer/Command/ReinstallCommand.php +++ b/src/Composer/Command/ReinstallCommand.php @@ -21,6 +21,8 @@ use Composer\Pcre\Preg; use Composer\Plugin\CommandEvent; use Composer\Plugin\PluginEvents; +use Composer\Script\ScriptEvents; +use Composer\Util\Platform; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputArgument; @@ -127,7 +129,8 @@ protected function execute(InputInterface $input, OutputInterface $output) }); $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'reinstall', $input, $output); - $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent); + $eventDispatcher = $composer->getEventDispatcher(); + $eventDispatcher->dispatch($commandEvent->getName(), $commandEvent); $config = $composer->getConfig(); list($preferSource, $preferDist) = $this->getPreferredInstallOptions($config, $input); @@ -146,8 +149,13 @@ protected function execute(InputInterface $input, OutputInterface $output) $downloadManager->setPreferSource($preferSource); $downloadManager->setPreferDist($preferDist); - $installationManager->execute($localRepo, $uninstallOperations, true); - $installationManager->execute($localRepo, $installOperations, true); + $devMode = $localRepo->getDevMode() !== null ? $localRepo->getDevMode() : true; + + Platform::putEnv('COMPOSER_DEV_MODE', $devMode ? '1' : '0'); + $eventDispatcher->dispatchScript(ScriptEvents::PRE_INSTALL_CMD, $devMode); + + $installationManager->execute($localRepo, $uninstallOperations, $devMode); + $installationManager->execute($localRepo, $installOperations, $devMode); if (!$input->getOption('no-autoloader')) { $optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader'); @@ -162,6 +170,8 @@ protected function execute(InputInterface $input, OutputInterface $output) $generator->dump($config, $localRepo, $package, $installationManager, 'composer', $optimize); } + $eventDispatcher->dispatchScript(ScriptEvents::POST_INSTALL_CMD, $devMode); + return 0; } } diff --git a/src/Composer/Repository/FilesystemRepository.php b/src/Composer/Repository/FilesystemRepository.php index 6f130ce05393..6138514fcc85 100644 --- a/src/Composer/Repository/FilesystemRepository.php +++ b/src/Composer/Repository/FilesystemRepository.php @@ -36,6 +36,8 @@ class FilesystemRepository extends WritableArrayRepository private $rootPackage; /** @var Filesystem */ private $filesystem; + /** @var bool|null */ + private $devMode = null; /** * Initializes filesystem repository. @@ -56,6 +58,14 @@ public function __construct(JsonFile $repositoryFile, $dumpVersions = false, Roo } } + /** + * @return bool|null true if dev requirements were installed, false if --no-dev was used, null if yet unknown + */ + public function getDevMode() + { + return $this->devMode; + } + /** * Initializes repository (reads file, or remote address). */ @@ -78,6 +88,9 @@ protected function initialize() if (isset($data['dev-package-names'])) { $this->setDevPackageNames($data['dev-package-names']); } + if (isset($data['dev'])) { + $this->devMode = $data['dev']; + } if (!is_array($packages)) { throw new \UnexpectedValueException('Could not parse package list from the repository'); diff --git a/src/Composer/Repository/InstalledRepositoryInterface.php b/src/Composer/Repository/InstalledRepositoryInterface.php index b5d8a264e39a..a25d7369e2e7 100644 --- a/src/Composer/Repository/InstalledRepositoryInterface.php +++ b/src/Composer/Repository/InstalledRepositoryInterface.php @@ -21,6 +21,11 @@ */ interface InstalledRepositoryInterface extends WritableRepositoryInterface { + /** + * @return bool|null true if dev requirements were installed, false if --no-dev was used, null if yet unknown + */ + public function getDevMode(); + /** * @return bool true if packages were never installed in this repository */ diff --git a/src/Composer/Repository/WritableArrayRepository.php b/src/Composer/Repository/WritableArrayRepository.php index 2cf2f576acc2..722cc68f1156 100644 --- a/src/Composer/Repository/WritableArrayRepository.php +++ b/src/Composer/Repository/WritableArrayRepository.php @@ -27,6 +27,17 @@ class WritableArrayRepository extends ArrayRepository implements WritableReposit */ protected $devPackageNames = array(); + /** @var bool|null */ + private $devMode = null; + + /** + * @return bool|null true if dev requirements were installed, false if --no-dev was used, null if yet unknown + */ + public function getDevMode() + { + return $this->devMode; + } + /** * @inheritDoc */ @@ -48,6 +59,7 @@ public function getDevPackageNames() */ public function write($devMode, InstallationManager $installationManager) { + $this->devMode = $devMode; } /** @@ -55,6 +67,7 @@ public function write($devMode, InstallationManager $installationManager) */ public function reload() { + $this->devMode = null; } /** From 6c36920453059fd01eb7770d3fc95e95078a74d1 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 4 Feb 2022 13:14:16 +0100 Subject: [PATCH 17/23] Bump semver --- composer.lock | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/composer.lock b/composer.lock index a0be49180e47..6b44b0234a57 100644 --- a/composer.lock +++ b/composer.lock @@ -224,23 +224,23 @@ }, { "name": "composer/semver", - "version": "3.2.7", + "version": "3.2.9", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "deac27056b57e46faf136fae7b449eeaa71661ee" + "reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/deac27056b57e46faf136fae7b449eeaa71661ee", - "reference": "deac27056b57e46faf136fae7b449eeaa71661ee", + "url": "https://api.github.com/repos/composer/semver/zipball/a951f614bd64dcd26137bc9b7b2637ddcfc57649", + "reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.54", + "phpstan/phpstan": "^1.4", "symfony/phpunit-bridge": "^4.2 || ^5" }, "type": "library", @@ -285,7 +285,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.2.7" + "source": "https://github.com/composer/semver/tree/3.2.9" }, "funding": [ { @@ -301,7 +301,7 @@ "type": "tidelift" } ], - "time": "2022-01-04T09:57:54+00:00" + "time": "2022-02-04T13:58:43+00:00" }, { "name": "composer/spdx-licenses", @@ -593,12 +593,12 @@ } }, "autoload": { - "psr-0": { - "React\\Promise": "src/" - }, "files": [ "src/React/Promise/functions_include.php" - ] + ], + "psr-0": { + "React\\Promise": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ From ee36c5e54a02c1cb3304c4fa3bc9edec4bd3feac Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 4 Feb 2022 15:36:53 +0100 Subject: [PATCH 18/23] Fix error reporting issues when partial updates cannot update due to a symlinked path repo package, fixes #10451 --- src/Composer/DependencyResolver/Problem.php | 14 ++++++++++++-- ...ock-but-not-in-remote-due-to-min-stability.test | 2 +- ...-package-present-in-lock-but-not-in-remote.test | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/Composer/DependencyResolver/Problem.php b/src/Composer/DependencyResolver/Problem.php index 2fe1d5ea14a3..124a544cbff8 100644 --- a/src/Composer/DependencyResolver/Problem.php +++ b/src/Composer/DependencyResolver/Problem.php @@ -554,8 +554,18 @@ private static function computeCheckForLowerPrioRepo(Pool $pool, $isVerbose, $pa if ($nextRepo instanceof LockArrayRepository) { $singular = count($higherRepoPackages) === 1; - return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', it is ', - 'found '.self::getPackageList($nextRepoPackages, $isVerbose, $pool, $constraint).' in the lock file and '.self::getPackageList($higherRepoPackages, $isVerbose, $pool, $constraint).' from '.reset($higherRepoPackages)->getRepository()->getRepoName().' but ' . ($singular ? 'it does' : 'these do') . ' not match your '.$reason.' and ' . ($singular ? 'is' : 'are') . ' therefore not installable. Make sure you either fix the '.$reason.' or avoid updating this package to keep the one from the lock file.', ); + $suggestion = 'Make sure you either fix the '.$reason.' or avoid updating this package to keep the one present in the lock file ('.self::getPackageList($nextRepoPackages, $isVerbose, $pool, $constraint).').'; + // symlinked path repos cannot be locked so do not suggest keeping it locked + if ($nextRepoPackages[0]->getDistType() === 'path') { + $transportOptions = $nextRepoPackages[0]->getTransportOptions(); + if (!isset($transportOptions['symlink']) || $transportOptions['symlink'] !== false) { + $suggestion = 'Make sure you fix the '.$reason.' as packages installed from symlinked path repos are updated even in partial updates and the one from the lock file can thus not be used.'; + } + } + + return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', + 'found ' . self::getPackageList($higherRepoPackages, $isVerbose, $pool, $constraint).' but ' . ($singular ? 'it does' : 'these do') . ' not match your '.$reason.' and ' . ($singular ? 'is' : 'are') . ' therefore not installable. '.$suggestion, + ); } return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', it is ', 'satisfiable by '.self::getPackageList($nextRepoPackages, $isVerbose, $pool, $constraint).' from '.$nextRepo->getRepoName().' but '.self::getPackageList($higherRepoPackages, $isVerbose, $pool, $constraint).' from '.reset($higherRepoPackages)->getRepository()->getRepoName().' has higher repository priority. The packages from the higher priority repository do not match your '.$reason.' and are therefore not installable. That repository is canonical so the lower priority repo\'s packages are not installable. See https://getcomposer.org/repoprio for details and assistance.'); diff --git a/tests/Composer/Test/Fixtures/installer/update-package-present-in-lock-but-not-in-remote-due-to-min-stability.test b/tests/Composer/Test/Fixtures/installer/update-package-present-in-lock-but-not-in-remote-due-to-min-stability.test index 0c66d1dc33bb..c5582a0e3a55 100644 --- a/tests/Composer/Test/Fixtures/installer/update-package-present-in-lock-but-not-in-remote-due-to-min-stability.test +++ b/tests/Composer/Test/Fixtures/installer/update-package-present-in-lock-but-not-in-remote-due-to-min-stability.test @@ -49,6 +49,6 @@ Your requirements could not be resolved to an installable set of packages. Problem 1 - Root composer.json requires main/dep * -> satisfiable by main/dep[1.0.0]. - - main/dep 1.0.0 requires locked/dep ^2.1 -> found locked/dep[2.1.0] in the lock file and locked/dep[2.x-dev] from package repo (defining 3 packages) but it does not match your minimum-stability and is therefore not installable. Make sure you either fix the minimum-stability or avoid updating this package to keep the one from the lock file. + - main/dep 1.0.0 requires locked/dep ^2.1 -> found locked/dep[2.x-dev] but it does not match your minimum-stability and is therefore not installable. Make sure you either fix the minimum-stability or avoid updating this package to keep the one present in the lock file (locked/dep[2.1.0]). --EXPECT-- diff --git a/tests/Composer/Test/Fixtures/installer/update-package-present-in-lock-but-not-in-remote.test b/tests/Composer/Test/Fixtures/installer/update-package-present-in-lock-but-not-in-remote.test index 0d1e680e7942..6ff3f6f5b7d8 100644 --- a/tests/Composer/Test/Fixtures/installer/update-package-present-in-lock-but-not-in-remote.test +++ b/tests/Composer/Test/Fixtures/installer/update-package-present-in-lock-but-not-in-remote.test @@ -48,6 +48,6 @@ Your requirements could not be resolved to an installable set of packages. Problem 1 - Root composer.json requires main/dep * -> satisfiable by main/dep[1.0.0]. - - main/dep 1.0.0 requires locked/dep ^2.1 -> found locked/dep[2.1.0] in the lock file and locked/dep[2.0.5] from package repo (defining 2 packages) but it does not match your constraint and is therefore not installable. Make sure you either fix the constraint or avoid updating this package to keep the one from the lock file. + - main/dep 1.0.0 requires locked/dep ^2.1 -> found locked/dep[2.0.5] but it does not match your constraint and is therefore not installable. Make sure you either fix the constraint or avoid updating this package to keep the one present in the lock file (locked/dep[2.1.0]). --EXPECT-- From d124c13a4246d8db7cb8513cd084ac2ad16ca1e9 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 4 Feb 2022 16:17:02 +0100 Subject: [PATCH 19/23] Add hints when the arg of show is not found, fixes #10493 --- src/Composer/Command/ShowCommand.php | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/Composer/Command/ShowCommand.php b/src/Composer/Command/ShowCommand.php index f1f52f90b7a2..6df57e08c75f 100644 --- a/src/Composer/Command/ShowCommand.php +++ b/src/Composer/Command/ShowCommand.php @@ -247,16 +247,21 @@ protected function execute(InputInterface $input, OutputInterface $output) if (empty($package)) { $options = $input->getOptions(); - if (!isset($options['working-dir']) || !file_exists('composer.json')) { - if (PlatformRepository::isPlatformPackage($input->getArgument('package')) && !$input->getOption('platform')) { - throw new \InvalidArgumentException('Package ' . $packageFilter . ' not found, try using --platform (-p) to show platform packages.'); - } - throw new \InvalidArgumentException('Package ' . $packageFilter . ' not found'); + $hint = ''; + if ($input->getOption('locked')) { + $hint .= ' in lock file'; + } + if (isset($options['working-dir'])) { + $hint .= ' in ' . $options['working-dir'] . '/composer.json'; + } + if (PlatformRepository::isPlatformPackage($input->getArgument('package')) && !$input->getOption('platform')) { + $hint .= ', try using --platform (-p) to show platform packages'; + } + if (!$input->getOption('all')) { + $hint .= ', try using --all (-a) to show all available packages'; } - $io->writeError('Package ' . $packageFilter . ' not found in ' . $options['working-dir'] . '/composer.json'); - - return 1; + throw new \InvalidArgumentException('Package "' . $packageFilter . '" not found'.$hint.'.'); } } else { $versions = array($package->getPrettyVersion() => $package->getVersion()); From 335c3c9450ceaa944f25d514fc7e074867276888 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 4 Feb 2022 16:25:16 +0100 Subject: [PATCH 20/23] Update baseline --- phpstan/baseline.neon | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/phpstan/baseline.neon b/phpstan/baseline.neon index 3d77449f0b85..e8bb60c5cb57 100644 --- a/phpstan/baseline.neon +++ b/phpstan/baseline.neon @@ -1766,17 +1766,17 @@ parameters: path: ../src/Composer/Command/ShowCommand.php - - message: "#^Binary operation \"\\.\" between '\\latest\\…' and array\\\\|string results in an error\\.$#" + message: "#^Binary operation \"\\.\" between ' in ' and array\\|bool\\|float\\|int\\|string results in an error\\.$#" count: 1 path: ../src/Composer/Command/ShowCommand.php - - message: "#^Binary operation \"\\.\" between non\\-empty\\-string and array\\\\|string results in an error\\.$#" + message: "#^Binary operation \"\\.\" between '\\latest\\…' and array\\\\|string results in an error\\.$#" count: 1 path: ../src/Composer/Command/ShowCommand.php - - message: "#^Binary operation \"\\.\" between non\\-empty\\-string and array\\|bool\\|float\\|int\\|string results in an error\\.$#" + message: "#^Binary operation \"\\.\" between non\\-empty\\-string and array\\\\|string results in an error\\.$#" count: 1 path: ../src/Composer/Command/ShowCommand.php @@ -1952,7 +1952,7 @@ parameters: - message: "#^Only booleans are allowed in a negated boolean, mixed given\\.$#" - count: 9 + count: 10 path: ../src/Composer/Command/ShowCommand.php - @@ -2012,7 +2012,7 @@ parameters: - message: "#^Only booleans are allowed in an if condition, mixed given\\.$#" - count: 13 + count: 14 path: ../src/Composer/Command/ShowCommand.php - @@ -2812,12 +2812,12 @@ parameters: - message: "#^Cannot call method getRepoName\\(\\) on Composer\\\\Repository\\\\RepositoryInterface\\|null\\.$#" - count: 4 + count: 3 path: ../src/Composer/DependencyResolver/Problem.php - message: "#^Cannot call method getRepository\\(\\) on Composer\\\\Package\\\\PackageInterface\\|false\\.$#" - count: 2 + count: 1 path: ../src/Composer/DependencyResolver/Problem.php - @@ -3445,21 +3445,11 @@ parameters: count: 4 path: ../src/Composer/Downloader/GitDownloader.php - - - message: "#^Parameter \\#2 \\$reference of method Composer\\\\Downloader\\\\GitDownloader\\:\\:updateToCommit\\(\\) expects string, string\\|null given\\.$#" - count: 2 - path: ../src/Composer/Downloader/GitDownloader.php - - message: "#^Parameter \\#3 \\$ref of method Composer\\\\Util\\\\Git\\:\\:fetchRefOrSyncMirror\\(\\) expects string, string\\|null given\\.$#" count: 1 path: ../src/Composer/Downloader/GitDownloader.php - - - message: "#^Parameter \\#4 \\$date of method Composer\\\\Downloader\\\\GitDownloader\\:\\:updateToCommit\\(\\) expects DateTime, DateTime\\|null given\\.$#" - count: 2 - path: ../src/Composer/Downloader/GitDownloader.php - - message: "#^Short ternary operator is not allowed\\. Use null coalesce operator if applicable or consider using long ternary\\.$#" count: 1 From 4f2e2ec4fc9e703278a5355226ee1c7c67972c49 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 4 Feb 2022 16:59:57 +0100 Subject: [PATCH 21/23] Update docs for renamed COMPOSER_RUNTIME_BIN_DIR --- doc/articles/vendor-binaries.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/articles/vendor-binaries.md b/doc/articles/vendor-binaries.md index f55c92692a30..6ce952a4ea43 100644 --- a/doc/articles/vendor-binaries.md +++ b/doc/articles/vendor-binaries.md @@ -99,8 +99,8 @@ As of Composer 2.2.2, a new `$_composer_bin_dir` global variable is defined by the bin proxy file, so that when your binary gets executed it can use it to easily locate the project's autoloader. -For non-PHP binaries, the bin proxy sets a `COMPOSER_BIN_DIR` environment -variable. +For non-PHP binaries, as of Composer 2.2.6, the bin proxy sets a +`COMPOSER_RUNTIME_BIN_DIR` environment variable. This global variable will not be available however when running binaries defined by the root package itself, so you need to have a fallback in place. @@ -116,10 +116,10 @@ $binDir = $_composer_bin_dir ?? __DIR__ . '/../vendor/bin'; ```php #!/bin/bash -if [[ -z "$COMPOSER_BIN_DIR" ]]; then +if [[ -z "$COMPOSER_RUNTIME_BIN_DIR" ]]; then BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" else - BIN_DIR="$COMPOSER_BIN_DIR" + BIN_DIR="$COMPOSER_RUNTIME_BIN_DIR" fi ``` From 809b372997fb4b1f6673fd1d15a1e39fdb0e8cb2 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 4 Feb 2022 17:00:30 +0100 Subject: [PATCH 22/23] Update changelog for 2.2.6 --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94efa9e93558..ff1ac0e34f29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +### [2.2.6] 2022-02-04 + + * BC Break: due to an oversight, the `COMPOSER_BIN_DIR` env var for binaries added in Composer 2.2.2 had to be renamed to `COMPOSER_RUNTIME_BIN_DIR` (#10512) + * Fixed enum parsing in classmap generation with syntax like `enum foo:string` without space after `:` (#10498) + * Fixed package search not urlencoding the input (#10500) + * Fixed `reinstall` command not firing `pre-install-cmd`/`post-install-cmd` events (#10514) + * Fixed edge case in path repositories where a symlink: true option would be ignored on old Windows and old PHP combos (#10482) + * Fixed test suite compatibility with latest symfony/console releases (#10499) + * Fixed some error reporting edge cases (#10484, #10451, #10493) + ### [2.2.5] 2022-01-21 * Disabled `composer/package-versions-deprecated` by default as it can function using `Composer\InstalledVersions` at runtime (#10458) @@ -1374,6 +1384,7 @@ * Initial release +[2.2.6]: https://github.com/composer/composer/compare/2.2.5...2.2.6 [2.2.5]: https://github.com/composer/composer/compare/2.2.4...2.2.5 [2.2.4]: https://github.com/composer/composer/compare/2.2.3...2.2.4 [2.2.3]: https://github.com/composer/composer/compare/2.2.2...2.2.3 From ce785a18c0fb472421e52d958bab339247cb0e82 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 4 Feb 2022 17:00:38 +0100 Subject: [PATCH 23/23] Release 2.2.6 --- src/Composer/Composer.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Composer/Composer.php b/src/Composer/Composer.php index 624e0250764e..8c74a689a577 100644 --- a/src/Composer/Composer.php +++ b/src/Composer/Composer.php @@ -52,10 +52,10 @@ class Composer * const RELEASE_DATE = '@release_date@'; * const SOURCE_VERSION = '1.8-dev+source'; */ - const VERSION = '@package_version@'; - const BRANCH_ALIAS_VERSION = '@package_branch_alias_version@'; - const RELEASE_DATE = '@release_date@'; - const SOURCE_VERSION = '2.2.999-dev+source'; + const VERSION = '2.2.6'; + const BRANCH_ALIAS_VERSION = ''; + const RELEASE_DATE = '2022-02-04 17:00:38'; + const SOURCE_VERSION = ''; /** * Version number of the internal composer-runtime-api package