@@ -32,6 +32,11 @@ class InstalledVersions
3232 */
3333 private static $ installed ;
3434
35+ /**
36+ * @var bool
37+ */
38+ private static $ installedIsLocalDir ;
39+
3540 /**
3641 * @var bool|null
3742 */
@@ -309,6 +314,12 @@ public static function reload($data)
309314 {
310315 self ::$ installed = $ data ;
311316 self ::$ installedByVendor = array ();
317+
318+ // when using reload, we disable the duplicate protection to ensure that self::$installed data is
319+ // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
320+ // so we have to assume it does not, and that may result in duplicate data being returned when listing
321+ // all installed packages for example
322+ self ::$ installedIsLocalDir = false ;
312323 }
313324
314325 /**
@@ -322,19 +333,27 @@ private static function getInstalled()
322333 }
323334
324335 $ installed = array ();
336+ $ copiedLocalDir = false ;
325337
326338 if (self ::$ canGetVendors ) {
339+ $ selfDir = strtr (__DIR__ , '\\' , '/ ' );
327340 foreach (ClassLoader::getRegisteredLoaders () as $ vendorDir => $ loader ) {
341+ $ vendorDir = strtr ($ vendorDir , '\\' , '/ ' );
328342 if (isset (self ::$ installedByVendor [$ vendorDir ])) {
329343 $ installed [] = self ::$ installedByVendor [$ vendorDir ];
330344 } elseif (is_file ($ vendorDir .'/composer/installed.php ' )) {
331345 /** @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 */
332346 $ required = require $ vendorDir .'/composer/installed.php ' ;
333- $ installed [] = self ::$ installedByVendor [$ vendorDir ] = $ required ;
334- if (null === self ::$ installed && strtr ($ vendorDir .'/composer ' , '\\' , '/ ' ) === strtr (__DIR__ , '\\' , '/ ' )) {
335- self ::$ installed = $ installed [count ($ installed ) - 1 ];
347+ self ::$ installedByVendor [$ vendorDir ] = $ required ;
348+ $ installed [] = $ required ;
349+ if (self ::$ installed === null && $ vendorDir .'/composer ' === $ selfDir ) {
350+ self ::$ installed = $ required ;
351+ self ::$ installedIsLocalDir = true ;
336352 }
337353 }
354+ if (self ::$ installedIsLocalDir && $ vendorDir .'/composer ' === $ selfDir ) {
355+ $ copiedLocalDir = true ;
356+ }
338357 }
339358 }
340359
@@ -350,7 +369,7 @@ private static function getInstalled()
350369 }
351370 }
352371
353- if (self ::$ installed !== array ()) {
372+ if (self ::$ installed !== array () && ! $ copiedLocalDir ) {
354373 $ installed [] = self ::$ installed ;
355374 }
356375
0 commit comments