Forráskód Böngészése

Merge pull request #8085 from danepowell/issue-8065-2

Fixes #8065: Sort plugins deterministically before loading.
Jordi Boggiano 5 éve
szülő
commit
9d642fe9af

+ 4 - 62
src/Composer/Autoload/AutoloadGenerator.php

@@ -21,6 +21,7 @@ use Composer\Package\PackageInterface;
 use Composer\Repository\InstalledRepositoryInterface;
 use Composer\Util\Filesystem;
 use Composer\Script\ScriptEvents;
+use Composer\Util\PackageSorter;
 
 /**
  * @author Igor Wiedler <igor@wiedler.ch>
@@ -973,80 +974,21 @@ INITIALIZER;
     {
         $packages = array();
         $paths = array();
-        $usageList = array();
 
         foreach ($packageMap as $item) {
             list($package, $path) = $item;
             $name = $package->getName();
             $packages[$name] = $package;
             $paths[$name] = $path;
-
-            foreach (array_merge($package->getRequires(), $package->getDevRequires()) as $link) {
-                $target = $link->getTarget();
-                $usageList[$target][] = $name;
-            }
-        }
-
-        $computing = array();
-        $computed = array();
-        $computeImportance = function ($name) use (&$computeImportance, &$computing, &$computed, $usageList) {
-            // reusing computed importance
-            if (isset($computed[$name])) {
-                return $computed[$name];
-            }
-
-            // canceling circular dependency
-            if (isset($computing[$name])) {
-                return 0;
-            }
-
-            $computing[$name] = true;
-            $weight = 0;
-
-            if (isset($usageList[$name])) {
-                foreach ($usageList[$name] as $user) {
-                    $weight -= 1 - $computeImportance($user);
-                }
-            }
-
-            unset($computing[$name]);
-            $computed[$name] = $weight;
-
-            return $weight;
-        };
-
-        $weightList = array();
-
-        foreach ($packages as $name => $package) {
-            $weight = $computeImportance($name);
-            $weightList[$name] = $weight;
         }
 
-        $stable_sort = function (&$array) {
-            static $transform, $restore;
-
-            $i = 0;
+        $sortedPackages = PackageSorter::sortPackages($packages);
 
-            if (!$transform) {
-                $transform = function (&$v, $k) use (&$i) {
-                    $v = array($v, ++$i, $k, $v);
-                };
-
-                $restore = function (&$v, $k) {
-                    $v = $v[3];
-                };
-            }
-
-            array_walk($array, $transform);
-            asort($array);
-            array_walk($array, $restore);
-        };
-
-        $stable_sort($weightList);
 
         $sortedPackageMap = array();
 
-        foreach (array_keys($weightList) as $name) {
+        foreach ($sortedPackages as $package) {
+            $name = $package->getName();
             $sortedPackageMap[] = array($packages[$name], $paths[$name]);
         }
 

+ 6 - 3
src/Composer/Plugin/PluginManager.php

@@ -15,15 +15,16 @@ namespace Composer\Plugin;
 use Composer\Composer;
 use Composer\EventDispatcher\EventSubscriberInterface;
 use Composer\IO\IOInterface;
+use Composer\Package\CompletePackage;
 use Composer\Package\Package;
 use Composer\Package\Version\VersionParser;
 use Composer\Repository\RepositoryInterface;
-use Composer\Package\AliasPackage;
 use Composer\Package\PackageInterface;
 use Composer\Package\Link;
 use Composer\Semver\Constraint\Constraint;
 use Composer\DependencyResolver\Pool;
 use Composer\Plugin\Capability\Capability;
+use Composer\Util\PackageSorter;
 
 /**
  * Plugin manager
@@ -253,8 +254,10 @@ class PluginManager
      */
     private function loadRepository(RepositoryInterface $repo)
     {
-        foreach ($repo->getPackages() as $package) { /** @var PackageInterface $package */
-            if ($package instanceof AliasPackage) {
+        $packages = $repo->getPackages();
+        $sortedPackages = array_reverse(PackageSorter::sortPackages($packages));
+        foreach ($sortedPackages as $package) {
+            if (!($package instanceof CompletePackage)) {
                 continue;
             }
             if ('composer-plugin' === $package->getType()) {

+ 92 - 0
src/Composer/Util/PackageSorter.php

@@ -0,0 +1,92 @@
+<?php
+
+
+namespace Composer\Util;
+
+use Composer\Package\Link;
+use Composer\Package\PackageInterface;
+
+class PackageSorter
+{
+    /**
+     * Sorts packages by dependency weight
+     *
+     * Packages of equal weight retain the original order
+     *
+     * @param  array $packages
+     * @return array
+     */
+    public static function sortPackages(array $packages) {
+        $usageList = array();
+
+        foreach ($packages as $package) { /** @var PackageInterface $package */
+            foreach (array_merge($package->getRequires(), $package->getDevRequires()) as $link) { /** @var Link $link */
+                $target = $link->getTarget();
+                $usageList[$target][] = $package->getName();
+            }
+        }
+        $computing = array();
+        $computed = array();
+        $computeImportance = function ($name) use (&$computeImportance, &$computing, &$computed, $usageList) {
+            // reusing computed importance
+            if (isset($computed[$name])) {
+                return $computed[$name];
+            }
+
+            // canceling circular dependency
+            if (isset($computing[$name])) {
+                return 0;
+            }
+
+            $computing[$name] = true;
+            $weight = 0;
+
+            if (isset($usageList[$name])) {
+                foreach ($usageList[$name] as $user) {
+                    $weight -= 1 - $computeImportance($user);
+                }
+            }
+
+            unset($computing[$name]);
+            $computed[$name] = $weight;
+
+            return $weight;
+        };
+
+        $weightList = array();
+
+        foreach ($packages as $name => $package) {
+            $weight = $computeImportance($name);
+            $weightList[$name] = $weight;
+        }
+
+        $stable_sort = function (&$array) {
+            static $transform, $restore;
+
+            $i = 0;
+
+            if (!$transform) {
+                $transform = function (&$v, $k) use (&$i) {
+                    $v = array($v, ++$i, $k, $v);
+                };
+
+                $restore = function (&$v) {
+                    $v = $v[3];
+                };
+            }
+
+            array_walk($array, $transform);
+            asort($array);
+            array_walk($array, $restore);
+        };
+
+        $stable_sort($weightList);
+
+        $sortedPackages = array();
+
+        foreach (array_keys($weightList) as $name) {
+            $sortedPackages[] = $packages[$name];
+        }
+        return $sortedPackages;
+    }
+}