From 51e6c3a4665fd2894ba6b9ec466c1fed9961be07 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 13 Oct 2013 23:01:26 -0300 Subject: [PATCH] Optimize solving by removing packages that are excluded by the root package requires --- src/Composer/DependencyResolver/Pool.php | 38 ++++++++++++++++++------ src/Composer/Installer.php | 17 ++++++++--- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/Composer/DependencyResolver/Pool.php b/src/Composer/DependencyResolver/Pool.php index 96198f4d6..a1bba4f3a 100644 --- a/src/Composer/DependencyResolver/Pool.php +++ b/src/Composer/DependencyResolver/Pool.php @@ -18,6 +18,7 @@ use Composer\Package\Version\VersionParser; use Composer\Package\Link; use Composer\Package\LinkConstraint\LinkConstraintInterface; use Composer\Package\LinkConstraint\VersionConstraint; +use Composer\Package\LinkConstraint\EmptyConstraint; use Composer\Repository\RepositoryInterface; use Composer\Repository\CompositeRepository; use Composer\Repository\ComposerRepository; @@ -38,6 +39,7 @@ class Pool const MATCH = 1; const MATCH_PROVIDE = 2; const MATCH_REPLACE = 3; + const MATCH_FILTERED = 4; protected $repositories = array(); protected $providerRepos = array(); @@ -47,9 +49,10 @@ class Pool protected $stabilityFlags; protected $versionParser; protected $providerCache = array(); + protected $filterRequires; protected $id = 1; - public function __construct($minimumStability = 'stable', array $stabilityFlags = array()) + public function __construct($minimumStability = 'stable', array $stabilityFlags = array(), array $filterRequires = array()) { $stabilities = BasePackage::$stabilities; $this->versionParser = new VersionParser; @@ -60,6 +63,7 @@ class Pool } } $this->stabilityFlags = $stabilityFlags; + $this->filterRequires = $filterRequires; } /** @@ -109,6 +113,7 @@ class Pool if ($exempt || $this->isPackageAcceptable($names, $stability)) { $package['id'] = $this->id++; + $package['stability'] = $stability; $this->packages[] = $package; foreach ($names as $provided) { @@ -275,6 +280,9 @@ class Pool $matches[] = $this->ensurePackageIsLoaded($candidate); break; + case self::MATCH_FILTERED: + break; + default: throw new \UnexpectedValueException('Unexpected match type'); } @@ -367,18 +375,30 @@ class Pool if (is_array($candidate)) { $candidateName = $candidate['name']; $candidateVersion = $candidate['version']; + $isDev = $candidate['stability'] === 'dev'; + $isAlias = isset($candidate['alias_of']); } else { // handle object packages $candidateName = $candidate->getName(); $candidateVersion = $candidate->getVersion(); + $isDev = $candidate->getStability() === 'dev'; + $isAlias = $candidate instanceof AliasPackage; + } + + if (!$isDev && !$isAlias && isset($this->filterRequires[$name])) { + $requireFilter = $this->filterRequires[$name]; + } else { + $requireFilter = new EmptyConstraint; } if ($candidateName === $name) { - if ($constraint === null) { - return self::MATCH; + $pkgConstraint = new VersionConstraint('==', $candidateVersion); + + if ($constraint === null || $constraint->matches($pkgConstraint)) { + return $requireFilter->matches($pkgConstraint) ? self::MATCH : self::MATCH_FILTERED; } - return $constraint->matches(new VersionConstraint('==', $candidateVersion)) ? self::MATCH : self::MATCH_NAME; + return self::MATCH_NAME; } if (is_array($candidate)) { @@ -393,17 +413,17 @@ class Pool $replaces = $candidate->getReplaces(); } - // aliases create multiple replaces/provides for one target so they can not use the shortcut + // aliases create multiple replaces/provides for one target so they can not use the shortcut below if (isset($replaces[0]) || isset($provides[0])) { foreach ($provides as $link) { if ($link->getTarget() === $name && ($constraint === null || $constraint->matches($link->getConstraint()))) { - return self::MATCH_PROVIDE; + return $requireFilter->matches($link->getConstraint()) ? self::MATCH_PROVIDE : self::MATCH_FILTERED; } } foreach ($replaces as $link) { if ($link->getTarget() === $name && ($constraint === null || $constraint->matches($link->getConstraint()))) { - return self::MATCH_REPLACE; + return $requireFilter->matches($link->getConstraint()) ? self::MATCH_REPLACE : self::MATCH_FILTERED; } } @@ -411,11 +431,11 @@ class Pool } if (isset($provides[$name]) && ($constraint === null || $constraint->matches($provides[$name]->getConstraint()))) { - return self::MATCH_PROVIDE; + return $requireFilter->matches($provides[$name]->getConstraint()) ? self::MATCH_PROVIDE : self::MATCH_FILTERED; } if (isset($replaces[$name]) && ($constraint === null || $constraint->matches($replaces[$name]->getConstraint()))) { - return self::MATCH_REPLACE; + return $requireFilter->matches($replaces[$name]->getConstraint()) ? self::MATCH_REPLACE : self::MATCH_FILTERED; } return self::MATCH_NONE; diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index 2bbcefe7d..900c14b6b 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -242,7 +242,7 @@ class Installer // split dev and non-dev requirements by checking what would be removed if we update without the dev requirements if ($this->devMode && $this->package->getDevRequires()) { $policy = $this->createPolicy(); - $pool = $this->createPool(); + $pool = $this->createPool(true); $pool->addRepository($installedRepo, $aliases); // creating requirements request @@ -325,7 +325,7 @@ class Installer // creating repository pool $policy = $this->createPolicy(); - $pool = $this->createPool(); + $pool = $this->createPool($withDevReqs); $pool->addRepository($installedRepo, $aliases); if ($installFromLock) { $pool->addRepository($lockedRepository, $aliases); @@ -573,7 +573,7 @@ class Installer return array_merge($installerOps, $operations); } - private function createPool() + private function createPool($withDevReqs) { $minimumStability = $this->package->getMinimumStability(); $stabilityFlags = $this->package->getStabilityFlags(); @@ -583,7 +583,16 @@ class Installer $stabilityFlags = $this->locker->getStabilityFlags(); } - return new Pool($minimumStability, $stabilityFlags); + $requires = $this->package->getRequires(); + if ($withDevReqs) { + $requires = array_merge($requires, $this->package->getDevRequires()); + } + $rootConstraints = array(); + foreach ($requires as $req => $constraint) { + $rootConstraints[$req] = $constraint->getConstraint(); + } + + return new Pool($minimumStability, $stabilityFlags, $rootConstraints); } private function createPolicy()