diff --git a/src/TodoByPackageVersionRule.php b/src/TodoByPackageVersionRule.php index 3711fa3..9802044 100644 --- a/src/TodoByPackageVersionRule.php +++ b/src/TodoByPackageVersionRule.php @@ -2,8 +2,7 @@ namespace staabm\PHPStanTodoBy; -use Composer\InstalledVersions; -use Composer\Semver\Comparator; +use OutOfBoundsException; use Composer\Semver\VersionParser; use PhpParser\Comment; use PhpParser\Node; @@ -61,6 +60,11 @@ final class TodoByPackageVersionRule implements Rule */ private array $virtualPackages; + /** + * @var array{versions: array} + */ + private array $installedVersions; + /** * @param array $virtualPackages */ @@ -74,9 +78,9 @@ public function __construct( $this->errorBuilder = $errorBuilder; // require the top level installed versions, so we don't mix it up with the one in phpstan.phar - $installedVersions = $this->workingDirectory . '/vendor/composer/InstalledVersions.php'; - if (!class_exists(InstalledVersions::class, false) && is_readable($installedVersions)) { - require_once $installedVersions; + $installedVersions = $this->workingDirectory . '/vendor/composer/installed.php'; + if (is_readable($installedVersions)) { + $this->installedVersions = require $installedVersions; } } @@ -261,7 +265,7 @@ private function satisfiesInstalledPackage(string $package, string $version, Com $versionParser = new VersionParser(); // see https://getcomposer.org/doc/07-runtime.md#installed-versions - if (!InstalledVersions::isInstalled($package)) { + if (!isset($this->installedVersions['versions'][$package])) { return $this->errorBuilder->buildError( $comment->getText(), $comment->getStartLine(), @@ -273,7 +277,10 @@ private function satisfiesInstalledPackage(string $package, string $version, Com } try { - return InstalledVersions::satisfies($versionParser, $package, $version); + $constraint = $versionParser->parseConstraints($version); + $provided = $versionParser->parseConstraints($this->getVersionRanges($package)); + + return $provided->matches($constraint); } catch (UnexpectedValueException $e) { return $this->errorBuilder->buildError( $comment->getText(), @@ -298,4 +305,27 @@ private function getVersionComparator(string $version): ?string return $comparator; } + + public function getVersionRanges(string $packageName) : string + { + if (!isset($this->installedVersions['versions'][$packageName])) { + throw new OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + $ranges = array(); + if (isset($this->installedVersions['versions'][$packageName]['pretty_version'])) { + $ranges[] = $this->installedVersions['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $this->installedVersions['versions'][$packageName])) { + $ranges = array_merge($ranges, $this->installedVersions['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $this->installedVersions['versions'][$packageName])) { + $ranges = array_merge($ranges, $this->installedVersions['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $this->installedVersions['versions'][$packageName])) { + $ranges = array_merge($ranges, $this->installedVersions['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } } diff --git a/tests/TodoByPackageVersionRuleTest.php b/tests/TodoByPackageVersionRuleTest.php index 034fcf3..950de95 100644 --- a/tests/TodoByPackageVersionRuleTest.php +++ b/tests/TodoByPackageVersionRuleTest.php @@ -57,37 +57,33 @@ public static function provideErrors(): iterable 'Unknown package "not-installed/package". It is neither installed via composer.json nor declared as virtual package via PHPStan config.', 11, ], - [ - '"phpunit/phpunit" version requirement "<10" satisfied.', - 14, - ], [ '"phpunit/phpunit" version requirement "<11" satisfied.', - 15, + 14, ], [ 'Invalid version constraint "7.3" satisfied: drop this code after min-version raise.', - 19, + 18, ], [ '"php" version requirement ">=7" satisfied: drop this code after min-version raise.', - 20, + 19, ], [ '"php" version requirement ">=7" satisfied.', - 22, + 21, ], [ '"php" version requirement ">=7" satisfied.', - 23, + 22, ], [ '"php" version requirement ">=7" satisfied.', - 24, + 23, ], ], ]; diff --git a/tests/data/packageVersion.php b/tests/data/packageVersion.php index aad9718..b3bb0ad 100644 --- a/tests/data/packageVersion.php +++ b/tests/data/packageVersion.php @@ -11,7 +11,6 @@ // TODO: not-installed/package:<5 this should error because package is not in composer.json // TODO: phpunit/phpunit:<9 -// TODO: phpunit/phpunit:<10 // TODO: phpunit/phpunit:<11 // TODO: phpunit/phpunit: