Fix many PHPStan errors in DependencyResolver namespace (#12121)
parent
3a2a18175d
commit
6b81140f81
|
@ -305,24 +305,24 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "composer/semver",
|
"name": "composer/semver",
|
||||||
"version": "3.4.2",
|
"version": "3.4.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/composer/semver.git",
|
"url": "https://github.com/composer/semver.git",
|
||||||
"reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6"
|
"reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/composer/semver/zipball/c51258e759afdb17f1fd1fe83bc12baaef6309d6",
|
"url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12",
|
||||||
"reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6",
|
"reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^5.3.2 || ^7.0 || ^8.0"
|
"php": "^5.3.2 || ^7.0 || ^8.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpstan/phpstan": "^1.4",
|
"phpstan/phpstan": "^1.11",
|
||||||
"symfony/phpunit-bridge": "^4.2 || ^5"
|
"symfony/phpunit-bridge": "^3 || ^7"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
|
@ -366,7 +366,7 @@
|
||||||
"support": {
|
"support": {
|
||||||
"irc": "ircs://irc.libera.chat:6697/composer",
|
"irc": "ircs://irc.libera.chat:6697/composer",
|
||||||
"issues": "https://github.com/composer/semver/issues",
|
"issues": "https://github.com/composer/semver/issues",
|
||||||
"source": "https://github.com/composer/semver/tree/3.4.2"
|
"source": "https://github.com/composer/semver/tree/3.4.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -382,7 +382,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-07-12T11:35:52+00:00"
|
"time": "2024-09-19T14:15:21+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "composer/spdx-licenses",
|
"name": "composer/spdx-licenses",
|
||||||
|
@ -2020,16 +2020,16 @@
|
||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
{
|
{
|
||||||
"name": "phpstan/phpstan",
|
"name": "phpstan/phpstan",
|
||||||
"version": "1.12.3",
|
"version": "1.12.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/phpstan/phpstan.git",
|
"url": "https://github.com/phpstan/phpstan.git",
|
||||||
"reference": "0fcbf194ab63d8159bb70d9aa3e1350051632009"
|
"reference": "ffa517cb918591b93acc9b95c0bebdcd0e4538bd"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/0fcbf194ab63d8159bb70d9aa3e1350051632009",
|
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/ffa517cb918591b93acc9b95c0bebdcd0e4538bd",
|
||||||
"reference": "0fcbf194ab63d8159bb70d9aa3e1350051632009",
|
"reference": "ffa517cb918591b93acc9b95c0bebdcd0e4538bd",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -2074,7 +2074,7 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-09-09T08:10:35+00:00"
|
"time": "2024-09-19T07:58:01+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpstan/phpstan-deprecation-rules",
|
"name": "phpstan/phpstan-deprecation-rules",
|
||||||
|
|
|
@ -670,16 +670,6 @@ parameters:
|
||||||
count: 1
|
count: 1
|
||||||
path: ../src/Composer/Command/ShowCommand.php
|
path: ../src/Composer/Command/ShowCommand.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in &&, array\\<Composer\\\\Package\\\\BasePackage\\|int\\> given on the right side\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/Command/ShowCommand.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in &&, array\\<int\\> given on the right side\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/Command/ShowCommand.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Only booleans are allowed in &&, string given on the left side\\.$#"
|
message: "#^Only booleans are allowed in &&, string given on the left side\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
@ -800,11 +790,6 @@ parameters:
|
||||||
count: 2
|
count: 2
|
||||||
path: ../src/Composer/Command/ShowCommand.php
|
path: ../src/Composer/Command/ShowCommand.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#2 \\$literals of method Composer\\\\DependencyResolver\\\\DefaultPolicy\\:\\:selectPreferredPackages\\(\\) expects array\\<int\\>, array\\<Composer\\\\Package\\\\BasePackage\\|int\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/Command/ShowCommand.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Parameter \\#2 \\.\\.\\.\\$values of function sprintf expects bool\\|float\\|int\\|string\\|null, array\\|string given\\.$#"
|
message: "#^Parameter \\#2 \\.\\.\\.\\$values of function sprintf expects bool\\|float\\|int\\|string\\|null, array\\|string given\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
@ -905,19 +890,9 @@ parameters:
|
||||||
count: 1
|
count: 1
|
||||||
path: ../src/Composer/Command/UpdateCommand.php
|
path: ../src/Composer/Command/UpdateCommand.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Call to function in_array\\(\\) requires parameter \\#3 to be set\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/Command/UpdateCommand.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
||||||
count: 3
|
count: 2
|
||||||
path: ../src/Composer/Command/UpdateCommand.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in a negated boolean, array\\<string\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/Command/UpdateCommand.php
|
path: ../src/Composer/Command/UpdateCommand.php
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -1095,96 +1070,11 @@ parameters:
|
||||||
count: 1
|
count: 1
|
||||||
path: ../src/Composer/Console/GithubActionError.php
|
path: ../src/Composer/Console/GithubActionError.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
|
||||||
count: 2
|
|
||||||
path: ../src/Composer/DependencyResolver/Decisions.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Method Composer\\\\DependencyResolver\\\\Decisions\\:\\:key\\(\\) should return int\\|null but returns int\\|string\\|null\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Decisions.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in a ternary operator condition, Composer\\\\DependencyResolver\\\\Pool\\|null given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Decisions.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Return type \\(array\\{int, Composer\\\\DependencyResolver\\\\Rule\\}\\|false\\) of method Composer\\\\DependencyResolver\\\\Decisions\\:\\:current\\(\\) should be covariant with return type \\(array\\{int, Composer\\\\DependencyResolver\\\\Rule\\}\\) of method Iterator\\<mixed,array\\<int, Composer\\\\DependencyResolver\\\\Rule\\|int\\>\\>\\:\\:current\\(\\)$#"
|
message: "#^Return type \\(array\\{int, Composer\\\\DependencyResolver\\\\Rule\\}\\|false\\) of method Composer\\\\DependencyResolver\\\\Decisions\\:\\:current\\(\\) should be covariant with return type \\(array\\{int, Composer\\\\DependencyResolver\\\\Rule\\}\\) of method Iterator\\<mixed,array\\<int, Composer\\\\DependencyResolver\\\\Rule\\|int\\>\\>\\:\\:current\\(\\)$#"
|
||||||
count: 1
|
count: 1
|
||||||
path: ../src/Composer/DependencyResolver/Decisions.php
|
path: ../src/Composer/DependencyResolver/Decisions.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in &&, string\\|null given on the left side\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/DefaultPolicy.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Cannot access offset 'hash' on array\\|false\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/GenericRule.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Cannot access offset 'hash' on array\\|false\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/MultiConflictRule.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in \\|\\|, mixed given on the right side\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Pool.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Cannot call method getPackages\\(\\) on Composer\\\\Repository\\\\LockArrayRepository\\|null\\.$#"
|
|
||||||
count: 2
|
|
||||||
path: ../src/Composer/DependencyResolver/PoolBuilder.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
|
||||||
count: 2
|
|
||||||
path: ../src/Composer/DependencyResolver/PoolBuilder.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in a negated boolean, array\\<string\\> given\\.$#"
|
|
||||||
count: 2
|
|
||||||
path: ../src/Composer/DependencyResolver/PoolBuilder.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, Composer\\\\EventDispatcher\\\\EventDispatcher\\|null given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/PoolBuilder.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, array\\<string\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/PoolBuilder.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, mixed given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/PoolBuilder.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#4 \\$index of method Composer\\\\DependencyResolver\\\\PoolBuilder\\:\\:removeLoadedPackage\\(\\) expects int, int\\|string given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/PoolBuilder.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in a negated boolean, array\\<int, string\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/PoolOptimizer.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, array\\<Composer\\\\Package\\\\Link\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/PoolOptimizer.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, mixed given\\.$#"
|
|
||||||
count: 4
|
|
||||||
path: ../src/Composer/DependencyResolver/PoolOptimizer.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Cannot call method getPrettyString\\(\\) on array\\<string, Composer\\\\Package\\\\BasePackage\\|Composer\\\\Semver\\\\Constraint\\\\ConstraintInterface\\|string\\>\\|Composer\\\\Package\\\\BasePackage\\|Composer\\\\Package\\\\Link\\|int\\|string\\.$#"
|
message: "#^Cannot call method getPrettyString\\(\\) on array\\<string, Composer\\\\Package\\\\BasePackage\\|Composer\\\\Semver\\\\Constraint\\\\ConstraintInterface\\|string\\>\\|Composer\\\\Package\\\\BasePackage\\|Composer\\\\Package\\\\Link\\|int\\|string\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
@ -1192,11 +1082,6 @@ parameters:
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Cannot call method getRepoName\\(\\) on Composer\\\\Repository\\\\RepositoryInterface\\|null\\.$#"
|
message: "#^Cannot call method getRepoName\\(\\) on Composer\\\\Repository\\\\RepositoryInterface\\|null\\.$#"
|
||||||
count: 3
|
|
||||||
path: ../src/Composer/DependencyResolver/Problem.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Cannot call method getRepository\\(\\) on Composer\\\\Package\\\\PackageInterface\\|false\\.$#"
|
|
||||||
count: 1
|
count: 1
|
||||||
path: ../src/Composer/DependencyResolver/Problem.php
|
path: ../src/Composer/DependencyResolver/Problem.php
|
||||||
|
|
||||||
|
@ -1205,311 +1090,11 @@ parameters:
|
||||||
count: 1
|
count: 1
|
||||||
path: ../src/Composer/DependencyResolver/Problem.php
|
path: ../src/Composer/DependencyResolver/Problem.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in &&, Composer\\\\DependencyResolver\\\\Pool\\|null given on the left side\\.$#"
|
|
||||||
count: 2
|
|
||||||
path: ../src/Composer/DependencyResolver/Problem.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in &&, Composer\\\\Semver\\\\Constraint\\\\ConstraintInterface\\|null given on the right side\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Problem.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in a negated boolean, array\\<Composer\\\\Package\\\\BasePackage\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Problem.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in a ternary operator condition, Composer\\\\Semver\\\\Constraint\\\\ConstraintInterface\\|null given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Problem.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in a ternary operator condition, string given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Problem.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, Composer\\\\Package\\\\BasePackage\\|null given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Problem.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, array\\<Composer\\\\Package\\\\BasePackage\\> given\\.$#"
|
|
||||||
count: 5
|
|
||||||
path: ../src/Composer/DependencyResolver/Problem.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, array\\<Composer\\\\Package\\\\PackageInterface\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Problem.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, array\\<string, array\\<string, string\\>\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Problem.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, int\\<0, max\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Problem.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, string\\|null given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Problem.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Short ternary operator is not allowed\\. Use null coalesce operator if applicable or consider using long ternary\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Problem.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, Composer\\\\Repository\\\\LockArrayRepository\\|null given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Request.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Foreach overwrites \\$literal with its value variable\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Rule.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Method Composer\\\\DependencyResolver\\\\Rule\\:\\:getReason\\(\\) should return 2\\|3\\|6\\|7\\|10\\|12\\|13\\|14 but returns int\\<0, 255\\>\\.$#"
|
message: "#^Method Composer\\\\DependencyResolver\\\\Rule\\:\\:getReason\\(\\) should return 2\\|3\\|6\\|7\\|10\\|12\\|13\\|14 but returns int\\<0, 255\\>\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
path: ../src/Composer/DependencyResolver/Rule.php
|
path: ../src/Composer/DependencyResolver/Rule.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in &&, array\\<int, Composer\\\\Package\\\\BasePackage\\> given on the left side\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Rule.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in &&, array\\<int, Composer\\\\Package\\\\BasePackage\\> given on the right side\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Rule.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in a negated boolean, array\\<Composer\\\\Package\\\\BasePackage\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Rule.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, Composer\\\\Repository\\\\LockArrayRepository\\|null given\\.$#"
|
|
||||||
count: 2
|
|
||||||
path: ../src/Composer/DependencyResolver/Rule.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, array\\<int, Composer\\\\Package\\\\BasePackage\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Rule.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#1 \\$literal of method Composer\\\\DependencyResolver\\\\Pool\\:\\:literalToPackage\\(\\) expects int, int\\|null given\\.$#"
|
|
||||||
count: 2
|
|
||||||
path: ../src/Composer/DependencyResolver/Rule.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#1 \\$packages of static method Composer\\\\DependencyResolver\\\\Problem\\:\\:getPackageList\\(\\) expects array\\<Composer\\\\Package\\\\PackageInterface\\>, array\\<Composer\\\\Package\\\\BasePackage\\|int\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Rule.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in &&, Composer\\\\DependencyResolver\\\\Pool\\|null given on the right side\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/RuleSet.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in &&, Composer\\\\DependencyResolver\\\\Request\\|null given on the right side\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/RuleSet.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in &&, Composer\\\\Repository\\\\RepositorySet\\|null given on the left side\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/RuleSet.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in a negated boolean, Composer\\\\DependencyResolver\\\\Rule\\|null given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/RuleSetGenerator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, array\\<Composer\\\\Package\\\\BasePackage\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/RuleSetGenerator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#3 \\$reasonData of class Composer\\\\DependencyResolver\\\\GenericRule constructor expects array\\{package\\: Composer\\\\Package\\\\BasePackage\\}\\|array\\{packageName\\: string, constraint\\: Composer\\\\Semver\\\\Constraint\\\\ConstraintInterface\\}\\|Composer\\\\Package\\\\BasePackage\\|Composer\\\\Package\\\\Link\\|int\\|string, array\\{package\\: Composer\\\\Package\\\\BasePackage\\}\\|array\\{packageName\\: string, constraint\\: Composer\\\\Semver\\\\Constraint\\\\ConstraintInterface\\}\\|Composer\\\\Package\\\\BasePackage\\|Composer\\\\Package\\\\Link\\|int\\|string\\|null given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/RuleSetGenerator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#4 \\$reasonData of class Composer\\\\DependencyResolver\\\\Rule2Literals constructor expects array\\{package\\: Composer\\\\Package\\\\BasePackage\\}\\|array\\{packageName\\: string, constraint\\: Composer\\\\Semver\\\\Constraint\\\\ConstraintInterface\\}\\|Composer\\\\Package\\\\BasePackage\\|Composer\\\\Package\\\\Link\\|int\\|string, array\\{package\\: Composer\\\\Package\\\\BasePackage\\}\\|array\\{packageName\\: string, constraint\\: Composer\\\\Semver\\\\Constraint\\\\ConstraintInterface\\}\\|Composer\\\\Package\\\\BasePackage\\|Composer\\\\Package\\\\Link\\|int\\|string\\|null given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/RuleSetGenerator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Short ternary operator is not allowed\\. Use null coalesce operator if applicable or consider using long ternary\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/RuleSetGenerator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Return type \\(\\-1\\|0\\|1\\|4\\) of method Composer\\\\DependencyResolver\\\\RuleSetIterator\\:\\:key\\(\\) should be covariant with return type \\(0\\|1\\|4\\) of method Iterator\\<int,Composer\\\\DependencyResolver\\\\Rule\\>\\:\\:key\\(\\)$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/RuleSetIterator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
|
||||||
count: 2
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Foreach overwrites \\$literal with its value variable\\.$#"
|
|
||||||
count: 2
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in &&, Composer\\\\DependencyResolver\\\\Rule\\|null given on the left side\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in &&, int\\<0, max\\> given on the right side\\.$#"
|
|
||||||
count: 2
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in &&, mixed given on the left side\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in a negated boolean, array\\<Composer\\\\Package\\\\BasePackage\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in a negated boolean, int given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, Composer\\\\DependencyResolver\\\\Rule\\|null given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, array\\<Composer\\\\DependencyResolver\\\\Problem\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, int given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, int\\<0, max\\> given\\.$#"
|
|
||||||
count: 2
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, mixed given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#1 \\$literal of method Composer\\\\DependencyResolver\\\\Decisions\\:\\:decide\\(\\) expects int, int\\|string given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#1 \\$literals of class Composer\\\\DependencyResolver\\\\GenericRule constructor expects list\\<int\\>, non\\-empty\\-list\\<int\\|null\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#1 \\$number of function abs expects int, int\\|null given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#1 \\$rule of method Composer\\\\DependencyResolver\\\\Problem\\:\\:addRule\\(\\) expects Composer\\\\DependencyResolver\\\\Rule, Composer\\\\DependencyResolver\\\\Rule\\|null given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#2 \\$literal of method Composer\\\\DependencyResolver\\\\Solver\\:\\:setPropagateLearn\\(\\) expects int\\|string, int\\|null given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#2 \\$presentMap of class Composer\\\\DependencyResolver\\\\LockTransaction constructor expects array\\<string, Composer\\\\Package\\\\BasePackage\\>, array\\<int\\|string, Composer\\\\Package\\\\BasePackage\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Short ternary operator is not allowed\\. Use null coalesce operator if applicable or consider using long ternary\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Solver.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/SolverProblemsException.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in &&, int\\<0, max\\>\\|false given on the left side\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/SolverProblemsException.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in &&, int\\<0, max\\>\\|false given on the right side\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/SolverProblemsException.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, array\\<int, string\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/SolverProblemsException.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in an if condition, int\\<0, max\\>\\|false given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/SolverProblemsException.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in \\|\\|, int\\<0, max\\>\\|false given on the left side\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/SolverProblemsException.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in \\|\\|, int\\<0, max\\>\\|false given on the right side\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/SolverProblemsException.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Transaction.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in &&, array given on the right side\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/DependencyResolver/Transaction.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in a negated boolean, int\\<0, max\\> given\\.$#"
|
|
||||||
count: 2
|
|
||||||
path: ../src/Composer/DependencyResolver/Transaction.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in \\|\\|, int\\<0, max\\> given on the right side\\.$#"
|
|
||||||
count: 2
|
|
||||||
path: ../src/Composer/DependencyResolver/Transaction.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Call to function array_search\\(\\) requires parameter \\#3 to be set\\.$#"
|
message: "#^Call to function array_search\\(\\) requires parameter \\#3 to be set\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
@ -2857,7 +2442,7 @@ parameters:
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Only booleans are allowed in a negated boolean, mixed given\\.$#"
|
message: "#^Only booleans are allowed in a negated boolean, mixed given\\.$#"
|
||||||
count: 2
|
count: 1
|
||||||
path: ../src/Composer/Repository/ComposerRepository.php
|
path: ../src/Composer/Repository/ComposerRepository.php
|
||||||
|
|
||||||
-
|
-
|
||||||
|
|
|
@ -817,7 +817,8 @@ EOT
|
||||||
$pool = $repositorySet->createPoolForPackage($name);
|
$pool = $repositorySet->createPoolForPackage($name);
|
||||||
}
|
}
|
||||||
$matches = $pool->whatProvides($name, $constraint);
|
$matches = $pool->whatProvides($name, $constraint);
|
||||||
foreach ($matches as $index => $package) {
|
$literals = [];
|
||||||
|
foreach ($matches as $package) {
|
||||||
// avoid showing the 9999999-dev alias if the default branch has no branch-alias set
|
// avoid showing the 9999999-dev alias if the default branch has no branch-alias set
|
||||||
if ($package instanceof AliasPackage && $package->getVersion() === VersionParser::DEFAULT_BRANCH_ALIAS) {
|
if ($package instanceof AliasPackage && $package->getVersion() === VersionParser::DEFAULT_BRANCH_ALIAS) {
|
||||||
$package = $package->getAliasOf();
|
$package = $package->getAliasOf();
|
||||||
|
@ -829,11 +830,12 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
$versions[$package->getPrettyVersion()] = $package->getVersion();
|
$versions[$package->getPrettyVersion()] = $package->getVersion();
|
||||||
$matches[$index] = $package->getId();
|
$literals[] = $package->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
// select preferred package according to policy rules
|
// select preferred package according to policy rules
|
||||||
if (null === $matchedPackage && $matches && $preferred = $policy->selectPreferredPackages($pool, $matches)) {
|
if (null === $matchedPackage && \count($literals) > 0) {
|
||||||
|
$preferred = $policy->selectPreferredPackages($pool, $literals);
|
||||||
$matchedPackage = $pool->literalToPackage($preferred[0]);
|
$matchedPackage = $pool->literalToPackage($preferred[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ class Decisions implements \Iterator, \Countable
|
||||||
/** @var array<int, int> */
|
/** @var array<int, int> */
|
||||||
protected $decisionMap;
|
protected $decisionMap;
|
||||||
/**
|
/**
|
||||||
* @var array<array{0: int, 1: Rule}>
|
* @var array<int, array{0: int, 1: Rule}>
|
||||||
*/
|
*/
|
||||||
protected $decisionQueue = [];
|
protected $decisionQueue = [];
|
||||||
|
|
||||||
|
@ -69,12 +69,12 @@ class Decisions implements \Iterator, \Countable
|
||||||
|
|
||||||
public function decided(int $literalOrPackageId): bool
|
public function decided(int $literalOrPackageId): bool
|
||||||
{
|
{
|
||||||
return !empty($this->decisionMap[abs($literalOrPackageId)]);
|
return ($this->decisionMap[abs($literalOrPackageId)] ?? 0) !== 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function undecided(int $literalOrPackageId): bool
|
public function undecided(int $literalOrPackageId): bool
|
||||||
{
|
{
|
||||||
return empty($this->decisionMap[abs($literalOrPackageId)]);
|
return ($this->decisionMap[abs($literalOrPackageId)] ?? 0) === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function decidedInstall(int $literalOrPackageId): bool
|
public function decidedInstall(int $literalOrPackageId): bool
|
||||||
|
@ -94,7 +94,7 @@ class Decisions implements \Iterator, \Countable
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function decisionRule(int $literalOrPackageId): ?Rule
|
public function decisionRule(int $literalOrPackageId): Rule
|
||||||
{
|
{
|
||||||
$packageId = abs($literalOrPackageId);
|
$packageId = abs($literalOrPackageId);
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ class Decisions implements \Iterator, \Countable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
throw new \LogicException('Did not find a decision rule using '.$literalOrPackageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -219,7 +219,7 @@ class Decisions implements \Iterator, \Countable
|
||||||
ksort($decisionMap);
|
ksort($decisionMap);
|
||||||
$str = '[';
|
$str = '[';
|
||||||
foreach ($decisionMap as $packageId => $level) {
|
foreach ($decisionMap as $packageId => $level) {
|
||||||
$str .= (($pool) ? $pool->literalToPackage($packageId) : $packageId).':'.$level.',';
|
$str .= ($pool !== null ? $pool->literalToPackage($packageId) : $packageId).':'.$level.',';
|
||||||
}
|
}
|
||||||
$str .= ']';
|
$str .= ']';
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ class DefaultPolicy implements PolicyInterface
|
||||||
private $preferLowest;
|
private $preferLowest;
|
||||||
/** @var array<string, string>|null */
|
/** @var array<string, string>|null */
|
||||||
private $preferredVersions;
|
private $preferredVersions;
|
||||||
/** @var array<int, array<string, array<int, int>>> */
|
/** @var array<int, array<string, non-empty-list<int>>> */
|
||||||
private $preferredPackageResultCachePerPool;
|
private $preferredPackageResultCachePerPool;
|
||||||
/** @var array<int, array<string, int>> */
|
/** @var array<int, array<string, int>> */
|
||||||
private $sortingCachePerPool;
|
private $sortingCachePerPool;
|
||||||
|
@ -68,9 +68,8 @@ class DefaultPolicy implements PolicyInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int[] $literals
|
* @param non-empty-list<int> $literals
|
||||||
* @param string $requiredPackage
|
* @return non-empty-list<int>
|
||||||
* @return int[]
|
|
||||||
*/
|
*/
|
||||||
public function selectPreferredPackages(Pool $pool, array $literals, ?string $requiredPackage = null): array
|
public function selectPreferredPackages(Pool $pool, array $literals, ?string $requiredPackage = null): array
|
||||||
{
|
{
|
||||||
|
@ -118,8 +117,8 @@ class DefaultPolicy implements PolicyInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int[] $literals
|
* @param non-empty-list<int> $literals
|
||||||
* @return array<string, int[]>
|
* @return non-empty-array<string, non-empty-list<int>>
|
||||||
*/
|
*/
|
||||||
protected function groupLiteralsByName(Pool $pool, array $literals): array
|
protected function groupLiteralsByName(Pool $pool, array $literals): array
|
||||||
{
|
{
|
||||||
|
@ -164,7 +163,7 @@ class DefaultPolicy implements PolicyInterface
|
||||||
|
|
||||||
// for replacers not replacing each other, put a higher prio on replacing
|
// for replacers not replacing each other, put a higher prio on replacing
|
||||||
// packages with the same vendor as the required package
|
// packages with the same vendor as the required package
|
||||||
if ($requiredPackage && false !== ($pos = strpos($requiredPackage, '/'))) {
|
if ($requiredPackage !== null && false !== ($pos = strpos($requiredPackage, '/'))) {
|
||||||
$requiredVendor = substr($requiredPackage, 0, $pos);
|
$requiredVendor = substr($requiredPackage, 0, $pos);
|
||||||
|
|
||||||
$aIsSameVendor = strpos($a->getName(), $requiredVendor) === 0;
|
$aIsSameVendor = strpos($a->getName(), $requiredVendor) === 0;
|
||||||
|
@ -205,8 +204,8 @@ class DefaultPolicy implements PolicyInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int[] $literals
|
* @param list<int> $literals
|
||||||
* @return int[]
|
* @return list<int>
|
||||||
*/
|
*/
|
||||||
protected function pruneToBestVersion(Pool $pool, array $literals): array
|
protected function pruneToBestVersion(Pool $pool, array $literals): array
|
||||||
{
|
{
|
||||||
|
@ -252,8 +251,8 @@ class DefaultPolicy implements PolicyInterface
|
||||||
*
|
*
|
||||||
* If no package is a local alias, nothing happens
|
* If no package is a local alias, nothing happens
|
||||||
*
|
*
|
||||||
* @param int[] $literals
|
* @param list<int> $literals
|
||||||
* @return int[]
|
* @return list<int>
|
||||||
*/
|
*/
|
||||||
protected function pruneRemoteAliases(Pool $pool, array $literals): array
|
protected function pruneRemoteAliases(Pool $pool, array $literals): array
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,6 +47,9 @@ class GenericRule extends Rule
|
||||||
public function getHash()
|
public function getHash()
|
||||||
{
|
{
|
||||||
$data = unpack('ihash', (string) hash(\PHP_VERSION_ID > 80100 ? 'xxh3' : 'sha1', implode(',', $this->literals), true));
|
$data = unpack('ihash', (string) hash(\PHP_VERSION_ID > 80100 ? 'xxh3' : 'sha1', implode(',', $this->literals), true));
|
||||||
|
if (false === $data) {
|
||||||
|
throw new \RuntimeException('Failed unpacking: '.implode(', ', $this->literals));
|
||||||
|
}
|
||||||
|
|
||||||
return $data['hash'];
|
return $data['hash'];
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,11 @@ namespace Composer\DependencyResolver;
|
||||||
*/
|
*/
|
||||||
class MultiConflictRule extends Rule
|
class MultiConflictRule extends Rule
|
||||||
{
|
{
|
||||||
/** @var list<int> */
|
/** @var non-empty-list<int> */
|
||||||
protected $literals;
|
protected $literals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param list<int> $literals
|
* @param non-empty-list<int> $literals
|
||||||
*/
|
*/
|
||||||
public function __construct(array $literals, $reason, $reasonData)
|
public function __construct(array $literals, $reason, $reasonData)
|
||||||
{
|
{
|
||||||
|
@ -40,7 +40,7 @@ class MultiConflictRule extends Rule
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return list<int>
|
* @return non-empty-list<int>
|
||||||
*/
|
*/
|
||||||
public function getLiterals(): array
|
public function getLiterals(): array
|
||||||
{
|
{
|
||||||
|
@ -53,6 +53,9 @@ class MultiConflictRule extends Rule
|
||||||
public function getHash()
|
public function getHash()
|
||||||
{
|
{
|
||||||
$data = unpack('ihash', (string) hash(\PHP_VERSION_ID > 80100 ? 'xxh3' : 'sha1', 'c:'.implode(',', $this->literals), true));
|
$data = unpack('ihash', (string) hash(\PHP_VERSION_ID > 80100 ? 'xxh3' : 'sha1', 'c:'.implode(',', $this->literals), true));
|
||||||
|
if (false === $data) {
|
||||||
|
throw new \RuntimeException('Failed unpacking: '.implode(', ', $this->literals));
|
||||||
|
}
|
||||||
|
|
||||||
return $data['hash'];
|
return $data['hash'];
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,8 @@ interface PolicyInterface
|
||||||
public function versionCompare(PackageInterface $a, PackageInterface $b, string $operator): bool;
|
public function versionCompare(PackageInterface $a, PackageInterface $b, string $operator): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int[] $literals
|
* @param non-empty-list<int> $literals
|
||||||
* @return int[]
|
* @return non-empty-list<int>
|
||||||
*/
|
*/
|
||||||
public function selectPreferredPackages(Pool $pool, array $literals, ?string $requiredPackage = null): array;
|
public function selectPreferredPackages(Pool $pool, array $literals, ?string $requiredPackage = null): array;
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ class PoolBuilder
|
||||||
*/
|
*/
|
||||||
private $loadedPerRepo = [];
|
private $loadedPerRepo = [];
|
||||||
/**
|
/**
|
||||||
* @var BasePackage[]
|
* @var array<int, BasePackage>
|
||||||
*/
|
*/
|
||||||
private $packages = [];
|
private $packages = [];
|
||||||
/**
|
/**
|
||||||
|
@ -201,10 +201,14 @@ class PoolBuilder
|
||||||
{
|
{
|
||||||
$this->restrictedPackagesList = $request->getRestrictedPackages() !== null ? array_flip($request->getRestrictedPackages()) : null;
|
$this->restrictedPackagesList = $request->getRestrictedPackages() !== null ? array_flip($request->getRestrictedPackages()) : null;
|
||||||
|
|
||||||
if ($request->getUpdateAllowList()) {
|
if (\count($request->getUpdateAllowList()) > 0) {
|
||||||
$this->updateAllowList = $request->getUpdateAllowList();
|
$this->updateAllowList = $request->getUpdateAllowList();
|
||||||
$this->warnAboutNonMatchingUpdateAllowList($request);
|
$this->warnAboutNonMatchingUpdateAllowList($request);
|
||||||
|
|
||||||
|
if (null === $request->getLockedRepository()) {
|
||||||
|
throw new \LogicException('No lock repo present and yet a partial update was requested.');
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($request->getLockedRepository()->getPackages() as $lockedPackage) {
|
foreach ($request->getLockedRepository()->getPackages() as $lockedPackage) {
|
||||||
if (!$this->isUpdateAllowed($lockedPackage)) {
|
if (!$this->isUpdateAllowed($lockedPackage)) {
|
||||||
// remember which packages we skipped loading remote content for in this partial update
|
// remember which packages we skipped loading remote content for in this partial update
|
||||||
|
@ -271,7 +275,7 @@ class PoolBuilder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!empty($this->packagesToLoad)) {
|
while (\count($this->packagesToLoad) > 0) {
|
||||||
$this->loadPackagesMarkedForLoading($request, $repositories);
|
$this->loadPackagesMarkedForLoading($request, $repositories);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +307,7 @@ class PoolBuilder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->eventDispatcher) {
|
if ($this->eventDispatcher !== null) {
|
||||||
$prePoolCreateEvent = new PrePoolCreateEvent(
|
$prePoolCreateEvent = new PrePoolCreateEvent(
|
||||||
PluginEvents::PRE_POOL_CREATE,
|
PluginEvents::PRE_POOL_CREATE,
|
||||||
$repositories,
|
$repositories,
|
||||||
|
@ -413,7 +417,7 @@ class PoolBuilder
|
||||||
$this->packagesToLoad = [];
|
$this->packagesToLoad = [];
|
||||||
|
|
||||||
foreach ($repositories as $repoIndex => $repository) {
|
foreach ($repositories as $repoIndex => $repository) {
|
||||||
if (empty($packageBatch)) {
|
if (0 === \count($packageBatch)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,7 +503,7 @@ class PoolBuilder
|
||||||
if ($propagateUpdate && $request->getUpdateAllowTransitiveDependencies()) {
|
if ($propagateUpdate && $request->getUpdateAllowTransitiveDependencies()) {
|
||||||
$skippedRootRequires = $this->getSkippedRootRequires($request, $require);
|
$skippedRootRequires = $this->getSkippedRootRequires($request, $require);
|
||||||
|
|
||||||
if ($request->getUpdateAllowTransitiveRootDependencies() || !$skippedRootRequires) {
|
if ($request->getUpdateAllowTransitiveRootDependencies() || 0 === \count($skippedRootRequires)) {
|
||||||
$this->unlockPackage($request, $repositories, $require);
|
$this->unlockPackage($request, $repositories, $require);
|
||||||
$this->markPackageNameForLoading($request, $require, $linkConstraint);
|
$this->markPackageNameForLoading($request, $require, $linkConstraint);
|
||||||
} else {
|
} else {
|
||||||
|
@ -528,7 +532,7 @@ class PoolBuilder
|
||||||
if (isset($this->loadedPackages[$replace], $this->skippedLoad[$replace])) {
|
if (isset($this->loadedPackages[$replace], $this->skippedLoad[$replace])) {
|
||||||
$skippedRootRequires = $this->getSkippedRootRequires($request, $replace);
|
$skippedRootRequires = $this->getSkippedRootRequires($request, $replace);
|
||||||
|
|
||||||
if ($request->getUpdateAllowTransitiveRootDependencies() || !$skippedRootRequires) {
|
if ($request->getUpdateAllowTransitiveRootDependencies() || 0 === \count($skippedRootRequires)) {
|
||||||
$this->unlockPackage($request, $repositories, $replace);
|
$this->unlockPackage($request, $repositories, $replace);
|
||||||
// the replaced package only needs to be loaded if something else requires it
|
// the replaced package only needs to be loaded if something else requires it
|
||||||
$this->markPackageNameForLoadingIfRequired($request, $replace);
|
$this->markPackageNameForLoadingIfRequired($request, $replace);
|
||||||
|
@ -615,6 +619,10 @@ class PoolBuilder
|
||||||
|
|
||||||
private function warnAboutNonMatchingUpdateAllowList(Request $request): void
|
private function warnAboutNonMatchingUpdateAllowList(Request $request): void
|
||||||
{
|
{
|
||||||
|
if (null === $request->getLockedRepository()) {
|
||||||
|
throw new \LogicException('No lock repo present and yet a partial update was requested.');
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($this->updateAllowList as $pattern) {
|
foreach ($this->updateAllowList as $pattern) {
|
||||||
$matchedPlatformPackage = false;
|
$matchedPlatformPackage = false;
|
||||||
|
|
||||||
|
|
|
@ -207,7 +207,7 @@ class PoolOptimizer
|
||||||
$groupHashParts[] = 'require:' . (string) $requireConstraint;
|
$groupHashParts[] = 'require:' . (string) $requireConstraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($package->getReplaces()) {
|
if (\count($package->getReplaces()) > 0) {
|
||||||
foreach ($package->getReplaces() as $link) {
|
foreach ($package->getReplaces() as $link) {
|
||||||
if (CompilingMatcher::match($link->getConstraint(), Constraint::OP_EQ, $package->getVersion())) {
|
if (CompilingMatcher::match($link->getConstraint(), Constraint::OP_EQ, $package->getVersion())) {
|
||||||
// Use the same hash part as the regular require hash because that's what the replacement does
|
// Use the same hash part as the regular require hash because that's what the replacement does
|
||||||
|
@ -224,7 +224,7 @@ class PoolOptimizer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$groupHashParts) {
|
if (0 === \count($groupHashParts)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,7 +371,7 @@ class PoolOptimizer
|
||||||
*/
|
*/
|
||||||
private function optimizeImpossiblePackagesAway(Request $request, Pool $pool): void
|
private function optimizeImpossiblePackagesAway(Request $request, Pool $pool): void
|
||||||
{
|
{
|
||||||
if (count($request->getLockedPackages()) === 0) {
|
if (\count($request->getLockedPackages()) === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ class Problem
|
||||||
// TODO doesn't this entirely defeat the purpose of the problem sections? what's the point of sections?
|
// TODO doesn't this entirely defeat the purpose of the problem sections? what's the point of sections?
|
||||||
$reasons = array_merge(...array_reverse($this->reasons));
|
$reasons = array_merge(...array_reverse($this->reasons));
|
||||||
|
|
||||||
if (count($reasons) === 1) {
|
if (\count($reasons) === 1) {
|
||||||
reset($reasons);
|
reset($reasons);
|
||||||
$rule = current($reasons);
|
$rule = current($reasons);
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ class Problem
|
||||||
$constraint = $reasonData['constraint'];
|
$constraint = $reasonData['constraint'];
|
||||||
|
|
||||||
$packages = $pool->whatProvides($packageName, $constraint);
|
$packages = $pool->whatProvides($packageName, $constraint);
|
||||||
if (count($packages) === 0) {
|
if (\count($packages) === 0) {
|
||||||
return "\n ".implode(self::getMissingPackageReason($repositorySet, $request, $pool, $isVerbose, $packageName, $constraint));
|
return "\n ".implode(self::getMissingPackageReason($repositorySet, $request, $pool, $isVerbose, $packageName, $constraint));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ class Problem
|
||||||
if (!$isVerbose) {
|
if (!$isVerbose) {
|
||||||
$versions = self::condenseVersionList($versions, 1);
|
$versions = self::condenseVersionList($versions, 1);
|
||||||
}
|
}
|
||||||
if (count($versions) > 1) {
|
if (\count($versions) > 1) {
|
||||||
// remove the s from requires/conflicts to correct grammar
|
// remove the s from requires/conflicts to correct grammar
|
||||||
$message = Preg::replace('{^(%s%s (?:require|conflict))s}', '$1', $message);
|
$message = Preg::replace('{^(%s%s (?:require|conflict))s}', '$1', $message);
|
||||||
$result[] = sprintf($message, $package, '['.implode(', ', $versions).']');
|
$result[] = sprintf($message, $package, '['.implode(', ', $versions).']');
|
||||||
|
@ -276,7 +276,7 @@ class Problem
|
||||||
$ext = substr($packageName, 4);
|
$ext = substr($packageName, 4);
|
||||||
$msg = "- Root composer.json requires PHP extension ".$packageName.self::constraintToText($constraint).' but ';
|
$msg = "- Root composer.json requires PHP extension ".$packageName.self::constraintToText($constraint).' but ';
|
||||||
|
|
||||||
$version = self::getPlatformPackageVersion($pool, $packageName, phpversion($ext) ?: '0');
|
$version = self::getPlatformPackageVersion($pool, $packageName, phpversion($ext) === false ? '0' : phpversion($ext));
|
||||||
if (null === $version) {
|
if (null === $version) {
|
||||||
$providersStr = self::getProvidersList($repositorySet, $packageName, 5);
|
$providersStr = self::getProvidersList($repositorySet, $packageName, 5);
|
||||||
if ($providersStr !== null) {
|
if ($providersStr !== null) {
|
||||||
|
@ -337,7 +337,8 @@ class Problem
|
||||||
|
|
||||||
// first check if the actual requested package is found in normal conditions
|
// first check if the actual requested package is found in normal conditions
|
||||||
// if so it must mean it is rejected by another constraint than the one given here
|
// if so it must mean it is rejected by another constraint than the one given here
|
||||||
if ($packages = $repositorySet->findPackages($packageName, $constraint)) {
|
$packages = $repositorySet->findPackages($packageName, $constraint);
|
||||||
|
if (\count($packages) > 0) {
|
||||||
$rootReqs = $repositorySet->getRootRequires();
|
$rootReqs = $repositorySet->getRootRequires();
|
||||||
if (isset($rootReqs[$packageName])) {
|
if (isset($rootReqs[$packageName])) {
|
||||||
$filtered = array_filter($packages, static function ($p) use ($rootReqs, $packageName): bool {
|
$filtered = array_filter($packages, static function ($p) use ($rootReqs, $packageName): bool {
|
||||||
|
@ -358,7 +359,7 @@ class Problem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($lockedPackage) {
|
if ($lockedPackage !== null) {
|
||||||
$fixedConstraint = new Constraint('==', $lockedPackage->getVersion());
|
$fixedConstraint = new Constraint('==', $lockedPackage->getVersion());
|
||||||
$filtered = array_filter($packages, static function ($p) use ($fixedConstraint): bool {
|
$filtered = array_filter($packages, static function ($p) use ($fixedConstraint): bool {
|
||||||
return $fixedConstraint->matches(new Constraint('==', $p->getVersion()));
|
return $fixedConstraint->matches(new Constraint('==', $p->getVersion()));
|
||||||
|
@ -372,7 +373,7 @@ class Problem
|
||||||
return !$p->getRepository() instanceof LockArrayRepository;
|
return !$p->getRepository() instanceof LockArrayRepository;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!$nonLockedPackages) {
|
if (0 === \count($nonLockedPackages)) {
|
||||||
return ["- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' in the lock file but not in remote repositories, make sure you avoid updating this package to keep the one from the lock file.'];
|
return ["- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' in the lock file but not in remote repositories, make sure you avoid updating this package to keep the one from the lock file.'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,9 +381,11 @@ class Problem
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the package is found when bypassing stability checks
|
// check if the package is found when bypassing stability checks
|
||||||
if ($packages = $repositorySet->findPackages($packageName, $constraint, RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES)) {
|
$packages = $repositorySet->findPackages($packageName, $constraint, RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES);
|
||||||
|
if (\count($packages) > 0) {
|
||||||
// we must first verify if a valid package would be found in a lower priority repository
|
// we must first verify if a valid package would be found in a lower priority repository
|
||||||
if ($allReposPackages = $repositorySet->findPackages($packageName, $constraint, RepositorySet::ALLOW_SHADOWED_REPOSITORIES)) {
|
$allReposPackages = $repositorySet->findPackages($packageName, $constraint, RepositorySet::ALLOW_SHADOWED_REPOSITORIES);
|
||||||
|
if (\count($allReposPackages) > 0) {
|
||||||
return self::computeCheckForLowerPrioRepo($pool, $isVerbose, $packageName, $packages, $allReposPackages, 'minimum-stability', $constraint);
|
return self::computeCheckForLowerPrioRepo($pool, $isVerbose, $packageName, $packages, $allReposPackages, 'minimum-stability', $constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,9 +393,11 @@ class Problem
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the package is found when bypassing the constraint and stability checks
|
// check if the package is found when bypassing the constraint and stability checks
|
||||||
if ($packages = $repositorySet->findPackages($packageName, null, RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES)) {
|
$packages = $repositorySet->findPackages($packageName, null, RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES);
|
||||||
|
if (\count($packages) > 0) {
|
||||||
// we must first verify if a valid package would be found in a lower priority repository
|
// we must first verify if a valid package would be found in a lower priority repository
|
||||||
if ($allReposPackages = $repositorySet->findPackages($packageName, $constraint, RepositorySet::ALLOW_SHADOWED_REPOSITORIES)) {
|
$allReposPackages = $repositorySet->findPackages($packageName, $constraint, RepositorySet::ALLOW_SHADOWED_REPOSITORIES);
|
||||||
|
if (\count($allReposPackages) > 0) {
|
||||||
return self::computeCheckForLowerPrioRepo($pool, $isVerbose, $packageName, $packages, $allReposPackages, 'constraint', $constraint);
|
return self::computeCheckForLowerPrioRepo($pool, $isVerbose, $packageName, $packages, $allReposPackages, 'constraint', $constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,12 +446,12 @@ class Problem
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
$prepared[$package->getName()]['name'] = $package->getPrettyName();
|
$prepared[$package->getName()]['name'] = $package->getPrettyName();
|
||||||
$prepared[$package->getName()]['versions'][$package->getVersion()] = $package->getPrettyVersion().($package instanceof AliasPackage ? ' (alias of '.$package->getAliasOf()->getPrettyVersion().')' : '');
|
$prepared[$package->getName()]['versions'][$package->getVersion()] = $package->getPrettyVersion().($package instanceof AliasPackage ? ' (alias of '.$package->getAliasOf()->getPrettyVersion().')' : '');
|
||||||
if ($pool && $constraint) {
|
if ($pool !== null && $constraint !== null) {
|
||||||
foreach ($pool->getRemovedVersions($package->getName(), $constraint) as $version => $prettyVersion) {
|
foreach ($pool->getRemovedVersions($package->getName(), $constraint) as $version => $prettyVersion) {
|
||||||
$prepared[$package->getName()]['versions'][$version] = $prettyVersion;
|
$prepared[$package->getName()]['versions'][$version] = $prettyVersion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($pool && $useRemovedVersionGroup) {
|
if ($pool !== null && $useRemovedVersionGroup) {
|
||||||
foreach ($pool->getRemovedVersionsByPackage(spl_object_hash($package)) as $version => $prettyVersion) {
|
foreach ($pool->getRemovedVersionsByPackage(spl_object_hash($package)) as $version => $prettyVersion) {
|
||||||
$prepared[$package->getName()]['versions'][$version] = $prettyVersion;
|
$prepared[$package->getName()]['versions'][$version] = $prettyVersion;
|
||||||
}
|
}
|
||||||
|
@ -482,7 +487,7 @@ class Problem
|
||||||
{
|
{
|
||||||
$available = $pool->whatProvides($packageName);
|
$available = $pool->whatProvides($packageName);
|
||||||
|
|
||||||
if (count($available)) {
|
if (\count($available) > 0) {
|
||||||
$selected = null;
|
$selected = null;
|
||||||
foreach ($available as $pkg) {
|
foreach ($available as $pkg) {
|
||||||
if ($pkg->getRepository() instanceof PlatformRepository) {
|
if ($pkg->getRepository() instanceof PlatformRepository) {
|
||||||
|
@ -507,7 +512,7 @@ class Problem
|
||||||
$version = $selected->getPrettyVersion();
|
$version = $selected->getPrettyVersion();
|
||||||
$extra = $selected->getExtra();
|
$extra = $selected->getExtra();
|
||||||
if ($selected instanceof CompletePackageInterface && isset($extra['config.platform']) && $extra['config.platform'] === true) {
|
if ($selected instanceof CompletePackageInterface && isset($extra['config.platform']) && $extra['config.platform'] === true) {
|
||||||
$version .= '; ' . str_replace('Package ', '', $selected->getDescription());
|
$version .= '; ' . str_replace('Package ', '', (string) $selected->getDescription());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
@ -568,8 +573,8 @@ class Problem
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param PackageInterface[] $higherRepoPackages
|
* @param non-empty-array<PackageInterface> $higherRepoPackages
|
||||||
* @param PackageInterface[] $allReposPackages
|
* @param non-empty-array<PackageInterface> $allReposPackages
|
||||||
* @return array{0: string, 1: string}
|
* @return array{0: string, 1: string}
|
||||||
*/
|
*/
|
||||||
private static function computeCheckForLowerPrioRepo(Pool $pool, bool $isVerbose, string $packageName, array $higherRepoPackages, array $allReposPackages, string $reason, ?ConstraintInterface $constraint = null): array
|
private static function computeCheckForLowerPrioRepo(Pool $pool, bool $isVerbose, string $packageName, array $higherRepoPackages, array $allReposPackages, string $reason, ?ConstraintInterface $constraint = null): array
|
||||||
|
@ -586,7 +591,9 @@ class Problem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($higherRepoPackages) {
|
assert(null !== $nextRepo);
|
||||||
|
|
||||||
|
if (\count($higherRepoPackages) > 0) {
|
||||||
$topPackage = reset($higherRepoPackages);
|
$topPackage = reset($higherRepoPackages);
|
||||||
if ($topPackage instanceof RootPackageInterface) {
|
if ($topPackage instanceof RootPackageInterface) {
|
||||||
return [
|
return [
|
||||||
|
@ -634,7 +641,7 @@ class Problem
|
||||||
return ' ' . $constraint->getPrettyString() . ' (exact version match: ' . (count($versions) > 1 ? implode(', ', array_slice($versions, 0, -1)) . ' or ' . end($versions) : $versions[0]) . ')';
|
return ' ' . $constraint->getPrettyString() . ' (exact version match: ' . (count($versions) > 1 ? implode(', ', array_slice($versions, 0, -1)) . ' or ' . end($versions) : $versions[0]) . ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $constraint ? ' '.$constraint->getPrettyString() : '';
|
return $constraint !== null ? ' '.$constraint->getPrettyString() : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function getProvidersList(RepositorySet $repositorySet, string $packageName, int $maxProviders): ?string
|
private static function getProvidersList(RepositorySet $repositorySet, string $packageName, int $maxProviders): ?string
|
||||||
|
@ -642,7 +649,7 @@ class Problem
|
||||||
$providers = $repositorySet->getProviders($packageName);
|
$providers = $repositorySet->getProviders($packageName);
|
||||||
if (\count($providers) > 0) {
|
if (\count($providers) > 0) {
|
||||||
$providersStr = implode(array_map(static function ($p): string {
|
$providersStr = implode(array_map(static function ($p): string {
|
||||||
$description = $p['description'] ? ' '.substr($p['description'], 0, 100) : '';
|
$description = $p['description'] !== '' ? ' '.substr($p['description'], 0, 100) : '';
|
||||||
|
|
||||||
return ' - '.$p['name'].$description."\n";
|
return ' - '.$p['name'].$description."\n";
|
||||||
}, count($providers) > $maxProviders + 1 ? array_slice($providers, 0, $maxProviders) : $providers));
|
}, count($providers) > $maxProviders + 1 ? array_slice($providers, 0, $maxProviders) : $providers));
|
||||||
|
|
|
@ -190,7 +190,7 @@ class Request
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<int|string, BasePackage>
|
* @return ($packageIds is true ? array<int, BasePackage> : array<string, BasePackage>)
|
||||||
*
|
*
|
||||||
* @TODO look into removing the packageIds option, the only place true is used
|
* @TODO look into removing the packageIds option, the only place true is used
|
||||||
* is for the installed map in the solver problems.
|
* is for the installed map in the solver problems.
|
||||||
|
@ -201,7 +201,7 @@ class Request
|
||||||
{
|
{
|
||||||
$presentMap = [];
|
$presentMap = [];
|
||||||
|
|
||||||
if ($this->lockedRepository) {
|
if ($this->lockedRepository !== null) {
|
||||||
foreach ($this->lockedRepository->getPackages() as $package) {
|
foreach ($this->lockedRepository->getPackages() as $package) {
|
||||||
$presentMap[$packageIds ? $package->getId() : spl_object_hash($package)] = $package;
|
$presentMap[$packageIds ? $package->getId() : spl_object_hash($package)] = $package;
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@ class Request
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BasePackage[]
|
* @return array<int, BasePackage>
|
||||||
*/
|
*/
|
||||||
public function getFixedPackagesMap(): array
|
public function getFixedPackagesMap(): array
|
||||||
{
|
{
|
||||||
|
|
|
@ -153,7 +153,7 @@ abstract class Rule
|
||||||
if (PlatformRepository::isPlatformPackage($this->getReasonData()->getTarget())) {
|
if (PlatformRepository::isPlatformPackage($this->getReasonData()->getTarget())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ($request->getLockedRepository()) {
|
if ($request->getLockedRepository() !== null) {
|
||||||
foreach ($request->getLockedRepository()->getPackages() as $package) {
|
foreach ($request->getLockedRepository()->getPackages() as $package) {
|
||||||
if ($package->getName() === $this->getReasonData()->getTarget()) {
|
if ($package->getName() === $this->getReasonData()->getTarget()) {
|
||||||
if ($pool->isUnacceptableFixedOrLockedPackage($package)) {
|
if ($pool->isUnacceptableFixedOrLockedPackage($package)) {
|
||||||
|
@ -176,7 +176,7 @@ abstract class Rule
|
||||||
if (PlatformRepository::isPlatformPackage($this->getReasonData()['packageName'])) {
|
if (PlatformRepository::isPlatformPackage($this->getReasonData()['packageName'])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ($request->getLockedRepository()) {
|
if ($request->getLockedRepository() !== null) {
|
||||||
foreach ($request->getLockedRepository()->getPackages() as $package) {
|
foreach ($request->getLockedRepository()->getPackages() as $package) {
|
||||||
if ($package->getName() === $this->getReasonData()['packageName']) {
|
if ($package->getName() === $this->getReasonData()['packageName']) {
|
||||||
if ($pool->isUnacceptableFixedOrLockedPackage($package)) {
|
if ($pool->isUnacceptableFixedOrLockedPackage($package)) {
|
||||||
|
@ -215,7 +215,7 @@ abstract class Rule
|
||||||
return $package2;
|
return $package2;
|
||||||
|
|
||||||
case self::RULE_PACKAGE_REQUIRES:
|
case self::RULE_PACKAGE_REQUIRES:
|
||||||
$sourceLiteral = array_shift($literals);
|
$sourceLiteral = $literals[0];
|
||||||
$sourcePackage = $this->deduplicateDefaultBranchAlias($pool->literalToPackage($sourceLiteral));
|
$sourcePackage = $this->deduplicateDefaultBranchAlias($pool->literalToPackage($sourceLiteral));
|
||||||
|
|
||||||
return $sourcePackage;
|
return $sourcePackage;
|
||||||
|
@ -240,14 +240,14 @@ abstract class Rule
|
||||||
$constraint = $reasonData['constraint'];
|
$constraint = $reasonData['constraint'];
|
||||||
|
|
||||||
$packages = $pool->whatProvides($packageName, $constraint);
|
$packages = $pool->whatProvides($packageName, $constraint);
|
||||||
if (!$packages) {
|
if (0 === \count($packages)) {
|
||||||
return 'No package found to satisfy root composer.json require '.$packageName.' '.$constraint->getPrettyString();
|
return 'No package found to satisfy root composer.json require '.$packageName.' '.$constraint->getPrettyString();
|
||||||
}
|
}
|
||||||
|
|
||||||
$packagesNonAlias = array_values(array_filter($packages, static function ($p): bool {
|
$packagesNonAlias = array_values(array_filter($packages, static function ($p): bool {
|
||||||
return !($p instanceof AliasPackage);
|
return !($p instanceof AliasPackage);
|
||||||
}));
|
}));
|
||||||
if (count($packagesNonAlias) === 1) {
|
if (\count($packagesNonAlias) === 1) {
|
||||||
$package = $packagesNonAlias[0];
|
$package = $packagesNonAlias[0];
|
||||||
if ($request->isLockedPackage($package)) {
|
if ($request->isLockedPackage($package)) {
|
||||||
return $package->getPrettyName().' is locked to version '.$package->getPrettyVersion()." and an update of this package was not requested.";
|
return $package->getPrettyName().' is locked to version '.$package->getPrettyVersion()." and an update of this package was not requested.";
|
||||||
|
@ -305,6 +305,7 @@ abstract class Rule
|
||||||
return $package2->getPrettyString().' conflicts with '.$conflictTarget.'.';
|
return $package2->getPrettyString().' conflicts with '.$conflictTarget.'.';
|
||||||
|
|
||||||
case self::RULE_PACKAGE_REQUIRES:
|
case self::RULE_PACKAGE_REQUIRES:
|
||||||
|
assert(\count($literals) > 0);
|
||||||
$sourceLiteral = array_shift($literals);
|
$sourceLiteral = array_shift($literals);
|
||||||
$sourcePackage = $this->deduplicateDefaultBranchAlias($pool->literalToPackage($sourceLiteral));
|
$sourcePackage = $this->deduplicateDefaultBranchAlias($pool->literalToPackage($sourceLiteral));
|
||||||
$reasonData = $this->getReasonData();
|
$reasonData = $this->getReasonData();
|
||||||
|
@ -315,7 +316,7 @@ abstract class Rule
|
||||||
}
|
}
|
||||||
|
|
||||||
$text = $reasonData->getPrettyString($sourcePackage);
|
$text = $reasonData->getPrettyString($sourcePackage);
|
||||||
if ($requires) {
|
if (\count($requires) > 0) {
|
||||||
$text .= ' -> satisfiable by ' . $this->formatPackagesUnique($pool, $requires, $isVerbose, $reasonData->getConstraint()) . '.';
|
$text .= ' -> satisfiable by ' . $this->formatPackagesUnique($pool, $requires, $isVerbose, $reasonData->getConstraint()) . '.';
|
||||||
} else {
|
} else {
|
||||||
$targetName = $reasonData->getTarget();
|
$targetName = $reasonData->getTarget();
|
||||||
|
@ -333,19 +334,18 @@ abstract class Rule
|
||||||
$package = $pool->literalToPackage($literal);
|
$package = $pool->literalToPackage($literal);
|
||||||
$packageNames[$package->getName()] = true;
|
$packageNames[$package->getName()] = true;
|
||||||
}
|
}
|
||||||
|
unset($literal);
|
||||||
$replacedName = $this->getReasonData();
|
$replacedName = $this->getReasonData();
|
||||||
|
|
||||||
if (count($packageNames) > 1) {
|
if (\count($packageNames) > 1) {
|
||||||
$reason = null;
|
|
||||||
|
|
||||||
if (!isset($packageNames[$replacedName])) {
|
if (!isset($packageNames[$replacedName])) {
|
||||||
$reason = 'They '.(count($literals) === 2 ? 'both' : 'all').' replace '.$replacedName.' and thus cannot coexist.';
|
$reason = 'They '.(\count($literals) === 2 ? 'both' : 'all').' replace '.$replacedName.' and thus cannot coexist.';
|
||||||
} else {
|
} else {
|
||||||
$replacerNames = $packageNames;
|
$replacerNames = $packageNames;
|
||||||
unset($replacerNames[$replacedName]);
|
unset($replacerNames[$replacedName]);
|
||||||
$replacerNames = array_keys($replacerNames);
|
$replacerNames = array_keys($replacerNames);
|
||||||
|
|
||||||
if (count($replacerNames) === 1) {
|
if (\count($replacerNames) === 1) {
|
||||||
$reason = $replacerNames[0] . ' replaces ';
|
$reason = $replacerNames[0] . ' replaces ';
|
||||||
} else {
|
} else {
|
||||||
$reason = '['.implode(', ', $replacerNames).'] replace ';
|
$reason = '['.implode(', ', $replacerNames).'] replace ';
|
||||||
|
@ -363,7 +363,7 @@ abstract class Rule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($installedPackages && $removablePackages) {
|
if (\count($installedPackages) > 0 && \count($removablePackages) > 0) {
|
||||||
return $this->formatPackagesUnique($pool, $removablePackages, $isVerbose, null, true).' cannot be installed as that would require removing '.$this->formatPackagesUnique($pool, $installedPackages, $isVerbose, null, true).'. '.$reason;
|
return $this->formatPackagesUnique($pool, $removablePackages, $isVerbose, null, true).' cannot be installed as that would require removing '.$this->formatPackagesUnique($pool, $installedPackages, $isVerbose, null, true).'. '.$reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,7 +381,7 @@ abstract class Rule
|
||||||
// }
|
// }
|
||||||
$learnedString = ' (conflict analysis result)';
|
$learnedString = ' (conflict analysis result)';
|
||||||
|
|
||||||
if (count($literals) === 1) {
|
if (\count($literals) === 1) {
|
||||||
$ruleText = $pool->literalToPrettyString($literals[0], $installedMap);
|
$ruleText = $pool->literalToPrettyString($literals[0], $installedMap);
|
||||||
} else {
|
} else {
|
||||||
$groups = [];
|
$groups = [];
|
||||||
|
@ -397,7 +397,7 @@ abstract class Rule
|
||||||
}
|
}
|
||||||
$ruleTexts = [];
|
$ruleTexts = [];
|
||||||
foreach ($groups as $group => $packages) {
|
foreach ($groups as $group => $packages) {
|
||||||
$ruleTexts[] = $group . (count($packages) > 1 ? ' one of' : '').' ' . $this->formatPackagesUnique($pool, $packages, $isVerbose);
|
$ruleTexts[] = $group . (\count($packages) > 1 ? ' one of' : '').' ' . $this->formatPackagesUnique($pool, $packages, $isVerbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
$ruleText = implode(' | ', $ruleTexts);
|
$ruleText = implode(' | ', $ruleTexts);
|
||||||
|
@ -439,14 +439,13 @@ abstract class Rule
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<int|BasePackage> $packages An array containing packages or literals
|
* @param array<int|BasePackage> $literalsOrPackages An array containing packages or literals
|
||||||
*/
|
*/
|
||||||
protected function formatPackagesUnique(Pool $pool, array $packages, bool $isVerbose, ?ConstraintInterface $constraint = null, bool $useRemovedVersionGroup = false): string
|
protected function formatPackagesUnique(Pool $pool, array $literalsOrPackages, bool $isVerbose, ?ConstraintInterface $constraint = null, bool $useRemovedVersionGroup = false): string
|
||||||
{
|
{
|
||||||
foreach ($packages as $index => $package) {
|
$packages = [];
|
||||||
if (!\is_object($package)) {
|
foreach ($literalsOrPackages as $package) {
|
||||||
$packages[$index] = $pool->literalToPackage($package);
|
$packages[] = \is_object($package) ? $package : $pool->literalToPackage($package);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Problem::getPackageList($packages, $isVerbose, $pool, $constraint, $useRemovedVersionGroup);
|
return Problem::getPackageList($packages, $isVerbose, $pool, $constraint, $useRemovedVersionGroup);
|
||||||
|
|
|
@ -43,7 +43,7 @@ class Rule2Literals extends Rule
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return list<int>
|
* @return non-empty-list<int>
|
||||||
*/
|
*/
|
||||||
public function getLiterals(): array
|
public function getLiterals(): array
|
||||||
{
|
{
|
||||||
|
|
|
@ -179,7 +179,7 @@ class RuleSet implements \IteratorAggregate, \Countable
|
||||||
foreach ($this->rules as $type => $rules) {
|
foreach ($this->rules as $type => $rules) {
|
||||||
$string .= str_pad(self::TYPES[$type], 8, ' ') . ": ";
|
$string .= str_pad(self::TYPES[$type], 8, ' ') . ": ";
|
||||||
foreach ($rules as $rule) {
|
foreach ($rules as $rule) {
|
||||||
$string .= ($repositorySet && $request && $pool ? $rule->getPrettyString($repositorySet, $request, $pool, $isVerbose) : $rule)."\n";
|
$string .= ($repositorySet !== null && $request !== null && $pool !== null ? $rule->getPrettyString($repositorySet, $request, $pool, $isVerbose) : $rule)."\n";
|
||||||
}
|
}
|
||||||
$string .= "\n\n";
|
$string .= "\n\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ class RuleSetGenerator
|
||||||
*
|
*
|
||||||
* @phpstan-param ReasonData $reasonData
|
* @phpstan-param ReasonData $reasonData
|
||||||
*/
|
*/
|
||||||
protected function createRequireRule(BasePackage $package, array $providers, $reason, $reasonData = null): ?Rule
|
protected function createRequireRule(BasePackage $package, array $providers, $reason, $reasonData): ?Rule
|
||||||
{
|
{
|
||||||
$literals = [-$package->id];
|
$literals = [-$package->id];
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ class RuleSetGenerator
|
||||||
* The rule is (A|B|C) with A, B and C different packages. If the given
|
* The rule is (A|B|C) with A, B and C different packages. If the given
|
||||||
* set of packages is empty an impossible rule is generated.
|
* set of packages is empty an impossible rule is generated.
|
||||||
*
|
*
|
||||||
* @param BasePackage[] $packages The set of packages to choose from
|
* @param non-empty-array<BasePackage> $packages The set of packages to choose from
|
||||||
* @param Rule::RULE_* $reason A RULE_* constant describing the reason for
|
* @param Rule::RULE_* $reason A RULE_* constant describing the reason for
|
||||||
* generating this rule
|
* generating this rule
|
||||||
* @param mixed $reasonData Additional data like the root require or fix request info
|
* @param mixed $reasonData Additional data like the root require or fix request info
|
||||||
|
@ -109,7 +109,7 @@ class RuleSetGenerator
|
||||||
*
|
*
|
||||||
* @phpstan-param ReasonData $reasonData
|
* @phpstan-param ReasonData $reasonData
|
||||||
*/
|
*/
|
||||||
protected function createRule2Literals(BasePackage $issuer, BasePackage $provider, $reason, $reasonData = null): ?Rule
|
protected function createRule2Literals(BasePackage $issuer, BasePackage $provider, $reason, $reasonData): ?Rule
|
||||||
{
|
{
|
||||||
// ignore self conflict
|
// ignore self conflict
|
||||||
if ($issuer === $provider) {
|
if ($issuer === $provider) {
|
||||||
|
@ -120,7 +120,7 @@ class RuleSetGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param BasePackage[] $packages
|
* @param non-empty-array<BasePackage> $packages
|
||||||
* @param Rule::RULE_* $reason A RULE_* constant
|
* @param Rule::RULE_* $reason A RULE_* constant
|
||||||
* @param mixed $reasonData
|
* @param mixed $reasonData
|
||||||
*
|
*
|
||||||
|
@ -151,7 +151,7 @@ class RuleSetGenerator
|
||||||
*/
|
*/
|
||||||
private function addRule($type, ?Rule $newRule = null): void
|
private function addRule($type, ?Rule $newRule = null): void
|
||||||
{
|
{
|
||||||
if (!$newRule) {
|
if (null === $newRule) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ class RuleSetGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
$packages = $this->pool->whatProvides($packageName, $constraint);
|
$packages = $this->pool->whatProvides($packageName, $constraint);
|
||||||
if ($packages) {
|
if (\count($packages) > 0) {
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
$this->addRulesForPackage($package, $platformRequirementFilter);
|
$this->addRulesForPackage($package, $platformRequirementFilter);
|
||||||
}
|
}
|
||||||
|
@ -307,7 +307,7 @@ class RuleSetGenerator
|
||||||
|
|
||||||
public function getRulesFor(Request $request, ?PlatformRequirementFilterInterface $platformRequirementFilter = null): RuleSet
|
public function getRulesFor(Request $request, ?PlatformRequirementFilterInterface $platformRequirementFilter = null): RuleSet
|
||||||
{
|
{
|
||||||
$platformRequirementFilter = $platformRequirementFilter ?: PlatformRequirementFilterFactory::ignoreNothing();
|
$platformRequirementFilter = $platformRequirementFilter ?? PlatformRequirementFilterFactory::ignoreNothing();
|
||||||
|
|
||||||
$this->addRulesForRequest($request, $platformRequirementFilter);
|
$this->addRulesForRequest($request, $platformRequirementFilter);
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Composer\DependencyResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Nils Adermann <naderman@naderman.de>
|
* @author Nils Adermann <naderman@naderman.de>
|
||||||
* @implements \Iterator<RuleSet::TYPE_*, Rule>
|
* @implements \Iterator<RuleSet::TYPE_*|-1, Rule>
|
||||||
*/
|
*/
|
||||||
class RuleSetIterator implements \Iterator
|
class RuleSetIterator implements \Iterator
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,7 +43,7 @@ class Solver
|
||||||
|
|
||||||
/** @var int */
|
/** @var int */
|
||||||
protected $propagateIndex;
|
protected $propagateIndex;
|
||||||
/** @var mixed[] */
|
/** @var array<int, array{array<int, int>, int}> */
|
||||||
protected $branches = [];
|
protected $branches = [];
|
||||||
/** @var Problem[] */
|
/** @var Problem[] */
|
||||||
protected $problems = [];
|
protected $problems = [];
|
||||||
|
@ -109,7 +109,7 @@ class Solver
|
||||||
|
|
||||||
$conflict = $this->decisions->decisionRule($literal);
|
$conflict = $this->decisions->decisionRule($literal);
|
||||||
|
|
||||||
if ($conflict && RuleSet::TYPE_PACKAGE === $conflict->getType()) {
|
if (RuleSet::TYPE_PACKAGE === $conflict->getType()) {
|
||||||
$problem = new Problem();
|
$problem = new Problem();
|
||||||
|
|
||||||
$problem->addRule($rule);
|
$problem->addRule($rule);
|
||||||
|
@ -164,7 +164,7 @@ class Solver
|
||||||
$constraint = $platformRequirementFilter->filterConstraint($packageName, $constraint);
|
$constraint = $platformRequirementFilter->filterConstraint($packageName, $constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->pool->whatProvides($packageName, $constraint)) {
|
if (0 === \count($this->pool->whatProvides($packageName, $constraint))) {
|
||||||
$problem = new Problem();
|
$problem = new Problem();
|
||||||
$problem->addRule(new GenericRule([], Rule::RULE_ROOT_REQUIRE, ['packageName' => $packageName, 'constraint' => $constraint]));
|
$problem->addRule(new GenericRule([], Rule::RULE_ROOT_REQUIRE, ['packageName' => $packageName, 'constraint' => $constraint]));
|
||||||
$this->problems[] = $problem;
|
$this->problems[] = $problem;
|
||||||
|
@ -174,7 +174,7 @@ class Solver
|
||||||
|
|
||||||
public function solve(Request $request, ?PlatformRequirementFilterInterface $platformRequirementFilter = null): LockTransaction
|
public function solve(Request $request, ?PlatformRequirementFilterInterface $platformRequirementFilter = null): LockTransaction
|
||||||
{
|
{
|
||||||
$platformRequirementFilter = $platformRequirementFilter ?: PlatformRequirementFilterFactory::ignoreNothing();
|
$platformRequirementFilter = $platformRequirementFilter ?? PlatformRequirementFilterFactory::ignoreNothing();
|
||||||
|
|
||||||
$this->setupFixedMap($request);
|
$this->setupFixedMap($request);
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ class Solver
|
||||||
$this->io->writeError('', true, IOInterface::DEBUG);
|
$this->io->writeError('', true, IOInterface::DEBUG);
|
||||||
$this->io->writeError(sprintf('Dependency resolution completed in %.3f seconds', microtime(true) - $before), true, IOInterface::VERBOSE);
|
$this->io->writeError(sprintf('Dependency resolution completed in %.3f seconds', microtime(true) - $before), true, IOInterface::VERBOSE);
|
||||||
|
|
||||||
if ($this->problems) {
|
if (\count($this->problems) > 0) {
|
||||||
throw new SolverProblemsException($this->problems, $this->learnedPool);
|
throw new SolverProblemsException($this->problems, $this->learnedPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +227,7 @@ class Solver
|
||||||
|
|
||||||
$this->propagateIndex++;
|
$this->propagateIndex++;
|
||||||
|
|
||||||
if ($conflict) {
|
if ($conflict !== null) {
|
||||||
return $conflict;
|
return $conflict;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,7 +257,7 @@ class Solver
|
||||||
$this->propagateIndex = \count($this->decisions);
|
$this->propagateIndex = \count($this->decisions);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!empty($this->branches) && $this->branches[\count($this->branches) - 1][self::BRANCH_LEVEL] >= $level) {
|
while (\count($this->branches) > 0 && $this->branches[\count($this->branches) - 1][self::BRANCH_LEVEL] >= $level) {
|
||||||
array_pop($this->branches);
|
array_pop($this->branches);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -274,10 +274,8 @@ class Solver
|
||||||
* rule (always unit) and re-propagate.
|
* rule (always unit) and re-propagate.
|
||||||
*
|
*
|
||||||
* returns the new solver level or 0 if unsolvable
|
* returns the new solver level or 0 if unsolvable
|
||||||
*
|
|
||||||
* @param string|int $literal
|
|
||||||
*/
|
*/
|
||||||
private function setPropagateLearn(int $level, $literal, Rule $rule): int
|
private function setPropagateLearn(int $level, int $literal, Rule $rule): int
|
||||||
{
|
{
|
||||||
$level++;
|
$level++;
|
||||||
|
|
||||||
|
@ -291,7 +289,9 @@ class Solver
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($level === 1) {
|
if ($level === 1) {
|
||||||
return $this->analyzeUnsolvable($rule);
|
$this->analyzeUnsolvable($rule);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// conflict
|
// conflict
|
||||||
|
@ -322,7 +322,7 @@ class Solver
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int[] $decisionQueue
|
* @param non-empty-list<int> $decisionQueue
|
||||||
*/
|
*/
|
||||||
private function selectAndInstall(int $level, array $decisionQueue, Rule $rule): int
|
private function selectAndInstall(int $level, array $decisionQueue, Rule $rule): int
|
||||||
{
|
{
|
||||||
|
@ -332,7 +332,7 @@ class Solver
|
||||||
$selectedLiteral = array_shift($literals);
|
$selectedLiteral = array_shift($literals);
|
||||||
|
|
||||||
// if there are multiple candidates, then branch
|
// if there are multiple candidates, then branch
|
||||||
if (\count($literals)) {
|
if (\count($literals) > 0) {
|
||||||
$this->branches[] = [$literals, $level];
|
$this->branches[] = [$literals, $level];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,7 +349,8 @@ class Solver
|
||||||
$num = 0;
|
$num = 0;
|
||||||
$l1num = 0;
|
$l1num = 0;
|
||||||
$seen = [];
|
$seen = [];
|
||||||
$learnedLiterals = [null];
|
$learnedLiteral = null;
|
||||||
|
$otherLearnedLiterals = [];
|
||||||
|
|
||||||
$decisionId = \count($this->decisions);
|
$decisionId = \count($this->decisions);
|
||||||
|
|
||||||
|
@ -382,7 +383,7 @@ class Solver
|
||||||
$num++;
|
$num++;
|
||||||
} else {
|
} else {
|
||||||
// not level1 or conflict level, add to new rule
|
// not level1 or conflict level, add to new rule
|
||||||
$learnedLiterals[] = $literal;
|
$otherLearnedLiterals[] = $literal;
|
||||||
|
|
||||||
if ($l > $ruleLevel) {
|
if ($l > $ruleLevel) {
|
||||||
$ruleLevel = $l;
|
$ruleLevel = $l;
|
||||||
|
@ -423,16 +424,14 @@ class Solver
|
||||||
if ($literal < 0) {
|
if ($literal < 0) {
|
||||||
$this->testFlagLearnedPositiveLiteral = true;
|
$this->testFlagLearnedPositiveLiteral = true;
|
||||||
}
|
}
|
||||||
$learnedLiterals[0] = -$literal;
|
$learnedLiteral = -$literal;
|
||||||
|
|
||||||
if (!$l1num) {
|
if (0 === $l1num) {
|
||||||
break 2;
|
break 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($learnedLiterals as $i => $learnedLiteral) {
|
foreach ($otherLearnedLiterals as $otherLiteral) {
|
||||||
if ($i !== 0) {
|
unset($seen[abs($otherLiteral)]);
|
||||||
unset($seen[abs($learnedLiteral)]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// only level 1 marks left
|
// only level 1 marks left
|
||||||
$l1num++;
|
$l1num++;
|
||||||
|
@ -442,24 +441,24 @@ class Solver
|
||||||
$rule = $decision[Decisions::DECISION_REASON];
|
$rule = $decision[Decisions::DECISION_REASON];
|
||||||
|
|
||||||
if ($rule instanceof MultiConflictRule) {
|
if ($rule instanceof MultiConflictRule) {
|
||||||
// there is only ever exactly one positive decision in a multiconflict rule
|
// there is only ever exactly one positive decision in a MultiConflictRule
|
||||||
foreach ($rule->getLiterals() as $literal) {
|
foreach ($rule->getLiterals() as $ruleLiteral) {
|
||||||
if (!isset($seen[abs($literal)]) && $this->decisions->satisfy(-$literal)) {
|
if (!isset($seen[abs($ruleLiteral)]) && $this->decisions->satisfy(-$ruleLiteral)) {
|
||||||
$this->learnedPool[\count($this->learnedPool) - 1][] = $rule;
|
$this->learnedPool[\count($this->learnedPool) - 1][] = $rule;
|
||||||
$l = $this->decisions->decisionLevel($literal);
|
$l = $this->decisions->decisionLevel($ruleLiteral);
|
||||||
if (1 === $l) {
|
if (1 === $l) {
|
||||||
$l1num++;
|
$l1num++;
|
||||||
} elseif ($level === $l) {
|
} elseif ($level === $l) {
|
||||||
$num++;
|
$num++;
|
||||||
} else {
|
} else {
|
||||||
// not level1 or conflict level, add to new rule
|
// not level1 or conflict level, add to new rule
|
||||||
$learnedLiterals[] = $literal;
|
$otherLearnedLiterals[] = $ruleLiteral;
|
||||||
|
|
||||||
if ($l > $ruleLevel) {
|
if ($l > $ruleLevel) {
|
||||||
$ruleLevel = $l;
|
$ruleLevel = $l;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$seen[abs($literal)] = true;
|
$seen[abs($ruleLiteral)] = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -475,15 +474,16 @@ class Solver
|
||||||
|
|
||||||
$why = \count($this->learnedPool) - 1;
|
$why = \count($this->learnedPool) - 1;
|
||||||
|
|
||||||
if (null === $learnedLiterals[0]) {
|
if (null === $learnedLiteral) {
|
||||||
throw new SolverBugException(
|
throw new SolverBugException(
|
||||||
"Did not find a learnable literal in analyzed rule $analyzedRule."
|
"Did not find a learnable literal in analyzed rule $analyzedRule."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$newRule = new GenericRule($learnedLiterals, Rule::RULE_LEARNED, $why);
|
array_unshift($otherLearnedLiterals, $learnedLiteral);
|
||||||
|
$newRule = new GenericRule($otherLearnedLiterals, Rule::RULE_LEARNED, $why);
|
||||||
|
|
||||||
return [$learnedLiterals[0], $ruleLevel, $newRule, $why];
|
return [$learnedLiteral, $ruleLevel, $newRule, $why];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -516,7 +516,7 @@ class Solver
|
||||||
$problem->addRule($conflictRule);
|
$problem->addRule($conflictRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function analyzeUnsolvable(Rule $conflictRule): int
|
private function analyzeUnsolvable(Rule $conflictRule): void
|
||||||
{
|
{
|
||||||
$problem = new Problem();
|
$problem = new Problem();
|
||||||
$problem->addRule($conflictRule);
|
$problem->addRule($conflictRule);
|
||||||
|
@ -539,10 +539,10 @@ class Solver
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->decisions as $decision) {
|
foreach ($this->decisions as $decision) {
|
||||||
$literal = $decision[Decisions::DECISION_LITERAL];
|
$decisionLiteral = $decision[Decisions::DECISION_LITERAL];
|
||||||
|
|
||||||
// skip literals that are not in this rule
|
// skip literals that are not in this rule
|
||||||
if (!isset($seen[abs($literal)])) {
|
if (!isset($seen[abs($decisionLiteral)])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -552,7 +552,6 @@ class Solver
|
||||||
$this->analyzeUnsolvableRule($problem, $why, $ruleSeen);
|
$this->analyzeUnsolvableRule($problem, $why, $ruleSeen);
|
||||||
|
|
||||||
$literals = $why->getLiterals();
|
$literals = $why->getLiterals();
|
||||||
|
|
||||||
foreach ($literals as $literal) {
|
foreach ($literals as $literal) {
|
||||||
// skip the one true literal
|
// skip the one true literal
|
||||||
if ($this->decisions->satisfy($literal)) {
|
if ($this->decisions->satisfy($literal)) {
|
||||||
|
@ -561,8 +560,6 @@ class Solver
|
||||||
$seen[abs($literal)] = true;
|
$seen[abs($literal)] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function runSat(): void
|
private function runSat(): void
|
||||||
|
@ -586,9 +583,7 @@ class Solver
|
||||||
if (1 === $level) {
|
if (1 === $level) {
|
||||||
$conflictRule = $this->propagate($level);
|
$conflictRule = $this->propagate($level);
|
||||||
if (null !== $conflictRule) {
|
if (null !== $conflictRule) {
|
||||||
if ($this->analyzeUnsolvable($conflictRule)) {
|
$this->analyzeUnsolvable($conflictRule);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -612,7 +607,7 @@ class Solver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($noneSatisfied && \count($decisionQueue)) {
|
if ($noneSatisfied && \count($decisionQueue) > 0) {
|
||||||
// if any of the options in the decision queue are fixed, only use those
|
// if any of the options in the decision queue are fixed, only use those
|
||||||
$prunedQueue = [];
|
$prunedQueue = [];
|
||||||
foreach ($decisionQueue as $literal) {
|
foreach ($decisionQueue as $literal) {
|
||||||
|
@ -620,12 +615,12 @@ class Solver
|
||||||
$prunedQueue[] = $literal;
|
$prunedQueue[] = $literal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!empty($prunedQueue)) {
|
if (\count($prunedQueue) > 0) {
|
||||||
$decisionQueue = $prunedQueue;
|
$decisionQueue = $prunedQueue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($noneSatisfied && \count($decisionQueue)) {
|
if ($noneSatisfied && \count($decisionQueue) > 0) {
|
||||||
$oLevel = $level;
|
$oLevel = $level;
|
||||||
$level = $this->selectAndInstall($level, $decisionQueue, $rule);
|
$level = $this->selectAndInstall($level, $decisionQueue, $rule);
|
||||||
|
|
||||||
|
@ -719,7 +714,7 @@ class Solver
|
||||||
}
|
}
|
||||||
|
|
||||||
// minimization step
|
// minimization step
|
||||||
if (\count($this->branches)) {
|
if (\count($this->branches) > 0) {
|
||||||
$lastLiteral = null;
|
$lastLiteral = null;
|
||||||
$lastLevel = null;
|
$lastLevel = null;
|
||||||
$lastBranchIndex = 0;
|
$lastBranchIndex = 0;
|
||||||
|
@ -729,7 +724,7 @@ class Solver
|
||||||
[$literals, $l] = $this->branches[$i];
|
[$literals, $l] = $this->branches[$i];
|
||||||
|
|
||||||
foreach ($literals as $offset => $literal) {
|
foreach ($literals as $offset => $literal) {
|
||||||
if ($literal && $literal > 0 && $this->decisions->decisionLevel($literal) > $l + 1) {
|
if ($literal > 0 && $this->decisions->decisionLevel($literal) > $l + 1) {
|
||||||
$lastLiteral = $literal;
|
$lastLiteral = $literal;
|
||||||
$lastBranchIndex = $i;
|
$lastBranchIndex = $i;
|
||||||
$lastBranchOffset = $offset;
|
$lastBranchOffset = $offset;
|
||||||
|
@ -738,7 +733,8 @@ class Solver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($lastLiteral) {
|
if ($lastLiteral !== null) {
|
||||||
|
assert($lastLevel !== null);
|
||||||
unset($this->branches[$lastBranchIndex][self::BRANCH_LITERALS][$lastBranchOffset]);
|
unset($this->branches[$lastBranchIndex][self::BRANCH_LITERALS][$lastBranchOffset]);
|
||||||
|
|
||||||
$level = $lastLevel;
|
$level = $lastLevel;
|
||||||
|
|
|
@ -38,7 +38,7 @@ class SolverProblemsException extends \RuntimeException
|
||||||
$this->problems = $problems;
|
$this->problems = $problems;
|
||||||
$this->learnedPool = $learnedPool;
|
$this->learnedPool = $learnedPool;
|
||||||
|
|
||||||
parent::__construct('Failed resolving dependencies with '.count($problems).' problems, call getPrettyString to get formatted details', self::ERROR_DEPENDENCY_RESOLUTION_FAILED);
|
parent::__construct('Failed resolving dependencies with '.\count($problems).' problems, call getPrettyString to get formatted details', self::ERROR_DEPENDENCY_RESOLUTION_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, bool $isVerbose, bool $isDevExtraction = false): string
|
public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, bool $isVerbose, bool $isDevExtraction = false): string
|
||||||
|
@ -63,11 +63,11 @@ class SolverProblemsException extends \RuntimeException
|
||||||
}
|
}
|
||||||
|
|
||||||
$hints = [];
|
$hints = [];
|
||||||
if (!$isDevExtraction && (strpos($text, 'could not be found') || strpos($text, 'no matching package found'))) {
|
if (!$isDevExtraction && (str_contains($text, 'could not be found') || str_contains($text, 'no matching package found'))) {
|
||||||
$hints[] = "Potential causes:\n - A typo in the package name\n - The package is not available in a stable-enough version according to your minimum-stability setting\n see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.\n - It's a private package and you forgot to add a custom repository to find it\n\nRead <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.";
|
$hints[] = "Potential causes:\n - A typo in the package name\n - The package is not available in a stable-enough version according to your minimum-stability setting\n see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.\n - It's a private package and you forgot to add a custom repository to find it\n\nRead <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($missingExtensions)) {
|
if (\count($missingExtensions) > 0) {
|
||||||
$hints[] = $this->createExtensionHint($missingExtensions);
|
$hints[] = $this->createExtensionHint($missingExtensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,17 +75,17 @@ class SolverProblemsException extends \RuntimeException
|
||||||
$hints[] = "Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.";
|
$hints[] = "Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strpos($text, 'found composer-plugin-api[2.0.0] but it does not match') && strpos($text, '- ocramius/package-versions')) {
|
if (str_contains($text, 'found composer-plugin-api[2.0.0] but it does not match') && str_contains($text, '- ocramius/package-versions')) {
|
||||||
$hints[] = "<warning>ocramius/package-versions only provides support for Composer 2 in 1.8+, which requires PHP 7.4.</warning>\nIf you can not upgrade PHP you can require <info>composer/package-versions-deprecated</info> to resolve this with PHP 7.0+.";
|
$hints[] = "<warning>ocramius/package-versions only provides support for Composer 2 in 1.8+, which requires PHP 7.4.</warning>\nIf you can not upgrade PHP you can require <info>composer/package-versions-deprecated</info> to resolve this with PHP 7.0+.";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!class_exists('PHPUnit\Framework\TestCase', false)) {
|
if (!class_exists('PHPUnit\Framework\TestCase', false)) {
|
||||||
if (strpos($text, 'found composer-plugin-api[2.0.0] but it does not match')) {
|
if (str_contains($text, 'found composer-plugin-api[2.0.0] but it does not match')) {
|
||||||
$hints[] = "You are using Composer 2, which some of your plugins seem to be incompatible with. Make sure you update your plugins or report a plugin-issue to ask them to support Composer 2.";
|
$hints[] = "You are using Composer 2, which some of your plugins seem to be incompatible with. Make sure you update your plugins or report a plugin-issue to ask them to support Composer 2.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hints) {
|
if (\count($hints) > 0) {
|
||||||
$text .= "\n" . implode("\n\n", $hints);
|
$text .= "\n" . implode("\n\n", $hints);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ class Transaction
|
||||||
$visited = [];
|
$visited = [];
|
||||||
$processed = [];
|
$processed = [];
|
||||||
|
|
||||||
while (!empty($stack)) {
|
while (\count($stack) > 0) {
|
||||||
$package = array_pop($stack);
|
$package = array_pop($stack);
|
||||||
|
|
||||||
if (isset($processed[spl_object_hash($package)])) {
|
if (isset($processed[spl_object_hash($package)])) {
|
||||||
|
@ -283,17 +283,18 @@ class Transaction
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$isDownloadsModifyingPlugin = $package->getType() === 'composer-plugin' && ($extra = $package->getExtra()) && isset($extra['plugin-modifies-downloads']) && $extra['plugin-modifies-downloads'] === true;
|
$extra = $package->getExtra();
|
||||||
|
$isDownloadsModifyingPlugin = $package->getType() === 'composer-plugin' && isset($extra['plugin-modifies-downloads']) && $extra['plugin-modifies-downloads'] === true;
|
||||||
|
|
||||||
// is this a downloads modifying plugin or a dependency of one?
|
// is this a downloads modifying plugin or a dependency of one?
|
||||||
if ($isDownloadsModifyingPlugin || count(array_intersect($package->getNames(), $dlModifyingPluginRequires))) {
|
if ($isDownloadsModifyingPlugin || \count(array_intersect($package->getNames(), $dlModifyingPluginRequires)) > 0) {
|
||||||
// get the package's requires, but filter out any platform requirements
|
// get the package's requires, but filter out any platform requirements
|
||||||
$requires = array_filter(array_keys($package->getRequires()), static function ($req): bool {
|
$requires = array_filter(array_keys($package->getRequires()), static function ($req): bool {
|
||||||
return !PlatformRepository::isPlatformPackage($req);
|
return !PlatformRepository::isPlatformPackage($req);
|
||||||
});
|
});
|
||||||
|
|
||||||
// is this a plugin with no meaningful dependencies?
|
// is this a plugin with no meaningful dependencies?
|
||||||
if ($isDownloadsModifyingPlugin && !count($requires)) {
|
if ($isDownloadsModifyingPlugin && 0 === \count($requires)) {
|
||||||
// plugins with no dependencies go to the very front
|
// plugins with no dependencies go to the very front
|
||||||
array_unshift($dlModifyingPluginsNoDeps, $op);
|
array_unshift($dlModifyingPluginsNoDeps, $op);
|
||||||
} else {
|
} else {
|
||||||
|
@ -311,14 +312,14 @@ class Transaction
|
||||||
$isPlugin = $package->getType() === 'composer-plugin' || $package->getType() === 'composer-installer';
|
$isPlugin = $package->getType() === 'composer-plugin' || $package->getType() === 'composer-installer';
|
||||||
|
|
||||||
// is this a plugin or a dependency of a plugin?
|
// is this a plugin or a dependency of a plugin?
|
||||||
if ($isPlugin || count(array_intersect($package->getNames(), $pluginRequires))) {
|
if ($isPlugin || \count(array_intersect($package->getNames(), $pluginRequires)) > 0) {
|
||||||
// get the package's requires, but filter out any platform requirements
|
// get the package's requires, but filter out any platform requirements
|
||||||
$requires = array_filter(array_keys($package->getRequires()), static function ($req): bool {
|
$requires = array_filter(array_keys($package->getRequires()), static function ($req): bool {
|
||||||
return !PlatformRepository::isPlatformPackage($req);
|
return !PlatformRepository::isPlatformPackage($req);
|
||||||
});
|
});
|
||||||
|
|
||||||
// is this a plugin with no meaningful dependencies?
|
// is this a plugin with no meaningful dependencies?
|
||||||
if ($isPlugin && !count($requires)) {
|
if ($isPlugin && 0 === \count($requires)) {
|
||||||
// plugins with no dependencies go to the very front
|
// plugins with no dependencies go to the very front
|
||||||
array_unshift($pluginsNoDeps, $op);
|
array_unshift($pluginsNoDeps, $op);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -226,6 +226,7 @@ class DefaultPolicyTest extends TestCase
|
||||||
$pool = $this->repositorySet->createPoolForPackage('A', $this->repoLocked);
|
$pool = $this->repositorySet->createPoolForPackage('A', $this->repoLocked);
|
||||||
|
|
||||||
$packages = $pool->whatProvides('a', new Constraint('=', '2.1.9999999.9999999-dev'));
|
$packages = $pool->whatProvides('a', new Constraint('=', '2.1.9999999.9999999-dev'));
|
||||||
|
self::assertNotEmpty($packages);
|
||||||
$literals = [];
|
$literals = [];
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
$literals[] = $package->getId();
|
$literals[] = $package->getId();
|
||||||
|
|
Loading…
Reference in New Issue