From 0a4c0778abdd014d9f4c7e18e0c2fb6605782270 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Wed, 9 Mar 2022 21:00:00 +0100 Subject: [PATCH 01/16] Propagate decoration state to repo warnings, fixes #10601 --- src/Composer/Util/HttpDownloader.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Composer/Util/HttpDownloader.php b/src/Composer/Util/HttpDownloader.php index 6b3e7d61d..79d06d164 100644 --- a/src/Composer/Util/HttpDownloader.php +++ b/src/Composer/Util/HttpDownloader.php @@ -454,6 +454,14 @@ class HttpDownloader */ public static function outputWarnings(IOInterface $io, $url, $data) { + $cleanMessage = function ($msg) use ($io) { + if (!$io->isDecorated()) { + $msg = Preg::replace('{'.chr(27).'\\[[;\d]*m}u', '', $msg); + } + + return $msg; + }; + // legacy warning/info keys foreach (array('warning', 'info') as $type) { if (empty($data[$type])) { @@ -469,7 +477,7 @@ class HttpDownloader } } - $io->writeError('<'.$type.'>'.ucfirst($type).' from '.Url::sanitize($url).': '.$data[$type].''); + $io->writeError('<'.$type.'>'.ucfirst($type).' from '.Url::sanitize($url).': '.$cleanMessage($data[$type]).''); } // modern Composer 2.2+ format with support for multiple warning/info messages @@ -487,7 +495,7 @@ class HttpDownloader continue; } - $io->writeError('<'.$type.'>'.ucfirst($type).' from '.Url::sanitize($url).': '.$spec['message'].''); + $io->writeError('<'.$type.'>'.ucfirst($type).' from '.Url::sanitize($url).': '.$cleanMessage($spec['message']).''); } } } From b3f99faff737d07715246711863103b55d962d5e Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Wed, 9 Mar 2022 21:39:18 +0100 Subject: [PATCH 02/16] Fix tests --- tests/Composer/Test/Fixtures/functional/installed-versions.test | 2 +- .../Composer/Test/Fixtures/functional/installed-versions2.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Composer/Test/Fixtures/functional/installed-versions.test b/tests/Composer/Test/Fixtures/functional/installed-versions.test index fa9386c17..42bc212fd 100644 --- a/tests/Composer/Test/Fixtures/functional/installed-versions.test +++ b/tests/Composer/Test/Fixtures/functional/installed-versions.test @@ -11,7 +11,7 @@ update !!PreUpdate:["composer/ca-bundle","composer/composer","composer/metadata-minifier","composer/pcre","composer/semver","composer/spdx-licenses","composer/xdebug-handler","justinrainbow/json-schema","psr/log","react/promise","seld/jsonlint","seld/phar-utils","symfony/console","symfony/debug","symfony/filesystem","symfony/finder","symfony/polyfill-ctype","symfony/polyfill-mbstring","symfony/process"] !!Versions:console:%[2-8]\.\d+\.\d+.0%;process:%[2-8]\.\d+\.\d+.0%;filesystem:%[2-8]\.\d+\.\d+.0% Loading composer repositories with package information -Updating dependencies +%((Info|Warning) from .*\n)?%Updating dependencies Lock file operations: 6 installs, 0 updates, 0 removals - Locking plugin/a (1.1.1) - Locking plugin/b (2.2.2) diff --git a/tests/Composer/Test/Fixtures/functional/installed-versions2.test b/tests/Composer/Test/Fixtures/functional/installed-versions2.test index bec76d430..2d7ef199d 100644 --- a/tests/Composer/Test/Fixtures/functional/installed-versions2.test +++ b/tests/Composer/Test/Fixtures/functional/installed-versions2.test @@ -17,7 +17,7 @@ update plugin/* symfony/console symfony/filesystem symfony/process !!PreUpdate:["composer/ca-bundle","composer/composer","composer/metadata-minifier","composer/pcre","composer/semver","composer/spdx-licenses","composer/xdebug-handler","justinrainbow/json-schema","psr/log","react/promise","seld/jsonlint","seld/phar-utils","symfony/console","symfony/debug","symfony/filesystem","symfony/finder","symfony/polyfill-ctype","symfony/polyfill-mbstring","symfony/process","plugin/a","plugin/b","root/pkg"] !!Versions:console:%[2-8]\.\d+\.\d+.0%;process:%[2-8]\.\d+\.\d+.0%;filesystem:%[2-8]\.\d+\.\d+.0% Loading composer repositories with package information -Updating dependencies +%((Info|Warning) from .*\n)?%Updating dependencies Lock file operations: 0 installs, 5 updates, 0 removals - Upgrading plugin/a (1.1.1 => 1.1.2) - Upgrading plugin/b (2.2.2 => 2.2.3) From ced24da7b012ec666d8d02ec71ffbcec6e4fb021 Mon Sep 17 00:00:00 2001 From: Yanick Witschi Date: Sat, 12 Mar 2022 14:16:38 +0100 Subject: [PATCH 03/16] Fix PoolOptimizer should consider disjunctive MultiConstraints (#10579) --- .../DependencyResolver/PoolOptimizer.php | 60 +++++++++++++++++-- .../pooloptimizer/basic-prefer-highest.test | 10 +++- .../pooloptimizer/complex-prefer-lowest.test | 55 +++++++++++++++++ 3 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 tests/Composer/Test/DependencyResolver/Fixtures/pooloptimizer/complex-prefer-lowest.test diff --git a/src/Composer/DependencyResolver/PoolOptimizer.php b/src/Composer/DependencyResolver/PoolOptimizer.php index ef17938b5..939e54a8d 100644 --- a/src/Composer/DependencyResolver/PoolOptimizer.php +++ b/src/Composer/DependencyResolver/PoolOptimizer.php @@ -110,21 +110,18 @@ class PoolOptimizer // Extract requested package requirements foreach ($request->getRequires() as $require => $constraint) { - $constraint = Intervals::compactConstraint($constraint); - $this->requireConstraintsPerPackage[$require][(string) $constraint] = $constraint; + $this->extractRequireConstraintsPerPackage($require, $constraint); } // First pass over all packages to extract information and mark package constraints irremovable foreach ($pool->getPackages() as $package) { // Extract package requirements foreach ($package->getRequires() as $link) { - $constraint = Intervals::compactConstraint($link->getConstraint()); - $this->requireConstraintsPerPackage[$link->getTarget()][(string) $constraint] = $constraint; + $this->extractRequireConstraintsPerPackage($link->getTarget(), $link->getConstraint()); } // Extract package conflicts foreach ($package->getConflicts() as $link) { - $constraint = Intervals::compactConstraint($link->getConstraint()); - $this->conflictConstraintsPerPackage[$link->getTarget()][(string) $constraint] = $constraint; + $this->extractConflictConstraintsPerPackage($link->getTarget(), $link->getConstraint()); } // Keep track of alias packages for every package so if either the alias or aliased is kept @@ -453,4 +450,55 @@ class PoolOptimizer } } } + + /** + * Disjunctive require constraints need to be considered in their own group. E.g. "^2.14 || ^3.3" needs to generate + * two require constraint groups in order for us to keep the best matching package for "^2.14" AND "^3.3" as otherwise, we'd + * only keep either one which can cause trouble (e.g. when using --prefer-lowest). + * + * @param string $package + * @param ConstraintInterface $constraint + * @return void + */ + private function extractRequireConstraintsPerPackage($package, ConstraintInterface $constraint) + { + foreach ($this->expandDisjunctiveMultiConstraints($constraint) as $expanded) { + $this->requireConstraintsPerPackage[$package][(string) $expanded] = $expanded; + } + } + + /** + * Disjunctive conflict constraints need to be considered in their own group. E.g. "^2.14 || ^3.3" needs to generate + * two conflict constraint groups in order for us to keep the best matching package for "^2.14" AND "^3.3" as otherwise, we'd + * only keep either one which can cause trouble (e.g. when using --prefer-lowest). + * + * @param string $package + * @param ConstraintInterface $constraint + * @return void + */ + private function extractConflictConstraintsPerPackage($package, ConstraintInterface $constraint) + { + foreach ($this->expandDisjunctiveMultiConstraints($constraint) as $expanded) { + $this->conflictConstraintsPerPackage[$package][(string) $expanded] = $expanded; + } + } + + /** + * + * @param ConstraintInterface $constraint + * @return ConstraintInterface[] + */ + private function expandDisjunctiveMultiConstraints(ConstraintInterface $constraint) + { + $constraint = Intervals::compactConstraint($constraint); + + if ($constraint instanceof MultiConstraint && $constraint->isDisjunctive()) { + // No need to call ourselves recursively here because Intervals::compactConstraint() ensures that there + // are no nested disjunctive MultiConstraint instances possible + return $constraint->getConstraints(); + } + + // Regular constraints and conjunctive MultiConstraints + return array($constraint); + } } diff --git a/tests/Composer/Test/DependencyResolver/Fixtures/pooloptimizer/basic-prefer-highest.test b/tests/Composer/Test/DependencyResolver/Fixtures/pooloptimizer/basic-prefer-highest.test index 91131b790..904d6c375 100644 --- a/tests/Composer/Test/DependencyResolver/Fixtures/pooloptimizer/basic-prefer-highest.test +++ b/tests/Composer/Test/DependencyResolver/Fixtures/pooloptimizer/basic-prefer-highest.test @@ -15,7 +15,7 @@ Test filters irrelevant package "package/b" in version 1.0.0 "name": "package/a", "version": "1.0.0", "require": { - "package/b": "^1.0" + "package/b": ">=1.0 <1.1 || ^1.2" } }, { @@ -25,6 +25,10 @@ Test filters irrelevant package "package/b" in version 1.0.0 { "name": "package/b", "version": "1.0.1" + }, + { + "name": "package/b", + "version": "1.2.0" } ] @@ -41,6 +45,10 @@ Test filters irrelevant package "package/b" in version 1.0.0 { "name": "package/b", "version": "1.0.1" + }, + { + "name": "package/b", + "version": "1.2.0" } ] diff --git a/tests/Composer/Test/DependencyResolver/Fixtures/pooloptimizer/complex-prefer-lowest.test b/tests/Composer/Test/DependencyResolver/Fixtures/pooloptimizer/complex-prefer-lowest.test new file mode 100644 index 000000000..74240e145 --- /dev/null +++ b/tests/Composer/Test/DependencyResolver/Fixtures/pooloptimizer/complex-prefer-lowest.test @@ -0,0 +1,55 @@ +--TEST-- +Test keeps package "package/b" in version 2.2.0 because for prefer-lowest either one might be relevant + +--REQUEST-- +{ + "require": { + "package/a": "^1.0" + }, + "preferLowest": true +} + + +--POOL-BEFORE-- +[ + { + "name": "package/a", + "version": "1.0.0", + "require": { + "package/b": "^1.0 || ^2.2" + } + }, + { + "name": "package/b", + "version": "1.0.0" + }, + { + "name": "package/b", + "version": "1.0.1" + }, + { + "name": "package/b", + "version": "2.2.0" + } +] + + +--POOL-AFTER-- +[ + { + "name": "package/a", + "version": "1.0.0", + "require": { + "package/b": "^1.0" + } + }, + { + "name": "package/b", + "version": "1.0.0" + }, + { + "name": "package/b", + "version": "2.2.0" + } +] + From 5b7ea9580eeaac1712b1b4c6558a1223100714af Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 15 Mar 2022 09:43:22 +0100 Subject: [PATCH 04/16] Update composer/semver to latest --- composer.lock | 12 ++++++------ src/Composer/Installer.php | 4 ++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 02adf842b..d81c1f446 100644 --- a/composer.lock +++ b/composer.lock @@ -224,16 +224,16 @@ }, { "name": "composer/semver", - "version": "3.2.9", + "version": "3.3.0", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649" + "reference": "f79c90ad4e9b41ac4dfc5d77bf398cf61fbd718b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/a951f614bd64dcd26137bc9b7b2637ddcfc57649", - "reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649", + "url": "https://api.github.com/repos/composer/semver/zipball/f79c90ad4e9b41ac4dfc5d77bf398cf61fbd718b", + "reference": "f79c90ad4e9b41ac4dfc5d77bf398cf61fbd718b", "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.9" + "source": "https://github.com/composer/semver/tree/3.3.0" }, "funding": [ { @@ -301,7 +301,7 @@ "type": "tidelift" } ], - "time": "2022-02-04T13:58:43+00:00" + "time": "2022-03-15T08:35:57+00:00" }, { "name": "composer/spdx-licenses", diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index 8bd88e5b9..7d4be070f 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -473,6 +473,10 @@ class Installer return $exitCode; } + if (method_exists('Composer\Semver\CompilingMatcher', 'clear')) { + \Composer\Semver\CompilingMatcher::clear(); + } + // write lock $platformReqs = $this->extractPlatformRequirements($this->package->getRequires()); $platformDevReqs = $this->extractPlatformRequirements($this->package->getDevRequires()); From 890b8fad3de8dc86d98a9cf0f578d86cb591205d Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 15 Mar 2022 10:01:23 +0100 Subject: [PATCH 05/16] Ignore phpstan issue --- src/Composer/Installer.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index 7d4be070f..31aacde00 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -473,7 +473,8 @@ class Installer return $exitCode; } - if (method_exists('Composer\Semver\CompilingMatcher', 'clear')) { + // exists as of composer/semver 3.3.0 + if (method_exists('Composer\Semver\CompilingMatcher', 'clear')) { // @phpstan-ignore-line \Composer\Semver\CompilingMatcher::clear(); } From e9680c4c5497b38e0e158c20aeee921b85bceef2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Tue, 15 Mar 2022 10:21:11 +0100 Subject: [PATCH 06/16] Enhancement: Update actions/stale (#10610) --- .github/workflows/close-stale-support.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/close-stale-support.yml b/.github/workflows/close-stale-support.yml index 76348915b..6d92d8b59 100644 --- a/.github/workflows/close-stale-support.yml +++ b/.github/workflows/close-stale-support.yml @@ -13,7 +13,7 @@ jobs: pull-requests: write steps: - - uses: actions/stale@v3 + - uses: actions/stale@v5 with: repo-token: ${{ secrets.GITHUB_TOKEN }} days-before-stale: 180 From 58deb390296117fa91db17b225cda1e7923d1402 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Tue, 15 Mar 2022 10:22:01 +0100 Subject: [PATCH 07/16] Enhancement: Update actions/github-script (#10612) --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e4af09c10..e3d872d60 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -81,14 +81,14 @@ jobs: # This step requires a secret token with `pull` access to composer/docker. The default # secrets.GITHUB_TOKEN is scoped to this repository only which is not sufficient. - name: "Open issue @ Docker repository" - uses: actions/github-script@v2 + uses: actions/github-script@v6 with: github-token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }} script: | // github.ref value looks like 'refs/tags/TAG', cleanup const tag = "${{ github.ref }}".replace(/refs\/tags\//, ''); // create new issue on Docker repository - github.issues.create({ + github.rest.issues.create({ owner: "${{ github.repository_owner }}", repo: "docker", title: `New Composer tag: ${ tag }`, From d67953266f2aae4d4f23447b654494d32e112fbe Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 15 Mar 2022 11:03:53 +0100 Subject: [PATCH 08/16] Do not read require-dev except for the root package when sorting packages --- src/Composer/Util/PackageSorter.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Composer/Util/PackageSorter.php b/src/Composer/Util/PackageSorter.php index df2d89a4b..01aabfc74 100644 --- a/src/Composer/Util/PackageSorter.php +++ b/src/Composer/Util/PackageSorter.php @@ -13,6 +13,7 @@ namespace Composer\Util; use Composer\Package\PackageInterface; +use Composer\Package\RootPackageInterface; class PackageSorter { @@ -29,7 +30,11 @@ class PackageSorter $usageList = array(); foreach ($packages as $package) { - foreach (array_merge($package->getRequires(), $package->getDevRequires()) as $link) { + $links = $package->getRequires(); + if ($package instanceof RootPackageInterface) { + $links = array_merge($links, $package->getDevRequires()); + } + foreach ($links as $link) { $target = $link->getTarget(); $usageList[$target][] = $package->getName(); } From f31700bf1983879a6f519ca6e50fc5591845de3b Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 15 Mar 2022 11:04:30 +0100 Subject: [PATCH 09/16] Sort packages with the same weight alphabetically to have a completely stable sort not dependent on input order, fixes #10614 --- src/Composer/Autoload/AutoloadGenerator.php | 2 +- src/Composer/Util/PackageSorter.php | 37 ++++++------------- .../Test/Autoload/AutoloadGeneratorTest.php | 8 ++++ .../autoload_static_files_by_dependency.php | 2 +- .../Composer/Test/Util/PackageSorterTest.php | 14 +++++++ 5 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/Composer/Autoload/AutoloadGenerator.php b/src/Composer/Autoload/AutoloadGenerator.php index efb8c7cef..b31f9ed67 100644 --- a/src/Composer/Autoload/AutoloadGenerator.php +++ b/src/Composer/Autoload/AutoloadGenerator.php @@ -1379,7 +1379,7 @@ INITIALIZER; /** * Sorts packages by dependency weight * - * Packages of equal weight retain the original order + * Packages of equal weight are sorted alphabetically * * @param array $packageMap * @return array diff --git a/src/Composer/Util/PackageSorter.php b/src/Composer/Util/PackageSorter.php index 01aabfc74..63e4a93cb 100644 --- a/src/Composer/Util/PackageSorter.php +++ b/src/Composer/Util/PackageSorter.php @@ -20,7 +20,7 @@ class PackageSorter /** * Sorts packages by dependency weight * - * Packages of equal weight retain the original order + * Packages of equal weight are sorted alphabetically * * @param PackageInterface[] $packages * @return PackageInterface[] sorted array @@ -67,39 +67,26 @@ class PackageSorter return $weight; }; - $weightList = array(); + $weightedPackages = array(); foreach ($packages as $index => $package) { - $weight = $computeImportance($package->getName()); - $weightList[$index] = $weight; + $name = $package->getName(); + $weight = $computeImportance($name); + $weightedPackages[] = array('name' => $name, 'weight' => $weight, 'index' => $index); } - $stable_sort = function (&$array) { - static $transform, $restore; - - $i = 0; - - if (!$transform) { - $transform = function (&$v, $k) use (&$i) { - $v = array($v, ++$i, $k, $v); - }; - - $restore = function (&$v) { - $v = $v[3]; - }; + usort($weightedPackages, function ($a, $b) { + if ($a['weight'] !== $b['weight']) { + return $a['weight'] - $b['weight']; } - array_walk($array, $transform); - asort($array); - array_walk($array, $restore); - }; - - $stable_sort($weightList); + return strnatcasecmp($a['name'], $b['name']); + }); $sortedPackages = array(); - foreach (array_keys($weightList) as $index) { - $sortedPackages[] = $packages[$index]; + foreach ($weightedPackages as $pkg) { + $sortedPackages[] = $packages[$pkg['index']]; } return $sortedPackages; diff --git a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php index 0a801ad63..c29121f21 100644 --- a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php +++ b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php @@ -1017,6 +1017,14 @@ EOF; $packages[] = $c = new Package('c/lorem', '1.0', '1.0'); $packages[] = $e = new Package('e/e', '1.0', '1.0'); + // expected order: + // c requires nothing + // d requires c + // b requires c & d + // e requires c + // z requires c + // (b, e, z ordered alphabetically) + $z->setAutoload(array('files' => array('testA.php'))); $z->setRequires(array('c/lorem' => new Link('z/foo', 'c/lorem', new MatchAllConstraint()))); diff --git a/tests/Composer/Test/Autoload/Fixtures/autoload_static_files_by_dependency.php b/tests/Composer/Test/Autoload/Fixtures/autoload_static_files_by_dependency.php index e3659aee3..addd6cc3f 100644 --- a/tests/Composer/Test/Autoload/Fixtures/autoload_static_files_by_dependency.php +++ b/tests/Composer/Test/Autoload/Fixtures/autoload_static_files_by_dependency.php @@ -9,9 +9,9 @@ class ComposerStaticInitFilesAutoloadOrder public static $files = array ( 'bfdd693009729d60c830ff8d79129635' => __DIR__ . '/..' . '/c/lorem/testC.php', '61e6098c8cafe404d6cf19e59fc2b788' => __DIR__ . '/..' . '/d/d/testD.php', - '8bceec6fdc149a1a6acbf7ad3cfed51c' => __DIR__ . '/..' . '/z/foo/testA.php', 'c5466e580c6c2403f225c43b6a21a96f' => __DIR__ . '/..' . '/b/bar/testB.php', '69dfc37c40a853a7cbac6c9d2367c5f4' => __DIR__ . '/..' . '/e/e/testE.php', + '8bceec6fdc149a1a6acbf7ad3cfed51c' => __DIR__ . '/..' . '/z/foo/testA.php', 'ab280164f4754f5dfdb0721de84d737f' => __DIR__ . '/../..' . '/root2.php', ); diff --git a/tests/Composer/Test/Util/PackageSorterTest.php b/tests/Composer/Test/Util/PackageSorterTest.php index 7ee94982c..b4c7e2b8a 100644 --- a/tests/Composer/Test/Util/PackageSorterTest.php +++ b/tests/Composer/Test/Util/PackageSorterTest.php @@ -99,6 +99,20 @@ class PackageSorterTest extends TestCase 'foo/bar6', ), ), + 'equal weight sorted alphabetically' => array( + array( + $this->createPackage('foo/bar10', array('foo/dep')), + $this->createPackage('foo/bar2', array('foo/dep')), + $this->createPackage('foo/baz', array('foo/dep')), + $this->createPackage('foo/dep', array()), + ), + array( + 'foo/dep', + 'foo/bar2', + 'foo/bar10', + 'foo/baz', + ), + ), ); } From dbcdb4a9038c08aefbc112cafb0f342b8f1312e1 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 15 Mar 2022 12:02:03 +0100 Subject: [PATCH 10/16] Add test for circular depths of equal weight --- tests/Composer/Test/Util/PackageSorterTest.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/Composer/Test/Util/PackageSorterTest.php b/tests/Composer/Test/Util/PackageSorterTest.php index b4c7e2b8a..5790ba04f 100644 --- a/tests/Composer/Test/Util/PackageSorterTest.php +++ b/tests/Composer/Test/Util/PackageSorterTest.php @@ -99,6 +99,20 @@ class PackageSorterTest extends TestCase 'foo/bar6', ), ), + 'circular deps sorted alphabetically if weighted equally' => array( + array( + $this->createPackage('foo/bar1', array('circular/part1')), + $this->createPackage('foo/bar2', array('circular/part2')), + $this->createPackage('circular/part1', array('circular/part2')), + $this->createPackage('circular/part2', array('circular/part1')), + ), + array( + 'circular/part1', + 'circular/part2', + 'foo/bar1', + 'foo/bar2', + ), + ), 'equal weight sorted alphabetically' => array( array( $this->createPackage('foo/bar10', array('foo/dep')), From bf235eba5646f2a21510d0769492ca45a5584830 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 15 Mar 2022 12:24:35 +0100 Subject: [PATCH 11/16] Add note about plugin autoloading, refs #10587 --- doc/articles/plugins.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/articles/plugins.md b/doc/articles/plugins.md index e3df2cf95..fc017e688 100644 --- a/doc/articles/plugins.md +++ b/doc/articles/plugins.md @@ -323,6 +323,13 @@ hint to Composer that the plugin should be installed on its own before proceedin the rest of the package downloads. This slightly slows down the overall installation process however, so do not use it in plugins which do not absolutely require it. +## Plugin Autoloading + +Due to plugins being loaded by Composer at runtime, and to ensure that plugins which +depend on other packages can function correctly, a runtime autoloader is created whenever +a plugin is loaded. That autoloader is only configured to load with the plugin dependencies, +so you may not have access to all the packages which are installed. + [1]: ../04-schema.md#type [2]: ../04-schema.md#extra [3]: https://github.com/composer/composer/blob/main/src/Composer/Plugin/PluginInterface.php From 2d7f1569f3f12cb6e58486a7b12cd3e4d428df11 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 15 Mar 2022 12:26:32 +0100 Subject: [PATCH 12/16] Allow using self.version with require command, fixes #10593 --- src/Composer/Command/RequireCommand.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Composer/Command/RequireCommand.php b/src/Composer/Command/RequireCommand.php index 92fc2114a..ed918f9ab 100644 --- a/src/Composer/Command/RequireCommand.php +++ b/src/Composer/Command/RequireCommand.php @@ -225,6 +225,9 @@ EOT return 1; } + if ($constraint === 'self.version') { + continue; + } $versionParser->parseConstraints($constraint); } From dca2d49d0c00aa3a4ab47a78288fa9abe37374fa Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 5 Mar 2022 19:17:37 +0100 Subject: [PATCH 13/16] GH Actions: version update for various predefined actions A number of predefined actions have had major release, which warrant an update to the workflow(s). These updates don't actually contain any changed functionality, they are mostly just a change of the Node version used by the action itself (from Node 14 to Node 16). Refs: * https://github.com/actions/checkout/releases P.S.: looks like there are some more actions in use which have had new major releases. As those actually _do_ contain changed functionality, I've excluded the others from this PR. --- .github/workflows/continuous-integration.yml | 4 ++-- .github/workflows/lint.yml | 2 +- .github/workflows/phpstan.yml | 2 +- .github/workflows/release.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 4acf1f584..76da0e4fe 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -64,7 +64,7 @@ jobs: steps: - name: "Checkout" - uses: "actions/checkout@v2" + uses: "actions/checkout@v3" - name: "Install PHP" uses: "shivammathur/setup-php@v2" @@ -138,7 +138,7 @@ jobs: steps: - name: "Checkout" - uses: "actions/checkout@v2" + uses: "actions/checkout@v3" - name: "Install PHP" uses: "shivammathur/setup-php@v2" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index be342746d..3058417b3 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -22,7 +22,7 @@ jobs: steps: - name: "Checkout" - uses: "actions/checkout@v2" + uses: "actions/checkout@v3" - name: "Install PHP" uses: "shivammathur/setup-php@v2" diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 5881fb0b7..849c2cb1f 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -25,7 +25,7 @@ jobs: steps: - name: "Checkout" - uses: "actions/checkout@v2" + uses: "actions/checkout@v3" - name: "Install PHP" uses: "shivammathur/setup-php@v2" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e3d872d60..c45cb57b3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: "Install PHP" uses: "shivammathur/setup-php@v2" From 8eb7f637307a41b658b402a3a8ee42fa8f74f8a1 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 15 Mar 2022 12:55:12 +0100 Subject: [PATCH 14/16] Update changelog --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index baf972ae2..46ad54018 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +### [2.2.8] 2022-03-15 + + * Fixed `files` autoloading sort order to be fully deterministic (#10617) + * Fixed pool optimization pass edge cases (#10579) + * Fixed `require` command failing when `self.version` is used as constraint (#10593) + * Fixed --no-ansi / undecorated output still showing color in repo warnings (#10601) + * Performance improvement in pool optimization step (composer/semver#131) + ### [2.2.7] 2022-02-25 * Allow installation together with composer/xdebug-handler ^3 (#10528) @@ -1394,6 +1402,7 @@ * Initial release +[2.2.8]: https://github.com/composer/composer/compare/2.2.7...2.2.8 [2.2.7]: https://github.com/composer/composer/compare/2.2.6...2.2.7 [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 From 26a587345daa2772bbe2006f13cd9d7f92b242eb Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 15 Mar 2022 12:55:20 +0100 Subject: [PATCH 15/16] Release 2.2.8 --- 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 624e02507..1a7ad4efe 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.8'; + const BRANCH_ALIAS_VERSION = ''; + const RELEASE_DATE = '2022-03-15 12:55:20'; + const SOURCE_VERSION = ''; /** * Version number of the internal composer-runtime-api package From 7bee425b5803ea8bf7449a9d0d0805ec98aba43b Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 15 Mar 2022 12:55:21 +0100 Subject: [PATCH 16/16] 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 1a7ad4efe..624e02507 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.8'; - const BRANCH_ALIAS_VERSION = ''; - const RELEASE_DATE = '2022-03-15 12:55:20'; - 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