diff --git a/composer.lock b/composer.lock index 347cd0923..c4ef29ef4 100644 --- a/composer.lock +++ b/composer.lock @@ -941,16 +941,16 @@ }, { "name": "symfony/console", - "version": "v5.4.19", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "dccb8d251a9017d5994c988b034d3e18aaabf740" + "reference": "c77433ddc6cdc689caf48065d9ea22ca0853fbd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/dccb8d251a9017d5994c988b034d3e18aaabf740", - "reference": "dccb8d251a9017d5994c988b034d3e18aaabf740", + "url": "https://api.github.com/repos/symfony/console/zipball/c77433ddc6cdc689caf48065d9ea22ca0853fbd9", + "reference": "c77433ddc6cdc689caf48065d9ea22ca0853fbd9", "shasum": "" }, "require": { @@ -1020,7 +1020,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.19" + "source": "https://github.com/symfony/console/tree/v5.4.21" }, "funding": [ { @@ -1036,7 +1036,7 @@ "type": "tidelift" } ], - "time": "2023-01-01T08:32:19+00:00" + "time": "2023-02-25T16:59:41+00:00" }, { "name": "symfony/deprecation-contracts", @@ -1107,16 +1107,16 @@ }, { "name": "symfony/filesystem", - "version": "v5.4.19", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "648bfaca6a494f3e22378123bcee2894045dc9d8" + "reference": "e75960b1bbfd2b8c9e483e0d74811d555ca3de9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/648bfaca6a494f3e22378123bcee2894045dc9d8", - "reference": "648bfaca6a494f3e22378123bcee2894045dc9d8", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/e75960b1bbfd2b8c9e483e0d74811d555ca3de9f", + "reference": "e75960b1bbfd2b8c9e483e0d74811d555ca3de9f", "shasum": "" }, "require": { @@ -1151,7 +1151,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v5.4.19" + "source": "https://github.com/symfony/filesystem/tree/v5.4.21" }, "funding": [ { @@ -1167,20 +1167,20 @@ "type": "tidelift" } ], - "time": "2023-01-14T19:14:44+00:00" + "time": "2023-02-14T08:03:56+00:00" }, { "name": "symfony/finder", - "version": "v5.4.19", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "6071aebf810ad13fe8200c224f36103abb37cf1f" + "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/6071aebf810ad13fe8200c224f36103abb37cf1f", - "reference": "6071aebf810ad13fe8200c224f36103abb37cf1f", + "url": "https://api.github.com/repos/symfony/finder/zipball/078e9a5e1871fcfe6a5ce421b539344c21afef19", + "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19", "shasum": "" }, "require": { @@ -1214,7 +1214,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.19" + "source": "https://github.com/symfony/finder/tree/v5.4.21" }, "funding": [ { @@ -1230,7 +1230,7 @@ "type": "tidelift" } ], - "time": "2023-01-14T19:14:44+00:00" + "time": "2023-02-16T09:33:00+00:00" }, { "name": "symfony/polyfill-ctype", @@ -1805,16 +1805,16 @@ }, { "name": "symfony/process", - "version": "v5.4.19", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "c5ba874c9b636dbccf761e22ce750e88ec3f55e1" + "reference": "d4ce417ebcb0b7d090b4c178ed6d3accc518e8bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/c5ba874c9b636dbccf761e22ce750e88ec3f55e1", - "reference": "c5ba874c9b636dbccf761e22ce750e88ec3f55e1", + "url": "https://api.github.com/repos/symfony/process/zipball/d4ce417ebcb0b7d090b4c178ed6d3accc518e8bd", + "reference": "d4ce417ebcb0b7d090b4c178ed6d3accc518e8bd", "shasum": "" }, "require": { @@ -1847,7 +1847,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.19" + "source": "https://github.com/symfony/process/tree/v5.4.21" }, "funding": [ { @@ -1863,7 +1863,7 @@ "type": "tidelift" } ], - "time": "2023-01-01T08:32:19+00:00" + "time": "2023-02-21T19:46:44+00:00" }, { "name": "symfony/service-contracts", @@ -1950,16 +1950,16 @@ }, { "name": "symfony/string", - "version": "v5.4.19", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "0a01071610fd861cc160dfb7e2682ceec66064cb" + "reference": "edac10d167b78b1d90f46a80320d632de0bd9f2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/0a01071610fd861cc160dfb7e2682ceec66064cb", - "reference": "0a01071610fd861cc160dfb7e2682ceec66064cb", + "url": "https://api.github.com/repos/symfony/string/zipball/edac10d167b78b1d90f46a80320d632de0bd9f2f", + "reference": "edac10d167b78b1d90f46a80320d632de0bd9f2f", "shasum": "" }, "require": { @@ -2016,7 +2016,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.19" + "source": "https://github.com/symfony/string/tree/v5.4.21" }, "funding": [ { @@ -2032,22 +2032,22 @@ "type": "tidelift" } ], - "time": "2023-01-01T08:32:19+00:00" + "time": "2023-02-22T08:00:55+00:00" } ], "packages-dev": [ { "name": "phpstan/phpstan", - "version": "1.9.14", + "version": "1.10.7", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "e5fcc96289cf737304286a9b505fbed091f02e58" + "reference": "b10ceb526d9607903c5b2673f1fc8775dbe48975" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e5fcc96289cf737304286a9b505fbed091f02e58", - "reference": "e5fcc96289cf737304286a9b505fbed091f02e58", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/b10ceb526d9607903c5b2673f1fc8775dbe48975", + "reference": "b10ceb526d9607903c5b2673f1fc8775dbe48975", "shasum": "" }, "require": { @@ -2076,8 +2076,11 @@ "static analysis" ], "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.9.14" + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" }, "funding": [ { @@ -2093,25 +2096,25 @@ "type": "tidelift" } ], - "time": "2023-01-19T10:47:09+00:00" + "time": "2023-03-16T15:24:20+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", - "version": "1.1.1", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-deprecation-rules.git", - "reference": "2c6792eda026d9c474c14aa018aed312686714db" + "reference": "a22b36b955a2e9a3d39fe533b6c1bb5359f9c319" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/2c6792eda026d9c474c14aa018aed312686714db", - "reference": "2c6792eda026d9c474c14aa018aed312686714db", + "url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/a22b36b955a2e9a3d39fe533b6c1bb5359f9c319", + "reference": "a22b36b955a2e9a3d39fe533b6c1bb5359f9c319", "shasum": "" }, "require": { "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.9.3" + "phpstan/phpstan": "^1.10" }, "require-dev": { "php-parallel-lint/php-parallel-lint": "^1.2", @@ -2139,27 +2142,27 @@ "description": "PHPStan rules for detecting usage of deprecated classes, methods, properties, constants and traits.", "support": { "issues": "https://github.com/phpstan/phpstan-deprecation-rules/issues", - "source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/1.1.1" + "source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/1.1.3" }, - "time": "2022-12-13T14:26:20+00:00" + "time": "2023-03-17T07:50:08+00:00" }, { "name": "phpstan/phpstan-phpunit", - "version": "1.3.3", + "version": "1.3.10", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-phpunit.git", - "reference": "54a24bd23e9e80ee918cdc24f909d376c2e273f7" + "reference": "4cc5c6cc38e56bce7ea47c4091814e516d172dc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/54a24bd23e9e80ee918cdc24f909d376c2e273f7", - "reference": "54a24bd23e9e80ee918cdc24f909d376c2e273f7", + "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/4cc5c6cc38e56bce7ea47c4091814e516d172dc3", + "reference": "4cc5c6cc38e56bce7ea47c4091814e516d172dc3", "shasum": "" }, "require": { "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.9.3" + "phpstan/phpstan": "^1.10" }, "conflict": { "phpunit/phpunit": "<7.0" @@ -2191,31 +2194,32 @@ "description": "PHPUnit extensions and rules for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-phpunit/issues", - "source": "https://github.com/phpstan/phpstan-phpunit/tree/1.3.3" + "source": "https://github.com/phpstan/phpstan-phpunit/tree/1.3.10" }, - "time": "2022-12-21T15:25:00+00:00" + "time": "2023-03-02T10:25:13+00:00" }, { "name": "phpstan/phpstan-strict-rules", - "version": "1.4.5", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-strict-rules.git", - "reference": "361f75b06066f3fdaba87c1f57bdb1ffc28d6f1d" + "reference": "b7dd96a5503919a43b3cd06a2dced9d4252492f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/361f75b06066f3fdaba87c1f57bdb1ffc28d6f1d", - "reference": "361f75b06066f3fdaba87c1f57bdb1ffc28d6f1d", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/b7dd96a5503919a43b3cd06a2dced9d4252492f2", + "reference": "b7dd96a5503919a43b3cd06a2dced9d4252492f2", "shasum": "" }, "require": { "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.9.7" + "phpstan/phpstan": "^1.10" }, "require-dev": { "nikic/php-parser": "^4.13.0", "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-deprecation-rules": "^1.1", "phpstan/phpstan-phpunit": "^1.0", "phpunit/phpunit": "^9.5" }, @@ -2239,22 +2243,22 @@ "description": "Extra strict and opinionated rules for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-strict-rules/issues", - "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.4.5" + "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.5.0" }, - "time": "2023-01-11T14:16:29+00:00" + "time": "2023-02-21T10:17:10+00:00" }, { "name": "phpstan/phpstan-symfony", - "version": "1.2.22", + "version": "1.2.23", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-symfony.git", - "reference": "cbf5b9ceadab8365ed46db42dcd23db1a4c26c93" + "reference": "8a8d0538ca943b20beda7e9799e14fb3683262d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/cbf5b9ceadab8365ed46db42dcd23db1a4c26c93", - "reference": "cbf5b9ceadab8365ed46db42dcd23db1a4c26c93", + "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/8a8d0538ca943b20beda7e9799e14fb3683262d4", + "reference": "8a8d0538ca943b20beda7e9799e14fb3683262d4", "shasum": "" }, "require": { @@ -2310,22 +2314,22 @@ "description": "Symfony Framework extensions and rules for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-symfony/issues", - "source": "https://github.com/phpstan/phpstan-symfony/tree/1.2.22" + "source": "https://github.com/phpstan/phpstan-symfony/tree/1.2.23" }, - "time": "2023-02-01T13:26:41+00:00" + "time": "2023-02-06T10:42:02+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v6.2.5", + "version": "v6.2.7", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "d759e5372de414bef53a688c7aa7e240e4fd8aa2" + "reference": "56965fae0b6b8d271015990eff5240ffff02e185" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/d759e5372de414bef53a688c7aa7e240e4fd8aa2", - "reference": "d759e5372de414bef53a688c7aa7e240e4fd8aa2", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/56965fae0b6b8d271015990eff5240ffff02e185", + "reference": "56965fae0b6b8d271015990eff5240ffff02e185", "shasum": "" }, "require": { @@ -2379,7 +2383,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v6.2.5" + "source": "https://github.com/symfony/phpunit-bridge/tree/v6.2.7" }, "funding": [ { @@ -2395,7 +2399,7 @@ "type": "tidelift" } ], - "time": "2023-01-01T08:38:09+00:00" + "time": "2023-02-16T09:57:23+00:00" } ], "aliases": [], diff --git a/phpstan/baseline.neon b/phpstan/baseline.neon index 3ba4b362c..a82930c7d 100644 --- a/phpstan/baseline.neon +++ b/phpstan/baseline.neon @@ -240,11 +240,6 @@ parameters: count: 1 path: ../src/Composer/Command/BaseDependencyCommand.php - - - message: "#^Cannot access an offset on array\\\\|Composer\\\\Package\\\\Link\\>\\|Composer\\\\Package\\\\Link\\>\\|Composer\\\\Package\\\\Link\\>\\|Composer\\\\Package\\\\Link\\.$#" - count: 1 - path: ../src/Composer/Command/CheckPlatformReqsCommand.php - - message: "#^Only booleans are allowed in a negated boolean, Composer\\\\Semver\\\\Constraint\\\\ConstraintInterface\\|null given\\.$#" count: 1 @@ -475,11 +470,6 @@ parameters: count: 1 path: ../src/Composer/Command/InitCommand.php - - - message: "#^Left side of && is always false\\.$#" - count: 1 - path: ../src/Composer/Command/InitCommand.php - - message: "#^Only booleans are allowed in a negated boolean, string given\\.$#" count: 1 @@ -510,11 +500,6 @@ parameters: count: 1 path: ../src/Composer/Command/InitCommand.php - - - message: "#^Right side of && is always false\\.$#" - count: 1 - path: ../src/Composer/Command/InitCommand.php - - message: "#^Short ternary operator is not allowed\\. Use null coalesce operator if applicable or consider using long ternary\\.$#" count: 7 @@ -552,11 +537,6 @@ parameters: - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 2 - path: ../src/Composer/Command/RequireCommand.php - - - - message: "#^Left side of && is always true\\.$#" count: 1 path: ../src/Composer/Command/RequireCommand.php @@ -590,11 +570,6 @@ parameters: count: 1 path: ../src/Composer/Command/RequireCommand.php - - - message: "#^Right side of && is always true\\.$#" - count: 1 - path: ../src/Composer/Command/RequireCommand.php - - message: "#^Call to function in_array\\(\\) requires parameter \\#3 to be set\\.$#" count: 1 @@ -1085,16 +1060,6 @@ parameters: count: 1 path: ../src/Composer/Config/JsonConfigSource.php - - - message: "#^Call to function is_array\\(\\) with array\\ will always evaluate to true\\.$#" - count: 1 - path: ../src/Composer/Console/Application.php - - - - message: "#^Instanceof between Composer\\\\Command\\\\BaseCommand and Composer\\\\Command\\\\BaseCommand will always evaluate to true\\.$#" - count: 1 - path: ../src/Composer/Console/Application.php - - message: "#^Only booleans are allowed in &&, array\\\\|int\\|string\\> given on the left side\\.$#" count: 1 @@ -1460,6 +1425,11 @@ parameters: count: 2 path: ../src/Composer/DependencyResolver/Solver.php + - + message: "#^Method Composer\\\\DependencyResolver\\\\Solver\\:\\:enableDisableLearnedRules\\(\\) is unused\\.$#" + count: 1 + path: ../src/Composer/DependencyResolver/Solver.php + - message: "#^Only booleans are allowed in &&, Composer\\\\DependencyResolver\\\\Rule\\|null given on the left side\\.$#" count: 1 @@ -2030,11 +2000,6 @@ parameters: count: 1 path: ../src/Composer/EventDispatcher/EventDispatcher.php - - - message: "#^Call to function is_callable\\(\\) with callable\\(\\)\\: mixed will always evaluate to true\\.$#" - count: 1 - path: ../src/Composer/EventDispatcher/EventDispatcher.php - - message: "#^Cannot access offset 0 on array\\{0\\: string, 1\\?\\: int\\}\\|int\\|string\\.$#" count: 1 @@ -2180,11 +2145,6 @@ parameters: count: 1 path: ../src/Composer/IO/BaseIO.php - - - message: "#^Instanceof between Symfony\\\\Component\\\\Console\\\\Input\\\\StringInput and Symfony\\\\Component\\\\Console\\\\Input\\\\StreamableInputInterface will always evaluate to true\\.$#" - count: 1 - path: ../src/Composer/IO/BufferIO.php - - message: "#^Only booleans are allowed in a ternary operator condition, Symfony\\\\Component\\\\Console\\\\Formatter\\\\OutputFormatterInterface\\|null given\\.$#" count: 1 @@ -2240,16 +2200,6 @@ parameters: count: 1 path: ../src/Composer/InstalledVersions.php - - - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 1 - path: ../src/Composer/InstalledVersions.php - - - - message: "#^Parameter \\#1 \\$constraints of method Composer\\\\Semver\\\\VersionParser\\:\\:parseConstraints\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: ../src/Composer/InstalledVersions.php - - message: "#^Cannot call method getPackages\\(\\) on Composer\\\\Repository\\\\LockArrayRepository\\|null\\.$#" count: 1 @@ -2647,12 +2597,7 @@ parameters: - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 4 - path: ../src/Composer/Package/Archiver/ArchiveManager.php - - - - message: "#^Only booleans are allowed in an if condition, string\\|null given\\.$#" - count: 2 + count: 3 path: ../src/Composer/Package/Archiver/ArchiveManager.php - @@ -3070,21 +3015,6 @@ parameters: count: 1 path: ../src/Composer/Package/Version/VersionGuesser.php - - - message: "#^Strict comparison using \\!\\=\\= between null and array\\{version\\: string\\|null, commit\\: '', pretty_version\\: string\\|null\\} will always evaluate to true\\.$#" - count: 1 - path: ../src/Composer/Package/Version/VersionGuesser.php - - - - message: "#^Strict comparison using \\!\\=\\= between null and array\\{version\\: string\\|null, commit\\: string\\|null, pretty_version\\: string\\|null, feature_version\\?\\: string\\|null, feature_pretty_version\\?\\: string\\|null\\} will always evaluate to true\\.$#" - count: 1 - path: ../src/Composer/Package/Version/VersionGuesser.php - - - - message: "#^Strict comparison using \\!\\=\\= between null and string will always evaluate to true\\.$#" - count: 1 - path: ../src/Composer/Package/Version/VersionGuesser.php - - message: "#^Only booleans are allowed in an if condition, int\\<0, max\\>\\|false given\\.$#" count: 1 @@ -3120,11 +3050,6 @@ parameters: count: 1 path: ../src/Composer/Platform/Runtime.php - - - message: "#^Casting to array\\ something that's already array\\\\.$#" - count: 1 - path: ../src/Composer/Plugin/PluginManager.php - - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" count: 3 @@ -3205,11 +3130,6 @@ parameters: count: 2 path: ../src/Composer/Question/StrictConfirmationQuestion.php - - - message: "#^Casting to array\\ something that's already array\\\\.$#" - count: 1 - path: ../src/Composer/Repository/ArrayRepository.php - - message: "#^Method Composer\\\\Repository\\\\ArrayRepository\\:\\:getProviders\\(\\) should return array\\ but returns array\\\\.$#" count: 1 @@ -3415,11 +3335,6 @@ parameters: count: 2 path: ../src/Composer/Repository/FilesystemRepository.php - - - message: "#^Parameter \\#2 \\$content of method Composer\\\\Util\\\\Filesystem\\:\\:filePutContentsIfModified\\(\\) expects string, string\\|false given\\.$#" - count: 1 - path: ../src/Composer/Repository/FilesystemRepository.php - - message: "#^Parameter \\#2 \\$installPaths of method Composer\\\\Repository\\\\FilesystemRepository\\:\\:generateInstalledVersions\\(\\) expects array\\, array\\ given\\.$#" count: 1 @@ -3978,11 +3893,6 @@ parameters: count: 1 path: ../src/Composer/Repository/Vcs/SvnDriver.php - - - message: "#^Strict comparison using \\!\\=\\= between string and false will always evaluate to true\\.$#" - count: 2 - path: ../src/Composer/Repository/Vcs/SvnDriver.php - - message: "#^Cannot call method read\\(\\) on Composer\\\\Cache\\|null\\.$#" count: 1 @@ -4303,11 +4213,6 @@ parameters: count: 1 path: ../src/Composer/Util/Http/CurlDownloader.php - - - message: "#^Call to function is_resource\\(\\) with resource will always evaluate to true\\.$#" - count: 2 - path: ../src/Composer/Util/Http/CurlDownloader.php - - message: "#^Cannot access offset 'features' on array\\|false\\.$#" count: 2 @@ -4998,11 +4903,6 @@ parameters: count: 1 path: ../src/Composer/Util/StreamContextFactory.php - - - message: "#^Casting to bool something that's already \\*NEVER\\*\\.$#" - count: 1 - path: ../src/Composer/Util/Svn.php - - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" count: 2 @@ -5356,11 +5256,6 @@ parameters: count: 1 path: ../tests/Composer/Test/Installer/InstallerEventTest.php - - - message: "#^Call to function is_array\\(\\) with array\\ will always evaluate to true\\.$#" - count: 1 - path: ../tests/Composer/Test/InstallerTest.php - - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" count: 9 @@ -5511,11 +5406,6 @@ parameters: count: 1 path: ../tests/Composer/Test/Platform/VersionTest.php - - - message: "#^Call to method PHPUnit\\\\Framework\\\\Assert\\:\\:assertInstanceOf\\(\\) with 'Composer\\\\\\\\Command…' and Composer\\\\Command\\\\BaseCommand will always evaluate to true\\.$#" - count: 1 - path: ../tests/Composer/Test/Plugin/PluginInstallerTest.php - - message: "#^Parameter \\#2 \\$capabilityClassName of method Composer\\\\Plugin\\\\PluginManager\\:\\:getPluginCapability\\(\\) expects class\\-string\\, string given\\.$#" count: 2 diff --git a/src/Composer/Command/CheckPlatformReqsCommand.php b/src/Composer/Command/CheckPlatformReqsCommand.php index 5ac4d6594..e25210075 100644 --- a/src/Composer/Command/CheckPlatformReqsCommand.php +++ b/src/Composer/Command/CheckPlatformReqsCommand.php @@ -69,11 +69,9 @@ EOT } } if (!$input->getOption('no-dev')) { - $requires += $composer->getPackage()->getDevRequires(); - } - - foreach ($requires as $require => $link) { - $requires[$require] = [$link]; + foreach ($composer->getPackage()->getDevRequires() as $require => $link) { + $requires[$require] = [$link]; + } } $installedRepo = new InstalledRepository([$installedRepo, new RootPackageRepository(clone $composer->getPackage())]); diff --git a/src/Composer/Command/PackageDiscoveryTrait.php b/src/Composer/Command/PackageDiscoveryTrait.php index db205a510..1e31abaa3 100644 --- a/src/Composer/Command/PackageDiscoveryTrait.php +++ b/src/Composer/Command/PackageDiscoveryTrait.php @@ -72,7 +72,7 @@ trait PackageDiscoveryTrait // @phpstan-ignore-next-line as RequireCommand does not have the option above so this code is reachable there $file = Factory::getComposerFile(); if (is_file($file) && Filesystem::isReadable($file) && is_array($composer = json_decode((string) file_get_contents($file), true))) { - if (!empty($composer['minimum-stability'])) { + if (isset($composer['minimum-stability'])) { return VersionParser::normalizeStability($composer['minimum-stability']); } } diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php index bdd6ef6d3..9e585e614 100644 --- a/src/Composer/Console/Application.php +++ b/src/Composer/Console/Application.php @@ -339,7 +339,7 @@ class Application extends BaseApplication // Check system temp folder for usability as it can cause weird runtime issues otherwise Silencer::call(static function () use ($io): void { - $tempfile = sys_get_temp_dir() . '/temp-' . md5(microtime()); + $tempfile = sys_get_temp_dir() . '/temp-' . getmypid() . '-' . md5(microtime()); if (!(file_put_contents($tempfile, __FILE__) && (file_get_contents($tempfile) === __FILE__) && unlink($tempfile) && !file_exists($tempfile))) { $io->writeError(sprintf('PHP temp directory (%s) does not exist or is not writable to Composer. Set sys_temp_dir in your php.ini', sys_get_temp_dir())); } diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index 8d5cbc0f7..300a7e604 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -132,7 +132,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface $retries = 3; $distUrls = $package->getDistUrls(); - /** @var non-empty-array $urls */ + /** @var array $urls */ $urls = []; foreach ($distUrls as $index => $url) { $processedUrl = $this->processUrl($package, $url); @@ -146,6 +146,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface 'cacheKey' => $cacheKeyGenerator($package, $processedUrl), ]; } + assert(count($urls) > 0); $fileName = $this->getFileName($package, $path); $this->filesystem->ensureDirectoryExists($path); diff --git a/src/Composer/InstalledVersions.php b/src/Composer/InstalledVersions.php index c6b54af7b..51e734a77 100644 --- a/src/Composer/InstalledVersions.php +++ b/src/Composer/InstalledVersions.php @@ -98,7 +98,7 @@ class InstalledVersions { foreach (self::getInstalled() as $installed) { if (isset($installed['versions'][$packageName])) { - return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']); + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; } } @@ -119,7 +119,7 @@ class InstalledVersions */ public static function satisfies(VersionParser $parser, $packageName, $constraint) { - $constraint = $parser->parseConstraints($constraint); + $constraint = $parser->parseConstraints((string) $constraint); $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); return $provided->matches($constraint); @@ -328,7 +328,9 @@ class InstalledVersions if (isset(self::$installedByVendor[$vendorDir])) { $installed[] = self::$installedByVendor[$vendorDir]; } elseif (is_file($vendorDir.'/composer/installed.php')) { - $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + $installed[] = self::$installedByVendor[$vendorDir] = $required; if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { self::$installed = $installed[count($installed) - 1]; } @@ -340,12 +342,17 @@ class InstalledVersions // only require the installed.php file if this file is loaded from its dumped location, // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 if (substr(__DIR__, -8, 1) !== 'C') { - self::$installed = require __DIR__ . '/installed.php'; + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; } else { self::$installed = array(); } } - $installed[] = self::$installed; + + if (self::$installed !== array()) { + $installed[] = self::$installed; + } return $installed; } diff --git a/src/Composer/Package/Archiver/ZipArchiver.php b/src/Composer/Package/Archiver/ZipArchiver.php index 71f512e5c..f8495e26b 100644 --- a/src/Composer/Package/Archiver/ZipArchiver.php +++ b/src/Composer/Package/Archiver/ZipArchiver.php @@ -38,7 +38,7 @@ class ZipArchiver implements ArchiverInterface if ($res === true) { $files = new ArchivableFilesFinder($sources, $excludes, $ignoreFilters); foreach ($files as $file) { - /** @var \SplFileInfo $file */ + /** @var \Symfony\Component\Finder\SplFileInfo $file */ $filepath = strtr($file->getPath()."/".$file->getFilename(), '\\', '/'); $localname = $filepath; if (strpos($localname, $sources . '/') === 0) { diff --git a/src/Composer/Package/Version/VersionGuesser.php b/src/Composer/Package/Version/VersionGuesser.php index d7085c5d5..46116f0b7 100644 --- a/src/Composer/Package/Version/VersionGuesser.php +++ b/src/Composer/Package/Version/VersionGuesser.php @@ -76,7 +76,7 @@ class VersionGuesser } $versionData = $this->guessGitVersion($packageConfig, $path); - if (null !== $versionData && null !== $versionData['version']) { + if (null !== $versionData['version']) { return $this->postprocess($versionData); } @@ -86,7 +86,7 @@ class VersionGuesser } $versionData = $this->guessFossilVersion($path); - if (null !== $versionData && null !== $versionData['version']) { + if (null !== $versionData['version']) { return $this->postprocess($versionData); } diff --git a/src/Composer/Repository/Vcs/GitBitbucketDriver.php b/src/Composer/Repository/Vcs/GitBitbucketDriver.php index c3b8dd8c4..ff9aecafc 100644 --- a/src/Composer/Repository/Vcs/GitBitbucketDriver.php +++ b/src/Composer/Repository/Vcs/GitBitbucketDriver.php @@ -153,6 +153,9 @@ class GitBitbucketDriver extends VcsDriver if ($composer !== null) { // specials for bitbucket + if (isset($composer['support']) && !is_array($composer['support'])) { + $composer['support'] = []; + } if (!isset($composer['support']['source'])) { $label = array_search( $identifier, diff --git a/src/Composer/Repository/Vcs/GitHubDriver.php b/src/Composer/Repository/Vcs/GitHubDriver.php index 98dbf989a..122b03fa7 100644 --- a/src/Composer/Repository/Vcs/GitHubDriver.php +++ b/src/Composer/Repository/Vcs/GitHubDriver.php @@ -174,6 +174,9 @@ class GitHubDriver extends VcsDriver if ($composer !== null) { // specials for github + if (isset($composer['support']) && !is_array($composer['support'])) { + $composer['support'] = []; + } if (!isset($composer['support']['source'])) { $label = array_search($identifier, $this->getTags()) ?: array_search($identifier, $this->getBranches()) ?: $identifier; $composer['support']['source'] = sprintf('https://%s/%s/%s/tree/%s', $this->originUrl, $this->owner, $this->repository, $label); diff --git a/src/Composer/Repository/Vcs/GitLabDriver.php b/src/Composer/Repository/Vcs/GitLabDriver.php index 77b183e0b..1e13154c5 100644 --- a/src/Composer/Repository/Vcs/GitLabDriver.php +++ b/src/Composer/Repository/Vcs/GitLabDriver.php @@ -167,6 +167,9 @@ class GitLabDriver extends VcsDriver if (null !== $composer) { // specials for gitlab (this data is only available if authentication is provided) + if (isset($composer['support']) && !is_array($composer['support'])) { + $composer['support'] = []; + } if (!isset($composer['support']['source']) && isset($this->project['web_url'])) { $label = array_search($identifier, $this->getTags(), true) ?: array_search($identifier, $this->getBranches(), true) ?: $identifier; $composer['support']['source'] = sprintf('%s/-/tree/%s', $this->project['web_url'], $label); diff --git a/src/Composer/SelfUpdate/Versions.php b/src/Composer/SelfUpdate/Versions.php index b6145fc48..045fb22a7 100644 --- a/src/Composer/SelfUpdate/Versions.php +++ b/src/Composer/SelfUpdate/Versions.php @@ -64,8 +64,8 @@ class Versions public function setChannel(string $channel, ?IOInterface $io = null): void { - if (!in_array($channel, self::$channels, true)) { - throw new \InvalidArgumentException('Invalid channel '.$channel.', must be one of: ' . implode(', ', self::$channels)); + if (!in_array($channel, self::CHANNELS, true)) { + throw new \InvalidArgumentException('Invalid channel '.$channel.', must be one of: ' . implode(', ', self::CHANNELS)); } $channelFile = $this->config->get('home').'/update-channel'; diff --git a/src/Composer/Util/GitHub.php b/src/Composer/Util/GitHub.php index 2ac30e3b8..43a635450 100644 --- a/src/Composer/Util/GitHub.php +++ b/src/Composer/Util/GitHub.php @@ -161,15 +161,15 @@ class GitHub foreach ($headers as $header) { $header = trim($header); - if (false === strpos($header, 'X-RateLimit-')) { + if (false === stripos($header, 'x-ratelimit-')) { continue; } [$type, $value] = explode(':', $header, 2); - switch ($type) { - case 'X-RateLimit-Limit': + switch (strtolower($type)) { + case 'x-ratelimit-limit': $rateLimit['limit'] = (int) trim($value); break; - case 'X-RateLimit-Reset': + case 'x-ratelimit-reset': $rateLimit['reset'] = date('Y-m-d H:i:s', (int) trim($value)); break; } @@ -206,7 +206,7 @@ class GitHub public function isRateLimited(array $headers): bool { foreach ($headers as $header) { - if (Preg::isMatch('{^X-RateLimit-Remaining: *0$}i', trim($header))) { + if (Preg::isMatch('{^x-ratelimit-remaining: *0$}i', trim($header))) { return true; } } @@ -224,7 +224,7 @@ class GitHub public function requiresSso(array $headers): bool { foreach ($headers as $header) { - if (Preg::isMatch('{^X-GitHub-SSO: required}i', trim($header))) { + if (Preg::isMatch('{^x-github-sso: required}i', trim($header))) { return true; } } diff --git a/src/Composer/Util/Http/CurlDownloader.php b/src/Composer/Util/Http/CurlDownloader.php index aaba93627..edc668a60 100644 --- a/src/Composer/Util/Http/CurlDownloader.php +++ b/src/Composer/Util/Http/CurlDownloader.php @@ -407,7 +407,7 @@ class CurlDownloader $result = $this->isAuthenticatedRetryNeeded($job, $response); if ($result['retry']) { - $this->restartJob($job, $job['url'], ['storeAuth' => $result['storeAuth']]); + $this->restartJob($job, $job['url'], ['storeAuth' => $result['storeAuth'], 'retries' => $job['attributes']['retries'] + 1]); continue; } diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php index 810e2271d..eea6f0d73 100644 --- a/tests/Composer/Test/InstallerTest.php +++ b/tests/Composer/Test/InstallerTest.php @@ -102,9 +102,6 @@ class InstallerTest extends TestCase $repositoryManager = new RepositoryManager($io, $config, $httpDownloader, $eventDispatcher); $repositoryManager->setLocalRepository(new InstalledArrayRepository()); - if (!is_array($repositories)) { - $repositories = [$repositories]; - } foreach ($repositories as $repository) { $repositoryManager->addRepository($repository); } diff --git a/tests/Composer/Test/Mock/ProcessExecutorMock.php b/tests/Composer/Test/Mock/ProcessExecutorMock.php index 96a4a9915..9f633a626 100644 --- a/tests/Composer/Test/Mock/ProcessExecutorMock.php +++ b/tests/Composer/Test/Mock/ProcessExecutorMock.php @@ -63,7 +63,7 @@ class ProcessExecutorMock extends ProcessExecutor */ public function expects(array $expectations, bool $strict = false, array $defaultHandler = ['return' => 0, 'stdout' => '', 'stderr' => '']): void { - /** @var array{cmd: string|list, return: int, stdout: string, stderr: string, callback: callable} $default */ + /** @var array{cmd: string|list, return: int, stdout: string, stderr: string, callback: callable|null} $default */ $default = ['cmd' => '', 'return' => 0, 'stdout' => '', 'stderr' => '', 'callback' => null]; $this->expectations = array_map(static function ($expect) use ($default): array { if (is_string($expect)) { diff --git a/tests/Composer/Test/Repository/Vcs/GitBitbucketDriverTest.php b/tests/Composer/Test/Repository/Vcs/GitBitbucketDriverTest.php index 3a35cd28e..5050b0fb4 100644 --- a/tests/Composer/Test/Repository/Vcs/GitBitbucketDriverTest.php +++ b/tests/Composer/Test/Repository/Vcs/GitBitbucketDriverTest.php @@ -14,6 +14,8 @@ namespace Composer\Test\Repository\Vcs; use Composer\Config; use Composer\Repository\Vcs\GitBitbucketDriver; +use Composer\Repository\Vcs\GitHubDriver; +use Composer\Test\Mock\HttpDownloaderMock; use Composer\Test\TestCase; use Composer\Util\Filesystem; use Composer\Util\ProcessExecutor; @@ -28,7 +30,7 @@ class GitBitbucketDriverTest extends TestCase private $io; /** @var Config */ private $config; - /** @var \Composer\Util\HttpDownloader&\PHPUnit\Framework\MockObject\MockObject */ + /** @var HttpDownloaderMock */ private $httpDownloader; /** @var string */ private $home; @@ -46,9 +48,7 @@ class GitBitbucketDriverTest extends TestCase ], ]); - $this->httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader') - ->disableOriginalConstructor() - ->getMock(); + $this->httpDownloader = $this->getHttpDownloaderMock($this->io, $this->config);; } protected function tearDown(): void @@ -83,15 +83,9 @@ class GitBitbucketDriverTest extends TestCase self::expectException('RuntimeException'); self::expectExceptionMessage('https://bitbucket.org/user/repo.git does not appear to be a git repository, use https://bitbucket.org/user/repo but remember that Bitbucket no longer supports the mercurial repositories. https://bitbucket.org/blog/sunsetting-mercurial-support-in-bitbucket'); - $this->httpDownloader->expects($this->once()) - ->method('get') - ->with( - $url = 'https://api.bitbucket.org/2.0/repositories/user/repo?fields=-project%2C-owner', - [] - ) - ->willReturn( - new Response(['url' => $url], 200, [], '{"scm":"hg","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/user\/repo","name":"https"},{"href":"ssh:\/\/hg@bitbucket.org\/user\/repo","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/user\/repo"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}') - ); + $this->httpDownloader->expects([ + ['url' => 'https://api.bitbucket.org/2.0/repositories/user/repo?fields=-project%2C-owner', 'body' => '{"scm":"hg","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/user\/repo","name":"https"},{"href":"ssh:\/\/hg@bitbucket.org\/user\/repo","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/user\/repo"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}'] + ], true); $driver = $this->getDriver(['url' => 'https://bitbucket.org/user/repo.git']); @@ -109,32 +103,13 @@ class GitBitbucketDriverTest extends TestCase 'https://api.bitbucket.org/2.0/repositories/user/repo/src/main/composer.json', 'https://api.bitbucket.org/2.0/repositories/user/repo/commit/main?fields=date', ]; - $this->httpDownloader->expects($this->any()) - ->method('get') - ->withConsecutive( - [ - $urls[0], [], - ], - [ - $urls[1], [], - ], - [ - $urls[2], [], - ], - [ - $urls[3], [], - ], - [ - $urls[4], [], - ] - ) - ->willReturnOnConsecutiveCalls( - new Response(['url' => $urls[0]], 200, [], '{"mainbranch": {"name": "main"}, "scm":"git","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/user\/repo.git","name":"https"},{"href":"ssh:\/\/git@bitbucket.org\/user\/repo.git","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/user\/repo"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}'), - new Response(['url' => $urls[1]], 200, [], '{"values":[{"name":"1.0.1","target":{"hash":"9b78a3932143497c519e49b8241083838c8ff8a1"}},{"name":"1.0.0","target":{"hash":"d3393d514318a9267d2f8ebbf463a9aaa389f8eb"}}]}'), - new Response(['url' => $urls[2]], 200, [], '{"values":[{"name":"main","target":{"hash":"937992d19d72b5116c3e8c4a04f960e5fa270b22"}}]}'), - new Response(['url' => $urls[3]], 200, [], '{"name": "user/repo","description": "test repo","license": "GPL","authors": [{"name": "Name","email": "local@domain.tld"}],"require": {"creator/package": "^1.0"},"require-dev": {"phpunit/phpunit": "~4.8"}}'), - new Response(['url' => $urls[4]], 200, [], '{"date": "2016-05-17T13:19:52+00:00"}') - ); + $this->httpDownloader->expects([ + ['url' => $urls[0], 'body' => '{"mainbranch": {"name": "main"}, "scm":"git","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/user\/repo.git","name":"https"},{"href":"ssh:\/\/git@bitbucket.org\/user\/repo.git","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/user\/repo"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}'], + ['url' => $urls[1], 'body' => '{"values":[{"name":"1.0.1","target":{"hash":"9b78a3932143497c519e49b8241083838c8ff8a1"}},{"name":"1.0.0","target":{"hash":"d3393d514318a9267d2f8ebbf463a9aaa389f8eb"}}]}'], + ['url' => $urls[2], 'body' => '{"values":[{"name":"main","target":{"hash":"937992d19d72b5116c3e8c4a04f960e5fa270b22"}}]}'], + ['url' => $urls[3], 'body' => '{"name": "user/repo","description": "test repo","license": "GPL","authors": [{"name": "Name","email": "local@domain.tld"}],"require": {"creator/package": "^1.0"},"require-dev": {"phpunit/phpunit": "~4.8"}}'], + ['url' => $urls[4], 'body' => '{"date": "2016-05-17T13:19:52+00:00"}'], + ], true); $this->assertEquals( 'main', @@ -218,6 +193,34 @@ class GitBitbucketDriverTest extends TestCase $driver->initialize(); } + public function testInvalidSupportData(): void + { + $repoUrl = 'https://bitbucket.org/user/repo.git'; + + $driver = $this->getDriver(['url' => $repoUrl]); + + $urls = [ + 'https://api.bitbucket.org/2.0/repositories/user/repo?fields=-project%2C-owner', + 'https://api.bitbucket.org/2.0/repositories/user/repo/src/main/composer.json', + 'https://api.bitbucket.org/2.0/repositories/user/repo/commit/main?fields=date', + 'https://api.bitbucket.org/2.0/repositories/user/repo/refs/tags?pagelen=100&fields=values.name%2Cvalues.target.hash%2Cnext&sort=-target.date', + 'https://api.bitbucket.org/2.0/repositories/user/repo/refs/branches?pagelen=100&fields=values.name%2Cvalues.target.hash%2Cvalues.heads%2Cnext&sort=-target.date', + ]; + $this->httpDownloader->expects([ + ['url' => $urls[0], 'body' => '{"mainbranch": {"name": "main"}, "scm":"git","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/user\/repo.git","name":"https"},{"href":"ssh:\/\/git@bitbucket.org\/user\/repo.git","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/user\/repo"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}'], + ['url' => $urls[1], 'body' => '{"support": "' . $repoUrl . '"}'], + ['url' => $urls[2], 'body' => '{"date": "2016-05-17T13:19:52+00:00"}'], + ['url' => $urls[3], 'body' => '{"values":[{"name":"1.0.1","target":{"hash":"9b78a3932143497c519e49b8241083838c8ff8a1"}},{"name":"1.0.0","target":{"hash":"d3393d514318a9267d2f8ebbf463a9aaa389f8eb"}}]}'], + ['url' => $urls[4], 'body' => '{"values":[{"name":"main","target":{"hash":"937992d19d72b5116c3e8c4a04f960e5fa270b22"}}]}'], + ], true); + + $driver->getRootIdentifier(); + $data = $driver->getComposerInformation('main'); + + $this->assertIsArray($data); + $this->assertSame('https://bitbucket.org/user/repo/src/937992d19d72b5116c3e8c4a04f960e5fa270b22/?at=main', $data['support']['source']); + } + public function testSupports(): void { $this->assertTrue( diff --git a/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php b/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php index 68cf5e295..8431a1b49 100644 --- a/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php +++ b/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php @@ -199,6 +199,44 @@ class GitHubDriverTest extends TestCase $this->assertArrayNotHasKey('abandoned', $data); } + public function testInvalidSupportData(): void + { + $repoUrl = 'http://github.com/composer/packagist'; + $repoApiUrl = 'https://api.github.com/repos/composer/packagist'; + $identifier = 'feature/3.2-foo'; + $sha = 'SOMESHA'; + + $io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock(); + $io->expects($this->any()) + ->method('isInteractive') + ->will($this->returnValue(true)); + + $httpDownloader = $this->getHttpDownloaderMock($io, $this->config); + $httpDownloader->expects( + [ + ['url' => $repoApiUrl, 'body' => '{"master_branch": "test_master", "owner": {"login": "composer"}, "name": "packagist"}'], + ['url' => 'https://api.github.com/repos/composer/packagist/contents/composer.json?ref=feature%2F3.2-foo', 'body' => '{"encoding":"base64","content":"'.base64_encode('{"support": "'.$repoUrl.'" }').'"}'], + ['url' => 'https://api.github.com/repos/composer/packagist/commits/feature%2F3.2-foo', 'body' => '{"commit": {"committer":{ "date": "2012-09-10"}}}'], + ['url' => 'https://api.github.com/repos/composer/packagist/contents/.github/FUNDING.yml', 'body' => '{"encoding": "base64", "content": "'.base64_encode("custom: https://example.com").'"}'], + ], + true + ); + + $repoConfig = [ + 'url' => $repoUrl, + ]; + + $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $httpDownloader, $this->getProcessExecutorMock()); + $gitHubDriver->initialize(); + $this->setAttribute($gitHubDriver, 'tags', [$identifier => $sha]); + $this->setAttribute($gitHubDriver, 'branches', ['test_master' => $sha]); + + $data = $gitHubDriver->getComposerInformation($identifier); + + $this->assertIsArray($data); + $this->assertSame('https://github.com/composer/packagist/tree/feature/3.2-foo', $data['support']['source']); + } + public function testPublicRepositoryArchived(): void { $repoUrl = 'http://github.com/composer/packagist'; diff --git a/tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php b/tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php index 2f9dae2b9..9d163f567 100644 --- a/tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php +++ b/tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php @@ -244,6 +244,22 @@ JSON; $this->assertEquals($url, $driver->getUrl()); } + public function testInvalidSupportData(): void + { + $driver = $this->testInitialize($repoUrl = 'https://gitlab.com/mygroup/myproject', 'https://gitlab.com/api/v4/projects/mygroup%2Fmyproject'); + $this->setAttribute($driver, 'branches', ['main' => 'SOMESHA']); + $this->setAttribute($driver, 'tags', []); + + $this->httpDownloader->expects([ + ['url' => 'https://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/files/composer%2Ejson/raw?ref=SOMESHA', 'body' => '{"support": "'.$repoUrl.'" }'], + ], true); + + $data = $driver->getComposerInformation('main'); + + $this->assertIsArray($data); + $this->assertSame('https://gitlab.com/mygroup/myproject/-/tree/main', $data['support']['source']); + } + public function testGetDist(): void { $driver = $this->testInitialize('https://gitlab.com/mygroup/myproject', 'https://gitlab.com/api/v4/projects/mygroup%2Fmyproject'); @@ -631,4 +647,15 @@ JSON; $driver->initialize(); $this->assertEquals('https://gitlab.com/mygroup/myproject.git', $driver->getRepositoryUrl(), 'Repository URL matches config request for http not git'); } + + /** + * @param object $object + * @param mixed $value + */ + protected function setAttribute($object, string $attribute, $value): void + { + $attr = new \ReflectionProperty($object, $attribute); + $attr->setAccessible(true); + $attr->setValue($object, $value); + } } diff --git a/tests/Composer/Test/Util/RemoteFilesystemTest.php b/tests/Composer/Test/Util/RemoteFilesystemTest.php index 1dc2ceebe..a54e700a8 100644 --- a/tests/Composer/Test/Util/RemoteFilesystemTest.php +++ b/tests/Composer/Test/Util/RemoteFilesystemTest.php @@ -280,7 +280,6 @@ class RemoteFilesystemTest extends TestCase */ public function testBitBucketPublicDownload(string $url, string $contents): void { - /** @var ConsoleIO $io */ $io = $this ->getMockBuilder('Composer\IO\ConsoleIO') ->disableOriginalConstructor()