diff --git a/src/Composer/Autoload/AutoloadGenerator.php b/src/Composer/Autoload/AutoloadGenerator.php index 4d04f7a2f..d970ca5b1 100644 --- a/src/Composer/Autoload/AutoloadGenerator.php +++ b/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 @@ -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]; - } + $sortedPackages = PackageSorter::sortPackages($packages); - // 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, $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]); } diff --git a/src/Composer/Plugin/PluginManager.php b/src/Composer/Plugin/PluginManager.php index e8f4b58c3..bb9b66d83 100644 --- a/src/Composer/Plugin/PluginManager.php +++ b/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()) { diff --git a/src/Composer/Util/PackageSorter.php b/src/Composer/Util/PackageSorter.php new file mode 100644 index 000000000..8d8c9a06c --- /dev/null +++ b/src/Composer/Util/PackageSorter.php @@ -0,0 +1,92 @@ +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; + } +}