diff --git a/src/Composer/DependencyResolver/Pool.php b/src/Composer/DependencyResolver/Pool.php index 35feafde8..355ba25d4 100644 --- a/src/Composer/DependencyResolver/Pool.php +++ b/src/Composer/DependencyResolver/Pool.php @@ -58,12 +58,12 @@ class Pool implements \Countable public function setPackages(array $packages, array $priorities = array()) { - $this->priorities = $priorities; - $this->packages = $packages; - $id = 1; - foreach ($this->packages as $package) { + foreach ($packages as $i => $package) { + $this->packages[] = $package; + $this->priorities[] = isset($priorities[$i]) ? $priorities[$i] : 0; + $package->id = $id++; $names = $package->getNames(); $this->packageByExactName[$package->getName()][$package->id] = $package; diff --git a/src/Composer/DependencyResolver/PoolBuilder.php b/src/Composer/DependencyResolver/PoolBuilder.php index 2fd3c8230..8ab6e5244 100644 --- a/src/Composer/DependencyResolver/PoolBuilder.php +++ b/src/Composer/DependencyResolver/PoolBuilder.php @@ -20,6 +20,8 @@ use Composer\Repository\ComposerRepository; use Composer\Repository\InstalledRepositoryInterface; use Composer\Repository\LockArrayRepository; use Composer\Repository\PlatformRepository; +use Composer\Semver\Constraint\Constraint; +use Composer\Semver\Constraint\MultiConstraint; /** * @author Nils Adermann @@ -30,6 +32,9 @@ class PoolBuilder private $filterRequires; private $rootAliases; + private $aliasMap = array(); + private $nameConstraints = array(); + private $loadedNames = array(); private $packages = array(); @@ -52,6 +57,7 @@ class PoolBuilder switch ($job['cmd']) { case 'install': $loadNames[$job['packageName']] = $job['constraint']; + $this->nameConstraints[$job['packageName']] = $job['constraint'] ? new MultiConstraint(array($job['constraint']), false) : null; break; } } @@ -92,6 +98,32 @@ class PoolBuilder $loadNames = $newLoadNames; } + foreach ($this->packages as $i => $package) { + // we check all alias related packages at once, so no need ot check individual aliases + // isset also checks non-null value + if (!$package instanceof AliasPackage && isset($this->nameConstraints[$package->getName()])) { + $constraint = $this->nameConstraints[$package->getName()]; + + $aliasedPackages = array($i => $package); + if (isset($this->aliasMap[spl_object_hash($package)])) { + $aliasedPackages += $this->aliasMap[spl_object_hash($package)]; + } + + $found = false; + foreach ($aliasedPackages as $packageOrAlias) { + if ($constraint->matches(new Constraint('==', $packageOrAlias->getVersion()))) { + $found = true; + } + } + if (!$found) { + foreach ($aliasedPackages as $index => $packageOrAlias) { + unset($this->packages[$index]); + unset($this->priorities[$index]); + } + } + } + } + foreach ($repositories as $key => $repository) { if ($repository instanceof PlatformRepository || $repository instanceof InstalledRepositoryInterface) { @@ -103,26 +135,39 @@ class PoolBuilder $this->pool->setPackages($this->packages, $this->priorities); + unset($this->aliasMap); + unset($this->loadedNames); + unset($this->nameConstraints); + return $this->pool; } private function loadPackage(PackageInterface $package, $repoIndex) { + $index = count($this->packages); $this->packages[] = $package; $this->priorities[] = -$repoIndex; + if ($package instanceof AliasPackage) { + $this->aliasMap[spl_object_hash($package->getAliasOf())][$index] = $package; + } + // handle root package aliases $name = $package->getName(); if (isset($this->rootAliases[$name][$package->getVersion()])) { $alias = $this->rootAliases[$name][$package->getVersion()]; if ($package instanceof AliasPackage) { - $package = $package->getAliasOf(); + $basePackage = $package->getAliasOf(); + } else { + $basePackage = $package; } - $aliasPackage = new AliasPackage($package, $alias['alias_normalized'], $alias['alias']); + $aliasPackage = new AliasPackage($basePackage, $alias['alias_normalized'], $alias['alias']); $aliasPackage->setRootPackageAlias(true); $package->getRepository()->addPackage($aliasPackage); // TODO do we need this? $this->packages[] = $aliasPackage; + $this->priorities[] = -$repoIndex; + $this->aliasMap[spl_object_hash($aliasPackage->getAliasOf())][$index+1] = $aliasPackage; } $loadNames = array(); @@ -131,6 +176,16 @@ class PoolBuilder if (!isset($this->loadedNames[$require])) { $loadNames[$require] = null; } + if ($link->getConstraint()) { + if (!array_key_exists($require, $this->nameConstraints)) { + $this->nameConstraints[$require] = new MultiConstraint(array($link->getConstraint()), false); + } elseif ($this->nameConstraints[$require]) { + // TODO addConstraint function? + $this->nameConstraints[$require] = new MultiConstraint(array_merge(array($link->getConstraint()), $this->nameConstraints[$require]->getConstraints()), false); + } + } else { + $this->nameConstraints[$require] = null; + } } return $loadNames;