1
0
Fork 0

Update deps, fix some phpstan issues

Update baseline (1484, 84)
pull/12088/head
Jordi Boggiano 2024-08-21 14:07:03 +02:00
parent 3ba58ea3eb
commit 48d345ac3e
No known key found for this signature in database
16 changed files with 98 additions and 248 deletions

86
composer.lock generated
View File

@ -226,26 +226,26 @@
}, },
{ {
"name": "composer/pcre", "name": "composer/pcre",
"version": "2.2.0", "version": "2.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/composer/pcre.git", "url": "https://github.com/composer/pcre.git",
"reference": "0e455b78ac53637929b29d5ab5bf3c978329c1eb" "reference": "06d0e49d6e136e4521c6bad18598bf0f6062ae37"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/composer/pcre/zipball/0e455b78ac53637929b29d5ab5bf3c978329c1eb", "url": "https://api.github.com/repos/composer/pcre/zipball/06d0e49d6e136e4521c6bad18598bf0f6062ae37",
"reference": "0e455b78ac53637929b29d5ab5bf3c978329c1eb", "reference": "06d0e49d6e136e4521c6bad18598bf0f6062ae37",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.2 || ^8.0" "php": "^7.2 || ^8.0"
}, },
"conflict": { "conflict": {
"phpstan/phpstan": "<1.11.8" "phpstan/phpstan": "<1.11.10"
}, },
"require-dev": { "require-dev": {
"phpstan/phpstan": "^1.11.8", "phpstan/phpstan": "^1.11.10",
"phpstan/phpstan-strict-rules": "^1.1", "phpstan/phpstan-strict-rules": "^1.1",
"phpunit/phpunit": "^8 || ^9" "phpunit/phpunit": "^8 || ^9"
}, },
@ -285,7 +285,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/composer/pcre/issues", "issues": "https://github.com/composer/pcre/issues",
"source": "https://github.com/composer/pcre/tree/2.2.0" "source": "https://github.com/composer/pcre/tree/2.3.0"
}, },
"funding": [ "funding": [
{ {
@ -301,7 +301,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-07-25T09:28:32+00:00" "time": "2024-08-19T19:14:31+00:00"
}, },
{ {
"name": "composer/semver", "name": "composer/semver",
@ -941,16 +941,16 @@
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v5.4.41", "version": "v5.4.42",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "6473d441a913cb997123b59ff2dbe3d1cf9e11ba" "reference": "cef62396a0477e94fc52e87a17c6e5c32e226b7f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/6473d441a913cb997123b59ff2dbe3d1cf9e11ba", "url": "https://api.github.com/repos/symfony/console/zipball/cef62396a0477e94fc52e87a17c6e5c32e226b7f",
"reference": "6473d441a913cb997123b59ff2dbe3d1cf9e11ba", "reference": "cef62396a0477e94fc52e87a17c6e5c32e226b7f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1020,7 +1020,7 @@
"terminal" "terminal"
], ],
"support": { "support": {
"source": "https://github.com/symfony/console/tree/v5.4.41" "source": "https://github.com/symfony/console/tree/v5.4.42"
}, },
"funding": [ "funding": [
{ {
@ -1036,7 +1036,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-06-28T07:48:55+00:00" "time": "2024-07-26T12:21:55+00:00"
}, },
{ {
"name": "symfony/deprecation-contracts", "name": "symfony/deprecation-contracts",
@ -1174,16 +1174,16 @@
}, },
{ {
"name": "symfony/finder", "name": "symfony/finder",
"version": "v5.4.40", "version": "v5.4.42",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/finder.git", "url": "https://github.com/symfony/finder.git",
"reference": "f51cff4687547641c7d8180d74932ab40b2205ce" "reference": "0724c51fa067b198e36506d2864e09a52180998a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/f51cff4687547641c7d8180d74932ab40b2205ce", "url": "https://api.github.com/repos/symfony/finder/zipball/0724c51fa067b198e36506d2864e09a52180998a",
"reference": "f51cff4687547641c7d8180d74932ab40b2205ce", "reference": "0724c51fa067b198e36506d2864e09a52180998a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1217,7 +1217,7 @@
"description": "Finds files and directories via an intuitive fluent interface", "description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/finder/tree/v5.4.40" "source": "https://github.com/symfony/finder/tree/v5.4.42"
}, },
"funding": [ "funding": [
{ {
@ -1233,7 +1233,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-05-31T14:33:22+00:00" "time": "2024-07-22T08:53:29+00:00"
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
@ -1932,16 +1932,16 @@
}, },
{ {
"name": "symfony/string", "name": "symfony/string",
"version": "v5.4.41", "version": "v5.4.42",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/string.git", "url": "https://github.com/symfony/string.git",
"reference": "065a9611e0b1fd2197a867e1fb7f2238191b7096" "reference": "909cec913edea162a3b2836788228ad45fcab337"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/065a9611e0b1fd2197a867e1fb7f2238191b7096", "url": "https://api.github.com/repos/symfony/string/zipball/909cec913edea162a3b2836788228ad45fcab337",
"reference": "065a9611e0b1fd2197a867e1fb7f2238191b7096", "reference": "909cec913edea162a3b2836788228ad45fcab337",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1998,7 +1998,7 @@
"utf8" "utf8"
], ],
"support": { "support": {
"source": "https://github.com/symfony/string/tree/v5.4.41" "source": "https://github.com/symfony/string/tree/v5.4.42"
}, },
"funding": [ "funding": [
{ {
@ -2014,22 +2014,22 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-06-28T09:20:55+00:00" "time": "2024-07-20T18:38:32+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [
{ {
"name": "phpstan/phpstan", "name": "phpstan/phpstan",
"version": "1.11.8", "version": "1.11.11",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan.git", "url": "https://github.com/phpstan/phpstan.git",
"reference": "6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec" "reference": "707c2aed5d8d0075666e673a5e71440c1d01a5a3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec", "url": "https://api.github.com/repos/phpstan/phpstan/zipball/707c2aed5d8d0075666e673a5e71440c1d01a5a3",
"reference": "6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec", "reference": "707c2aed5d8d0075666e673a5e71440c1d01a5a3",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2074,7 +2074,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-07-24T07:01:22+00:00" "time": "2024-08-19T14:37:29+00:00"
}, },
{ {
"name": "phpstan/phpstan-deprecation-rules", "name": "phpstan/phpstan-deprecation-rules",
@ -2226,16 +2226,16 @@
}, },
{ {
"name": "phpstan/phpstan-symfony", "name": "phpstan/phpstan-symfony",
"version": "1.4.6", "version": "1.4.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan-symfony.git", "url": "https://github.com/phpstan/phpstan-symfony.git",
"reference": "e909a075d69e0d4db262ac3407350ae2c6b6ab5f" "reference": "14eec8c011b856eee4d744a2a3f709db1e1858bd"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/e909a075d69e0d4db262ac3407350ae2c6b6ab5f", "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/14eec8c011b856eee4d744a2a3f709db1e1858bd",
"reference": "e909a075d69e0d4db262ac3407350ae2c6b6ab5f", "reference": "14eec8c011b856eee4d744a2a3f709db1e1858bd",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2292,22 +2292,22 @@
"description": "Symfony Framework extensions and rules for PHPStan", "description": "Symfony Framework extensions and rules for PHPStan",
"support": { "support": {
"issues": "https://github.com/phpstan/phpstan-symfony/issues", "issues": "https://github.com/phpstan/phpstan-symfony/issues",
"source": "https://github.com/phpstan/phpstan-symfony/tree/1.4.6" "source": "https://github.com/phpstan/phpstan-symfony/tree/1.4.8"
}, },
"time": "2024-07-16T11:48:54+00:00" "time": "2024-08-13T19:43:40+00:00"
}, },
{ {
"name": "symfony/phpunit-bridge", "name": "symfony/phpunit-bridge",
"version": "v7.1.2", "version": "v7.1.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/phpunit-bridge.git", "url": "https://github.com/symfony/phpunit-bridge.git",
"reference": "8eb63f1c0e2001f97b3cd9ed550b18765cdeb1c8" "reference": "e823122d31935eb711e2767c31f3d71cb0b87fb1"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/8eb63f1c0e2001f97b3cd9ed550b18765cdeb1c8", "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/e823122d31935eb711e2767c31f3d71cb0b87fb1",
"reference": "8eb63f1c0e2001f97b3cd9ed550b18765cdeb1c8", "reference": "e823122d31935eb711e2767c31f3d71cb0b87fb1",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2360,7 +2360,7 @@
"description": "Provides utilities for PHPUnit, especially user deprecation notices management", "description": "Provides utilities for PHPUnit, especially user deprecation notices management",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/phpunit-bridge/tree/v7.1.2" "source": "https://github.com/symfony/phpunit-bridge/tree/v7.1.3"
}, },
"funding": [ "funding": [
{ {
@ -2376,7 +2376,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-06-25T19:55:06+00:00" "time": "2024-07-26T12:41:01+00:00"
} }
], ],
"aliases": [], "aliases": [],

View File

@ -105,16 +105,6 @@ parameters:
count: 1 count: 1
path: ../src/Composer/EventDispatcher/EventDispatcher.php path: ../src/Composer/EventDispatcher/EventDispatcher.php
-
message: "#^Parameter \\#1 \\$stream of function fwrite expects resource, resource\\|false given\\.$#"
count: 1
path: ../src/Composer/IO/BufferIO.php
-
message: "#^Parameter \\#1 \\$stream of function rewind expects resource, resource\\|false given\\.$#"
count: 1
path: ../src/Composer/IO/BufferIO.php
- -
message: "#^Parameter \\#1 \\$stream of function fclose expects resource, resource\\|false given\\.$#" message: "#^Parameter \\#1 \\$stream of function fclose expects resource, resource\\|false given\\.$#"
count: 1 count: 1

View File

@ -1885,11 +1885,6 @@ parameters:
count: 1 count: 1
path: ../src/Composer/EventDispatcher/EventDispatcher.php path: ../src/Composer/EventDispatcher/EventDispatcher.php
-
message: "#^Only booleans are allowed in an if condition, array\\<string\\> given\\.$#"
count: 1
path: ../src/Composer/EventDispatcher/EventDispatcher.php
- -
message: "#^Only booleans are allowed in an if condition, string\\|false given\\.$#" message: "#^Only booleans are allowed in an if condition, string\\|false given\\.$#"
count: 2 count: 2
@ -1985,46 +1980,6 @@ parameters:
count: 1 count: 1
path: ../src/Composer/IO/BaseIO.php path: ../src/Composer/IO/BaseIO.php
-
message: "#^Only booleans are allowed in a ternary operator condition, Symfony\\\\Component\\\\Console\\\\Formatter\\\\OutputFormatterInterface\\|null given\\.$#"
count: 1
path: ../src/Composer/IO/BufferIO.php
-
message: "#^PHPDoc type Symfony\\\\Component\\\\Console\\\\Input\\\\StringInput of property Composer\\\\IO\\\\BufferIO\\:\\:\\$input is not the same as PHPDoc type Symfony\\\\Component\\\\Console\\\\Input\\\\InputInterface of overridden property Composer\\\\IO\\\\ConsoleIO\\:\\:\\$input\\.$#"
count: 1
path: ../src/Composer/IO/BufferIO.php
-
message: "#^PHPDoc type Symfony\\\\Component\\\\Console\\\\Output\\\\StreamOutput of property Composer\\\\IO\\\\BufferIO\\:\\:\\$output is not the same as PHPDoc type Symfony\\\\Component\\\\Console\\\\Output\\\\OutputInterface of overridden property Composer\\\\IO\\\\ConsoleIO\\:\\:\\$output\\.$#"
count: 1
path: ../src/Composer/IO/BufferIO.php
-
message: "#^Parameter \\#1 \\$fp of function fwrite expects resource, resource\\|false given\\.$#"
count: 1
path: ../src/Composer/IO/BufferIO.php
-
message: "#^Parameter \\#1 \\$fp of function rewind expects resource, resource\\|false given\\.$#"
count: 1
path: ../src/Composer/IO/BufferIO.php
-
message: "#^Parameter \\#1 \\$stream of class Symfony\\\\Component\\\\Console\\\\Output\\\\StreamOutput constructor expects resource, resource\\|false given\\.$#"
count: 1
path: ../src/Composer/IO/BufferIO.php
-
message: "#^Parameter \\#1 \\$stream of method Symfony\\\\Component\\\\Console\\\\Input\\\\Input\\:\\:setStream\\(\\) expects resource, resource\\|false given\\.$#"
count: 1
path: ../src/Composer/IO/BufferIO.php
-
message: "#^Parameter \\#3 \\$subject of static method Composer\\\\Pcre\\\\Preg\\:\\:replaceCallback\\(\\) expects string, string\\|false given\\.$#"
count: 1
path: ../src/Composer/IO/BufferIO.php
- -
message: "#^Parameter \\#1 \\$attempts of method Symfony\\\\Component\\\\Console\\\\Question\\\\Question\\:\\:setMaxAttempts\\(\\) expects int\\|null, int\\<min, \\-1\\>\\|int\\<1, max\\>\\|true\\|null given\\.$#" message: "#^Parameter \\#1 \\$attempts of method Symfony\\\\Component\\\\Console\\\\Question\\\\Question\\:\\:setMaxAttempts\\(\\) expects int\\|null, int\\<min, \\-1\\>\\|int\\<1, max\\>\\|true\\|null given\\.$#"
count: 1 count: 1
@ -2145,71 +2100,6 @@ parameters:
count: 1 count: 1
path: ../src/Composer/Installer/BinaryInstaller.php path: ../src/Composer/Installer/BinaryInstaller.php
-
message: "#^Call to function in_array\\(\\) requires parameter \\#3 to be set\\.$#"
count: 2
path: ../src/Composer/Installer/InstallationManager.php
-
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
count: 1
path: ../src/Composer/Installer/InstallationManager.php
-
message: "#^Foreach overwrites \\$batch with its value variable\\.$#"
count: 2
path: ../src/Composer/Installer/InstallationManager.php
-
message: "#^Only booleans are allowed in &&, Composer\\\\EventDispatcher\\\\EventDispatcher\\|null given on the right side\\.$#"
count: 2
path: ../src/Composer/Installer/InstallationManager.php
-
message: "#^Only booleans are allowed in &&, array given on the right side\\.$#"
count: 1
path: ../src/Composer/Installer/InstallationManager.php
-
message: "#^Only booleans are allowed in a negated boolean, string\\|false given\\.$#"
count: 1
path: ../src/Composer/Installer/InstallationManager.php
-
message: "#^Only booleans are allowed in a negated boolean, string\\|null given\\.$#"
count: 1
path: ../src/Composer/Installer/InstallationManager.php
-
message: "#^Only booleans are allowed in an if condition, Symfony\\\\Component\\\\Console\\\\Helper\\\\ProgressBar\\|null given\\.$#"
count: 1
path: ../src/Composer/Installer/InstallationManager.php
-
message: "#^Only booleans are allowed in an if condition, array\\<Composer\\\\DependencyResolver\\\\Operation\\\\OperationInterface\\> given\\.$#"
count: 4
path: ../src/Composer/Installer/InstallationManager.php
-
message: "#^Only booleans are allowed in an if condition, int\\<0, max\\> given\\.$#"
count: 2
path: ../src/Composer/Installer/InstallationManager.php
-
message: "#^Only booleans are allowed in an if condition, int\\<0, max\\>\\|false given\\.$#"
count: 1
path: ../src/Composer/Installer/InstallationManager.php
-
message: "#^Only booleans are allowed in an if condition, string\\|null given\\.$#"
count: 1
path: ../src/Composer/Installer/InstallationManager.php
-
message: "#^Parameter \\#2 \\$offset of function array_splice expects int, int\\|string given\\.$#"
count: 1
path: ../src/Composer/Installer/InstallationManager.php
- -
message: "#^Variable method call on \\$this\\(Composer\\\\Installer\\\\InstallationManager\\)\\.$#" message: "#^Variable method call on \\$this\\(Composer\\\\Installer\\\\InstallationManager\\)\\.$#"
count: 2 count: 2
@ -4303,31 +4193,11 @@ parameters:
count: 1 count: 1
path: ../src/Composer/Util/Perforce.php path: ../src/Composer/Util/Perforce.php
-
message: "#^Casting to string something that's already string\\.$#"
count: 1
path: ../src/Composer/Util/Platform.php
-
message: "#^Only booleans are allowed in &&, string\\|false given on the right side\\.$#"
count: 1
path: ../src/Composer/Util/Platform.php
- -
message: "#^Only booleans are allowed in a negated boolean, string\\|false given\\.$#" message: "#^Only booleans are allowed in a negated boolean, string\\|false given\\.$#"
count: 1 count: 1
path: ../src/Composer/Util/Platform.php path: ../src/Composer/Util/Platform.php
-
message: "#^Only booleans are allowed in a ternary operator condition, array\\<int\\|string, int\\>\\|false given\\.$#"
count: 1
path: ../src/Composer/Util/Platform.php
-
message: "#^Short ternary operator is not allowed\\. Use null coalesce operator if applicable or consider using long ternary\\.$#"
count: 2
path: ../src/Composer/Util/Platform.php
- -
message: "#^Method Composer\\\\Util\\\\ProcessExecutor\\:\\:doExecute\\(\\) should return int but returns int\\|null\\.$#" message: "#^Method Composer\\\\Util\\\\ProcessExecutor\\:\\:doExecute\\(\\) should return int but returns int\\|null\\.$#"
count: 1 count: 1

View File

@ -18,9 +18,8 @@ parameters:
excludePaths: excludePaths:
- '../tests/Composer/Test/Fixtures/*' - '../tests/Composer/Test/Fixtures/*'
- '../tests/Composer/Test/Autoload/Fixtures/*' - '../tests/Composer/Test/Autoload/Fixtures/*'
- '../tests/Composer/Test/Autoload/MinimumVersionSupport/vendor/' - '../tests/Composer/Test/Autoload/MinimumVersionSupport/vendor/*'
- '../tests/Composer/Test/Plugin/Fixtures/*' - '../tests/Composer/Test/Plugin/Fixtures/*'
- '../tests/Composer/Test/PolyfillTestCase.php'
reportUnmatchedIgnoredErrors: false reportUnmatchedIgnoredErrors: false
treatPhpDocTypesAsCertain: false treatPhpDocTypesAsCertain: false

View File

@ -410,7 +410,7 @@ EOF;
// carry over existing autoload.php's suffix if possible and none is configured // carry over existing autoload.php's suffix if possible and none is configured
if (null === $suffix && Filesystem::isReadable($vendorPath.'/autoload.php')) { if (null === $suffix && Filesystem::isReadable($vendorPath.'/autoload.php')) {
$content = file_get_contents($vendorPath.'/autoload.php'); $content = (string) file_get_contents($vendorPath.'/autoload.php');
if (Preg::isMatch('{ComposerAutoloaderInit([^:\s]+)::}', $content, $match)) { if (Preg::isMatch('{ComposerAutoloaderInit([^:\s]+)::}', $content, $match)) {
$suffix = $match[1]; $suffix = $match[1];
} }
@ -1269,10 +1269,8 @@ INITIALIZER;
$path = Preg::replaceCallback( $path = Preg::replaceCallback(
'{^((?:(?:\\\\\\.){1,2}+/)+)}', '{^((?:(?:\\\\\\.){1,2}+/)+)}',
static function ($matches) use (&$updir): string { static function ($matches) use (&$updir): string {
if (isset($matches[1])) {
// undo preg_quote for the matched string // undo preg_quote for the matched string
$updir = str_replace('\\.', '.', $matches[1]); $updir = str_replace('\\.', '.', $matches[1]);
}
return ''; return '';
}, },

View File

@ -529,7 +529,6 @@ class Config
} }
return Preg::replaceCallback('#\{\$(.+)\}#', function ($match) use ($flags) { return Preg::replaceCallback('#\{\$(.+)\}#', function ($match) use ($flags) {
assert(is_string($match[1]));
return $this->get($match[1], $flags); return $this->get($match[1], $flags);
}, $value); }, $value);
} }

View File

@ -330,7 +330,7 @@ class EventDispatcher
} }
$possibleLocalBinaries = $this->composer->getPackage()->getBinaries(); $possibleLocalBinaries = $this->composer->getPackage()->getBinaries();
if ($possibleLocalBinaries) { if (count($possibleLocalBinaries) > 0) {
foreach ($possibleLocalBinaries as $localExec) { foreach ($possibleLocalBinaries as $localExec) {
if (Preg::isMatch('{\b'.preg_quote($callable).'$}', $localExec)) { if (Preg::isMatch('{\b'.preg_quote($callable).'$}', $localExec)) {
$caller = BinaryInstaller::determineBinaryCaller($localExec); $caller = BinaryInstaller::determineBinaryCaller($localExec);
@ -354,7 +354,7 @@ class EventDispatcher
$pathAndArgs = substr($exec, 5); $pathAndArgs = substr($exec, 5);
if (Platform::isWindows()) { if (Platform::isWindows()) {
$pathAndArgs = Preg::replaceCallback('{^\S+}', static function ($path) { $pathAndArgs = Preg::replaceCallback('{^\S+}', static function ($path) {
return str_replace('/', '\\', (string) $path[0]); return str_replace('/', '\\', $path[0]);
}, $pathAndArgs); }, $pathAndArgs);
} }
// match somename (not in quote, and not a qualified path) and if it is not a valid path from CWD then try to find it // match somename (not in quote, and not a qualified path) and if it is not a valid path from CWD then try to find it
@ -384,8 +384,6 @@ class EventDispatcher
if (Platform::isWindows()) { if (Platform::isWindows()) {
$exec = Preg::replaceCallback('{^\S+}', static function ($path) { $exec = Preg::replaceCallback('{^\S+}', static function ($path) {
assert(is_string($path[0]));
return str_replace('/', '\\', $path[0]); return str_replace('/', '\\', $path[0]);
}, $exec); }, $exec);
} }

View File

@ -14,6 +14,8 @@ namespace Composer\IO;
use Composer\Pcre\Preg; use Composer\Pcre\Preg;
use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\StreamOutput; use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Formatter\OutputFormatterInterface; use Symfony\Component\Console\Formatter\OutputFormatterInterface;
use Symfony\Component\Console\Input\StreamableInputInterface; use Symfony\Component\Console\Input\StreamableInputInterface;
@ -25,17 +27,16 @@ use Symfony\Component\Console\Helper\HelperSet;
*/ */
class BufferIO extends ConsoleIO class BufferIO extends ConsoleIO
{ {
/** @var StringInput */
protected $input;
/** @var StreamOutput */
protected $output;
public function __construct(string $input = '', int $verbosity = StreamOutput::VERBOSITY_NORMAL, ?OutputFormatterInterface $formatter = null) public function __construct(string $input = '', int $verbosity = StreamOutput::VERBOSITY_NORMAL, ?OutputFormatterInterface $formatter = null)
{ {
$input = new StringInput($input); $input = new StringInput($input);
$input->setInteractive(false); $input->setInteractive(false);
$output = new StreamOutput(fopen('php://memory', 'rw'), $verbosity, $formatter ? $formatter->isDecorated() : false, $formatter); $stream = fopen('php://memory', 'rw');
if ($stream === false) {
throw new \RuntimeException('Unable to open memory output stream');
}
$output = new StreamOutput($stream, $verbosity, $formatter !== null ? $formatter->isDecorated() : false, $formatter);
parent::__construct($input, $output, new HelperSet([ parent::__construct($input, $output, new HelperSet([
new QuestionHelper(), new QuestionHelper(),
@ -47,13 +48,12 @@ class BufferIO extends ConsoleIO
*/ */
public function getOutput(): string public function getOutput(): string
{ {
assert($this->output instanceof StreamOutput);
fseek($this->output->getStream(), 0); fseek($this->output->getStream(), 0);
$output = stream_get_contents($this->output->getStream()); $output = (string) stream_get_contents($this->output->getStream());
$output = Preg::replaceCallback("{(?<=^|\n|\x08)(.+?)(\x08+)}", static function ($matches): string { $output = Preg::replaceCallback("{(?<=^|\n|\x08)(.+?)(\x08+)}", static function ($matches): string {
assert(is_string($matches[1]));
assert(is_string($matches[2]));
$pre = strip_tags($matches[1]); $pre = strip_tags($matches[1]);
if (strlen($pre) === strlen($matches[2])) { if (strlen($pre) === strlen($matches[2])) {
@ -85,11 +85,14 @@ class BufferIO extends ConsoleIO
/** /**
* @param string[] $inputs * @param string[] $inputs
* *
* @return false|resource stream * @return resource stream
*/ */
private function createStream(array $inputs) private function createStream(array $inputs)
{ {
$stream = fopen('php://memory', 'r+'); $stream = fopen('php://memory', 'r+');
if ($stream === false) {
throw new \RuntimeException('Unable to open memory output stream');
}
foreach ($inputs as $input) { foreach ($inputs as $input) {
fwrite($stream, $input.PHP_EOL); fwrite($stream, $input.PHP_EOL);

View File

@ -39,7 +39,7 @@ use Seld\Signal\SignalHandler;
*/ */
class InstallationManager class InstallationManager
{ {
/** @var array<InstallerInterface> */ /** @var list<InstallerInterface> */
private $installers = []; private $installers = [];
/** @var array<string, InstallerInterface> */ /** @var array<string, InstallerInterface> */
private $cache = []; private $cache = [];
@ -180,7 +180,7 @@ class InstallationManager
*/ */
public function execute(InstalledRepositoryInterface $repo, array $operations, bool $devMode = true, bool $runScripts = true, bool $downloadOnly = false): void public function execute(InstalledRepositoryInterface $repo, array $operations, bool $devMode = true, bool $runScripts = true, bool $downloadOnly = false): void
{ {
/** @var array<callable(): ?PromiseInterface<void|null>> */ /** @var array<callable(): ?PromiseInterface<void|null>> $cleanupPromises */
$cleanupPromises = []; $cleanupPromises = [];
$signalHandler = SignalHandler::create([SignalHandler::SIGINT, SignalHandler::SIGTERM, SignalHandler::SIGHUP], function (string $signal, SignalHandler $handler) use (&$cleanupPromises) { $signalHandler = SignalHandler::create([SignalHandler::SIGINT, SignalHandler::SIGTERM, SignalHandler::SIGHUP], function (string $signal, SignalHandler $handler) use (&$cleanupPromises) {
@ -197,8 +197,10 @@ class InstallationManager
foreach ($operations as $index => $operation) { foreach ($operations as $index => $operation) {
if ($operation instanceof UpdateOperation || $operation instanceof InstallOperation) { if ($operation instanceof UpdateOperation || $operation instanceof InstallOperation) {
$package = $operation instanceof UpdateOperation ? $operation->getTargetPackage() : $operation->getPackage(); $package = $operation instanceof UpdateOperation ? $operation->getTargetPackage() : $operation->getPackage();
if ($package->getType() === 'composer-plugin' && ($extra = $package->getExtra()) && isset($extra['plugin-modifies-downloads']) && $extra['plugin-modifies-downloads'] === true) { if ($package->getType() === 'composer-plugin') {
if ($batch) { $extra = $package->getExtra();
if (isset($extra['plugin-modifies-downloads']) && $extra['plugin-modifies-downloads'] === true) {
if (count($batch) > 0) {
$batches[] = $batch; $batches[] = $batch;
} }
$batches[] = [$index => $operation]; $batches[] = [$index => $operation];
@ -207,15 +209,16 @@ class InstallationManager
continue; continue;
} }
} }
}
$batch[$index] = $operation; $batch[$index] = $operation;
} }
if ($batch) { if (count($batch) > 0) {
$batches[] = $batch; $batches[] = $batch;
} }
foreach ($batches as $batch) { foreach ($batches as $batchToExecute) {
$this->downloadAndExecuteBatch($repo, $batch, $cleanupPromises, $devMode, $runScripts, $downloadOnly, $operations); $this->downloadAndExecuteBatch($repo, $batchToExecute, $cleanupPromises, $devMode, $runScripts, $downloadOnly, $operations);
} }
} catch (\Exception $e) { } catch (\Exception $e) {
$this->runCleanup($cleanupPromises); $this->runCleanup($cleanupPromises);
@ -248,7 +251,7 @@ class InstallationManager
$opType = $operation->getOperationType(); $opType = $operation->getOperationType();
// ignoring alias ops as they don't need to execute anything at this stage // ignoring alias ops as they don't need to execute anything at this stage
if (!in_array($opType, ['update', 'install', 'uninstall'])) { if (!in_array($opType, ['update', 'install', 'uninstall'], true)) {
continue; continue;
} }
@ -266,7 +269,7 @@ class InstallationManager
$cleanupPromises[$index] = static function () use ($opType, $installer, $package, $initialPackage): ?PromiseInterface { $cleanupPromises[$index] = static function () use ($opType, $installer, $package, $initialPackage): ?PromiseInterface {
// avoid calling cleanup if the download was not even initialized for a package // avoid calling cleanup if the download was not even initialized for a package
// as without installation source configured nothing will work // as without installation source configured nothing will work
if (!$package->getInstallationSource()) { if (null === $package->getInstallationSource()) {
return \React\Promise\resolve(null); return \React\Promise\resolve(null);
} }
@ -282,7 +285,7 @@ class InstallationManager
} }
// execute all downloads first // execute all downloads first
if (count($promises)) { if (count($promises) > 0) {
$this->waitOnPromises($promises); $this->waitOnPromises($promises);
} }
@ -299,7 +302,7 @@ class InstallationManager
if ($operation instanceof InstallOperation || $operation instanceof UpdateOperation) { if ($operation instanceof InstallOperation || $operation instanceof UpdateOperation) {
$package = $operation instanceof UpdateOperation ? $operation->getTargetPackage() : $operation->getPackage(); $package = $operation instanceof UpdateOperation ? $operation->getTargetPackage() : $operation->getPackage();
if ($package->getType() === 'composer-plugin' || $package->getType() === 'composer-installer') { if ($package->getType() === 'composer-plugin' || $package->getType() === 'composer-installer') {
if ($batch) { if (count($batch) > 0) {
$batches[] = $batch; $batches[] = $batch;
} }
$batches[] = [$index => $operation]; $batches[] = [$index => $operation];
@ -311,12 +314,12 @@ class InstallationManager
$batch[$index] = $operation; $batch[$index] = $operation;
} }
if ($batch) { if (count($batch) > 0) {
$batches[] = $batch; $batches[] = $batch;
} }
foreach ($batches as $batch) { foreach ($batches as $batchToExecute) {
$this->executeBatch($repo, $batch, $cleanupPromises, $devMode, $runScripts, $allOperations); $this->executeBatch($repo, $batchToExecute, $cleanupPromises, $devMode, $runScripts, $allOperations);
} }
} }
@ -334,7 +337,7 @@ class InstallationManager
$opType = $operation->getOperationType(); $opType = $operation->getOperationType();
// ignoring alias ops as they don't need to execute anything // ignoring alias ops as they don't need to execute anything
if (!in_array($opType, ['update', 'install', 'uninstall'])) { if (!in_array($opType, ['update', 'install', 'uninstall'], true)) {
// output alias ops in debug verbosity as they have no output otherwise // output alias ops in debug verbosity as they have no output otherwise
if ($this->io->isDebug()) { if ($this->io->isDebug()) {
$this->io->writeError(' - ' . $operation->show(false)); $this->io->writeError(' - ' . $operation->show(false));
@ -360,9 +363,9 @@ class InstallationManager
'install' => PackageEvents::PRE_PACKAGE_INSTALL, 'install' => PackageEvents::PRE_PACKAGE_INSTALL,
'update' => PackageEvents::PRE_PACKAGE_UPDATE, 'update' => PackageEvents::PRE_PACKAGE_UPDATE,
'uninstall' => PackageEvents::PRE_PACKAGE_UNINSTALL, 'uninstall' => PackageEvents::PRE_PACKAGE_UNINSTALL,
][$opType] ?? null; ][$opType];
if (null !== $eventName && $runScripts && $this->eventDispatcher) { if ($runScripts && $this->eventDispatcher !== null) {
$this->eventDispatcher->dispatchPackageEvent($eventName, $devMode, $repo, $allOperations, $operation); $this->eventDispatcher->dispatchPackageEvent($eventName, $devMode, $repo, $allOperations, $operation);
} }
@ -389,9 +392,9 @@ class InstallationManager
'install' => PackageEvents::POST_PACKAGE_INSTALL, 'install' => PackageEvents::POST_PACKAGE_INSTALL,
'update' => PackageEvents::POST_PACKAGE_UPDATE, 'update' => PackageEvents::POST_PACKAGE_UPDATE,
'uninstall' => PackageEvents::POST_PACKAGE_UNINSTALL, 'uninstall' => PackageEvents::POST_PACKAGE_UNINSTALL,
][$opType] ?? null; ][$opType];
if (null !== $eventName && $runScripts && $dispatcher) { if ($runScripts && $dispatcher !== null) {
$postExecCallbacks[] = static function () use ($dispatcher, $eventName, $devMode, $repo, $allOperations, $operation): void { $postExecCallbacks[] = static function () use ($dispatcher, $eventName, $devMode, $repo, $allOperations, $operation): void {
$dispatcher->dispatchPackageEvent($eventName, $devMode, $repo, $allOperations, $operation); $dispatcher->dispatchPackageEvent($eventName, $devMode, $repo, $allOperations, $operation);
}; };
@ -401,7 +404,7 @@ class InstallationManager
} }
// execute all prepare => installs/updates/removes => cleanup steps // execute all prepare => installs/updates/removes => cleanup steps
if (count($promises)) { if (count($promises) > 0) {
$this->waitOnPromises($promises); $this->waitOnPromises($promises);
} }
@ -421,14 +424,14 @@ class InstallationManager
if ( if (
$this->outputProgress $this->outputProgress
&& $this->io instanceof ConsoleIO && $this->io instanceof ConsoleIO
&& !Platform::getEnv('CI') && !((bool) Platform::getEnv('CI'))
&& !$this->io->isDebug() && !$this->io->isDebug()
&& count($promises) > 1 && count($promises) > 1
) { ) {
$progress = $this->io->getProgressBar(); $progress = $this->io->getProgressBar();
} }
$this->loop->wait($promises, $progress); $this->loop->wait($promises, $progress);
if ($progress) { if ($progress !== null) {
$progress->clear(); $progress->clear();
// ProgressBar in non-decorated output does not output a final line-break and clear() does nothing // ProgressBar in non-decorated output does not output a final line-break and clear() does nothing
if (!$this->io->isDecorated()) { if (!$this->io->isDecorated()) {
@ -573,7 +576,7 @@ class InstallationManager
try { try {
foreach ($this->notifiablePackages as $repoUrl => $packages) { foreach ($this->notifiablePackages as $repoUrl => $packages) {
// non-batch API, deprecated // non-batch API, deprecated
if (strpos($repoUrl, '%package%')) { if (str_contains($repoUrl, '%package%')) {
foreach ($packages as $package) { foreach ($packages as $package) {
$url = str_replace('%package%', $package->getPrettyName(), $repoUrl); $url = str_replace('%package%', $package->getPrettyName(), $repoUrl);
@ -635,7 +638,7 @@ class InstallationManager
private function markForNotification(PackageInterface $package): void private function markForNotification(PackageInterface $package): void
{ {
if ($package->getNotificationUrl()) { if ($package->getNotificationUrl() !== null) {
$this->notifiablePackages[$package->getNotificationUrl()][$package->getName()] = $package; $this->notifiablePackages[$package->getNotificationUrl()][$package->getName()] = $package;
} }
} }
@ -663,7 +666,7 @@ class InstallationManager
}); });
} }
if (!empty($promises)) { if (count($promises) > 0) {
$this->loop->wait($promises); $this->loop->wait($promises);
} }
} }

View File

@ -284,7 +284,7 @@ class JsonFile
return Preg::replaceCallback( return Preg::replaceCallback(
'#^ {4,}#m', '#^ {4,}#m',
static function ($match) use ($indent): string { static function ($match) use ($indent): string {
return str_repeat($indent, (int)(strlen($match[0] ?? '') / 4)); return str_repeat($indent, (int)(strlen($match[0]) / 4));
}, },
$json $json
); );

View File

@ -68,8 +68,6 @@ class JsonFormatter
if ($unescapeUnicode && function_exists('mb_convert_encoding')) { if ($unescapeUnicode && function_exists('mb_convert_encoding')) {
// https://stackoverflow.com/questions/2934563/how-to-decode-unicode-escape-sequences-like-u00ed-to-proper-utf-8-encoded-cha // https://stackoverflow.com/questions/2934563/how-to-decode-unicode-escape-sequences-like-u00ed-to-proper-utf-8-encoded-cha
$buffer = Preg::replaceCallback('/(\\\\+)u([0-9a-f]{4})/i', static function ($match): string { $buffer = Preg::replaceCallback('/(\\\\+)u([0-9a-f]{4})/i', static function ($match): string {
assert(is_string($match[1]));
assert(is_string($match[2]));
$l = strlen($match[1]); $l = strlen($match[1]);
if ($l % 2) { if ($l % 2) {
@ -77,7 +75,7 @@ class JsonFormatter
// 0xD800..0xDFFF denotes UTF-16 surrogate pair which won't be unescaped // 0xD800..0xDFFF denotes UTF-16 surrogate pair which won't be unescaped
// see https://github.com/composer/composer/issues/7510 // see https://github.com/composer/composer/issues/7510
if (0xD800 <= $code && 0xDFFF >= $code) { if (0xD800 <= $code && 0xDFFF >= $code) {
return (string) $match[0]; return $match[0];
} }
return str_repeat('\\', $l - 1) . mb_convert_encoding( return str_repeat('\\', $l - 1) . mb_convert_encoding(
@ -87,7 +85,7 @@ class JsonFormatter
); );
} }
return (string) $match[0]; return $match[0];
}, $buffer); }, $buffer);
} }

View File

@ -608,7 +608,6 @@ class Filesystem
// ensure c: is normalized to C: // ensure c: is normalized to C:
$prefix = Preg::replaceCallback('{(^|://)[a-z]:$}i', static function (array $m) { $prefix = Preg::replaceCallback('{(^|://)[a-z]:$}i', static function (array $m) {
assert(is_string($m[0]));
return strtoupper($m[0]); return strtoupper($m[0]);
}, $prefix); }, $prefix);

View File

@ -101,9 +101,6 @@ class Platform
} }
return Preg::replaceCallback('#^(\$|(?P<percent>%))(?P<var>\w++)(?(percent)%)(?P<path>.*)#', static function ($matches): string { return Preg::replaceCallback('#^(\$|(?P<percent>%))(?P<var>\w++)(?(percent)%)(?P<path>.*)#', static function ($matches): string {
assert(is_string($matches['var']));
assert('' !== $matches['var']);
// Treat HOME as an alias for USERPROFILE on Windows for legacy reasons // Treat HOME as an alias for USERPROFILE on Windows for legacy reasons
if (Platform::isWindows() && $matches['var'] === 'HOME') { if (Platform::isWindows() && $matches['var'] === 'HOME') {
if ((bool) Platform::getEnv('HOME')) { if ((bool) Platform::getEnv('HOME')) {

View File

@ -455,8 +455,6 @@ class ProcessExecutor
$commandString = is_string($command) ? $command : implode(' ', array_map(self::class.'::escape', $command)); $commandString = is_string($command) ? $command : implode(' ', array_map(self::class.'::escape', $command));
$safeCommand = Preg::replaceCallback('{://(?P<user>[^:/\s]+):(?P<password>[^@\s/]+)@}i', static function ($m): string { $safeCommand = Preg::replaceCallback('{://(?P<user>[^:/\s]+):(?P<password>[^@\s/]+)@}i', static function ($m): string {
assert(is_string($m['user']));
// if the username looks like a long (12char+) hex string, or a modern github token (e.g. ghp_xxx) we obfuscate that // if the username looks like a long (12char+) hex string, or a modern github token (e.g. ghp_xxx) we obfuscate that
if (Preg::isMatch('{^([a-f0-9]{12,}|gh[a-z]_[a-zA-Z0-9_]+)$}', $m['user'])) { if (Preg::isMatch('{^([a-f0-9]{12,}|gh[a-z]_[a-zA-Z0-9_]+)$}', $m['user'])) {
return '://***:***@'; return '://***:***@';

View File

@ -110,7 +110,6 @@ class Url
$url = Preg::replace('{([&?]access_token=)[^&]+}', '$1***', $url); $url = Preg::replace('{([&?]access_token=)[^&]+}', '$1***', $url);
$url = Preg::replaceCallback('{^(?P<prefix>[a-z0-9]+://)?(?P<user>[^:/\s@]+):(?P<password>[^@\s/]+)@}i', static function ($m): string { $url = Preg::replaceCallback('{^(?P<prefix>[a-z0-9]+://)?(?P<user>[^:/\s@]+):(?P<password>[^@\s/]+)@}i', static function ($m): string {
assert(is_string($m['user']));
// if the username looks like a long (12char+) hex string, or a modern github token (e.g. ghp_xxx) we obfuscate that // if the username looks like a long (12char+) hex string, or a modern github token (e.g. ghp_xxx) we obfuscate that
if (Preg::isMatch('{^([a-f0-9]{12,}|gh[a-z]_[a-zA-Z0-9_]+|github_pat_[a-zA-Z0-9_]+)$}', $m['user'])) { if (Preg::isMatch('{^([a-f0-9]{12,}|gh[a-z]_[a-zA-Z0-9_]+|github_pat_[a-zA-Z0-9_]+)$}', $m['user'])) {
return $m['prefix'].'***:***@'; return $m['prefix'].'***:***@';

View File

@ -355,7 +355,6 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase
{ {
if (Platform::isWindows()) { if (Platform::isWindows()) {
$cmd = Preg::replaceCallback("/('[^']*')/", static function ($m) { $cmd = Preg::replaceCallback("/('[^']*')/", static function ($m) {
assert(is_string($m[1]));
// Double-quotes are used only when needed // Double-quotes are used only when needed
$char = (strpbrk($m[1], " \t^&|<>()") !== false || $m[1] === "''") ? '"' : ''; $char = (strpbrk($m[1], " \t^&|<>()") !== false || $m[1] === "''") ? '"' : '';