| @@ -8,12 +8,12 @@ | ||
| 8 | 8 | * |
| 9 | 9 | * For the full copyright and license information, please view the LICENSE |
| 10 | 10 | * file that was distributed with this source code. |
| 11 | 11 | */ |
| 12 | -namespace WindPressPackages\Composer; | |
| 12 | +namespace WindPressDeps\Composer; | |
| 13 | 13 | |
| 14 | -use WindPressPackages\Composer\Autoload\ClassLoader; | |
| 15 | -use WindPressPackages\Composer\Semver\VersionParser; | |
| 14 | +use WindPressDeps\Composer\Autoload\ClassLoader; | |
| 15 | +use WindPressDeps\Composer\Semver\VersionParser; | |
| 16 | 16 | /** |
| 17 | 17 | * This class is copied in every Composer installed project and available to all |
| 18 | 18 | * |
| 19 | 19 | * See also https://getcomposer.org/doc/07-runtime.md#installed-versions |
| @@ -24,13 +24,22 @@ | ||
| 24 | 24 | */ |
| 25 | 25 | class InstalledVersions |
| 26 | 26 | { |
| 27 | 27 | /** |
| 28 | + * @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to | |
| 29 | + * @internal | |
| 30 | + */ | |
| 31 | + private static $selfDir = null; | |
| 32 | + /** | |
| 28 | 33 | * @var mixed[]|null |
| 29 | 34 | * @psalm-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<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null |
| 30 | 35 | */ |
| 31 | 36 | private static $installed; |
| 32 | 37 | /** |
| 38 | + * @var bool | |
| 39 | + */ | |
| 40 | + private static $installedIsLocalDir; | |
| 41 | + /** | |
| 33 | 42 | * @var bool|null |
| 34 | 43 | */ |
| 35 | 44 | private static $canGetVendors; |
| 36 | 45 | /** |
| @@ -268,10 +277,25 @@ | ||
| 268 | 277 | public static function reload($data) |
| 269 | 278 | { |
| 270 | 279 | self::$installed = $data; |
| 271 | 280 | self::$installedByVendor = array(); |
| 281 | + // when using reload, we disable the duplicate protection to ensure that self::$installed data is | |
| 282 | + // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not, | |
| 283 | + // so we have to assume it does not, and that may result in duplicate data being returned when listing | |
| 284 | + // all installed packages for example | |
| 285 | + self::$installedIsLocalDir = \false; | |
| 272 | 286 | } |
| 273 | 287 | /** |
| 288 | + * @return string | |
| 289 | + */ | |
| 290 | + private static function getSelfDir() | |
| 291 | + { | |
| 292 | + if (self::$selfDir === null) { | |
| 293 | + self::$selfDir = strtr(__DIR__, '\\', '/'); | |
| 294 | + } | |
| 295 | + return self::$selfDir; | |
| 296 | + } | |
| 297 | + /** | |
| 274 | 298 | * @return array[] |
| 275 | 299 | * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}> |
| 276 | 300 | */ |
| 277 | 301 | private static function getInstalled() |
| @@ -276,23 +300,31 @@ | ||
| 276 | 300 | */ |
| 277 | 301 | private static function getInstalled() |
| 278 | 302 | { |
| 279 | 303 | if (null === self::$canGetVendors) { |
| 280 | - self::$canGetVendors = method_exists('WindPressPackages\Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); | |
| 304 | + self::$canGetVendors = method_exists('WindPressDeps\Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); | |
| 281 | 305 | } |
| 282 | 306 | $installed = array(); |
| 307 | + $copiedLocalDir = \false; | |
| 283 | 308 | if (self::$canGetVendors) { |
| 309 | + $selfDir = self::getSelfDir(); | |
| 284 | 310 | foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { |
| 311 | + $vendorDir = strtr($vendorDir, '\\', '/'); | |
| 285 | 312 | if (isset(self::$installedByVendor[$vendorDir])) { |
| 286 | 313 | $installed[] = self::$installedByVendor[$vendorDir]; |
| 287 | 314 | } elseif (is_file($vendorDir . '/composer/installed.php')) { |
| 288 | 315 | /** @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<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */ |
| 289 | 316 | $required = require $vendorDir . '/composer/installed.php'; |
| 290 | - $installed[] = self::$installedByVendor[$vendorDir] = $required; | |
| 291 | - if (null === self::$installed && strtr($vendorDir . '/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { | |
| 292 | - self::$installed = $installed[count($installed) - 1]; | |
| 317 | + self::$installedByVendor[$vendorDir] = $required; | |
| 318 | + $installed[] = $required; | |
| 319 | + if (self::$installed === null && $vendorDir . '/composer' === $selfDir) { | |
| 320 | + self::$installed = $required; | |
| 321 | + self::$installedIsLocalDir = \true; | |
| 293 | 322 | } |
| 294 | 323 | } |
| 324 | + if (self::$installedIsLocalDir && $vendorDir . '/composer' === $selfDir) { | |
| 325 | + $copiedLocalDir = \true; | |
| 326 | + } | |
| 295 | 327 | } |
| 296 | 328 | } |
| 297 | 329 | if (null === self::$installed) { |
| 298 | 330 | // only require the installed.php file if this file is loaded from its dumped location, |
| @@ -304,9 +336,9 @@ | ||
| 304 | 336 | } else { |
| 305 | 337 | self::$installed = array(); |
| 306 | 338 | } |
| 307 | 339 | } |
| 308 | - if (self::$installed !== array()) { | |
| 340 | + if (self::$installed !== array() && !$copiedLocalDir) { | |
| 309 | 341 | $installed[] = self::$installed; |
| 310 | 342 | } |
| 311 | 343 | return $installed; |
| 312 | 344 | } |