22
33namespace staabm \PHPStanTodoBy ;
44
5- use Composer \InstalledVersions ;
6- use Composer \Semver \Comparator ;
5+ use OutOfBoundsException ;
76use Composer \Semver \VersionParser ;
87use PhpParser \Comment ;
98use PhpParser \Node ;
@@ -61,6 +60,11 @@ final class TodoByPackageVersionRule implements Rule
6160 */
6261 private array $ virtualPackages ;
6362
63+ /**
64+ * @var array{versions: array<string, array{version: string, pretty_version?: string}>}
65+ */
66+ private array $ installedVersions ;
67+
6468 /**
6569 * @param array<string, string> $virtualPackages
6670 */
@@ -74,9 +78,9 @@ public function __construct(
7478 $ this ->errorBuilder = $ errorBuilder ;
7579
7680 // require the top level installed versions, so we don't mix it up with the one in phpstan.phar
77- $ installedVersions = $ this ->workingDirectory . '/vendor/composer/InstalledVersions .php ' ;
78- if (! class_exists (InstalledVersions::class, false ) && is_readable ($ installedVersions )) {
79- require_once $ installedVersions ;
81+ $ installedVersions = $ this ->workingDirectory . '/vendor/composer/installed .php ' ;
82+ if (is_readable ($ installedVersions )) {
83+ $ this -> installedVersions = require $ installedVersions ;
8084 }
8185 }
8286
@@ -261,7 +265,7 @@ private function satisfiesInstalledPackage(string $package, string $version, Com
261265 $ versionParser = new VersionParser ();
262266
263267 // see https://getcomposer.org/doc/07-runtime.md#installed-versions
264- if (!InstalledVersions:: isInstalled ( $ package )) {
268+ if (!isset ( $ this -> installedVersions [ ' versions ' ][ $ package] )) {
265269 return $ this ->errorBuilder ->buildError (
266270 $ comment ->getText (),
267271 $ comment ->getStartLine (),
@@ -273,7 +277,10 @@ private function satisfiesInstalledPackage(string $package, string $version, Com
273277 }
274278
275279 try {
276- return InstalledVersions::satisfies ($ versionParser , $ package , $ version );
280+ $ constraint = $ versionParser ->parseConstraints ($ version );
281+ $ provided = $ versionParser ->parseConstraints ($ this ->getVersionRanges ($ package ));
282+
283+ return $ provided ->matches ($ constraint );
277284 } catch (UnexpectedValueException $ e ) {
278285 return $ this ->errorBuilder ->buildError (
279286 $ comment ->getText (),
@@ -298,4 +305,27 @@ private function getVersionComparator(string $version): ?string
298305
299306 return $ comparator ;
300307 }
308+
309+ public function getVersionRanges (string $ packageName ) : string
310+ {
311+ if (!isset ($ this ->installedVersions ['versions ' ][$ packageName ])) {
312+ throw new OutOfBoundsException ('Package " ' . $ packageName . '" is not installed ' );
313+ }
314+
315+ $ ranges = array ();
316+ if (isset ($ this ->installedVersions ['versions ' ][$ packageName ]['pretty_version ' ])) {
317+ $ ranges [] = $ this ->installedVersions ['versions ' ][$ packageName ]['pretty_version ' ];
318+ }
319+ if (array_key_exists ('aliases ' , $ this ->installedVersions ['versions ' ][$ packageName ])) {
320+ $ ranges = array_merge ($ ranges , $ this ->installedVersions ['versions ' ][$ packageName ]['aliases ' ]);
321+ }
322+ if (array_key_exists ('replaced ' , $ this ->installedVersions ['versions ' ][$ packageName ])) {
323+ $ ranges = array_merge ($ ranges , $ this ->installedVersions ['versions ' ][$ packageName ]['replaced ' ]);
324+ }
325+ if (array_key_exists ('provided ' , $ this ->installedVersions ['versions ' ][$ packageName ])) {
326+ $ ranges = array_merge ($ ranges , $ this ->installedVersions ['versions ' ][$ packageName ]['provided ' ]);
327+ }
328+
329+ return implode (' || ' , $ ranges );
330+ }
301331}
0 commit comments