From 8fc09afbae6bc6cf4d7f70da5668cd00ddc7138b Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Tue, 15 May 2012 19:55:41 +0200 Subject: [PATCH] Move transaction generation to a separate class --- .../DependencyResolver/DefaultPolicy.php | 2 +- .../DependencyResolver/PolicyInterface.php | 2 +- src/Composer/DependencyResolver/Solver.php | 162 +---------------- .../DependencyResolver/Transaction.php | 169 ++++++++++++++++++ 4 files changed, 174 insertions(+), 161 deletions(-) create mode 100644 src/Composer/DependencyResolver/Transaction.php diff --git a/src/Composer/DependencyResolver/DefaultPolicy.php b/src/Composer/DependencyResolver/DefaultPolicy.php index ac3d38995..1fe22ff3c 100644 --- a/src/Composer/DependencyResolver/DefaultPolicy.php +++ b/src/Composer/DependencyResolver/DefaultPolicy.php @@ -30,7 +30,7 @@ class DefaultPolicy implements PolicyInterface return $constraint->matchSpecific($version); } - public function findUpdatePackages(Solver $solver, Pool $pool, array $installedMap, PackageInterface $package) + public function findUpdatePackages(Pool $pool, array $installedMap, PackageInterface $package) { $packages = array(); diff --git a/src/Composer/DependencyResolver/PolicyInterface.php b/src/Composer/DependencyResolver/PolicyInterface.php index 7c26ab63f..1f65c1bf9 100644 --- a/src/Composer/DependencyResolver/PolicyInterface.php +++ b/src/Composer/DependencyResolver/PolicyInterface.php @@ -21,7 +21,7 @@ use Composer\Package\PackageInterface; interface PolicyInterface { function versionCompare(PackageInterface $a, PackageInterface $b, $operator); - function findUpdatePackages(Solver $solver, Pool $pool, array $installedMap, PackageInterface $package); + function findUpdatePackages(Pool $pool, array $installedMap, PackageInterface $package); function installable(Solver $solver, Pool $pool, array $installedMap, PackageInterface $package); function selectPreferedPackages(Pool $pool, array $installedMap, array $literals); } diff --git a/src/Composer/DependencyResolver/Solver.php b/src/Composer/DependencyResolver/Solver.php index a03e27464..5a243a2ec 100644 --- a/src/Composer/DependencyResolver/Solver.php +++ b/src/Composer/DependencyResolver/Solver.php @@ -84,30 +84,6 @@ class Solver return new Rule($literals, $reason, $reasonData); } - /** - * Create a new rule for updating a package - * - * If package A1 can be updated to A2 or A3 the rule is (A1|A2|A3). - * - * @param PackageInterface $package The package to be updated - * @param array $updates An array of update candidate packages - * @param int $reason A RULE_* constant describing the - * reason for generating this rule - * @param mixed $reasonData Any data, e.g. the package name, that - * goes with the reason - * @return Rule The generated rule or null if tautology - */ - protected function createUpdateRule(PackageInterface $package, array $updates, $reason, $reasonData = null) - { - $literals = array(new Literal($package, true)); - - foreach ($updates as $update) { - $literals[] = new Literal($update, true); - } - - return new Rule($literals, $reason, $reasonData); - } - /** * Creates a new rule for installing a package * @@ -308,7 +284,7 @@ class Solver */ private function addRulesForUpdatePackages(PackageInterface $package) { - $updates = $this->policy->findUpdatePackages($this, $this->pool, $this->installedMap, $package); + $updates = $this->policy->findUpdatePackages($this->pool, $this->installedMap, $package); $this->addRulesForPackage($package); @@ -568,13 +544,6 @@ class Solver } } - foreach ($this->installedMap as $package) { - $updates = $this->policy->findUpdatePackages($this, $this->pool, $this->installedMap, $package); - $rule = $this->createUpdateRule($package, $updates, Rule::RULE_INTERNAL_ALLOW_UPDATE, (string) $package); - - $this->packageToUpdateRule[$package->getId()] = $rule; - } - foreach ($this->jobs as $job) { switch ($job['cmd']) { case 'install': @@ -627,133 +596,8 @@ class Solver throw new SolverProblemsException($this->problems); } - return $this->createTransaction(); - } - - protected function createTransaction() - { - $transaction = array(); - $installMeansUpdateMap = array(); - - foreach ($this->decisionQueue as $i => $literal) { - $package = $literal->getPackage(); - - // !wanted & installed - if (!$literal->isWanted() && isset($this->installedMap[$package->getId()])) { - $literals = array(); - - if (isset($this->packageToUpdateRule[$package->getId()])) { - $literals = array_merge($literals, $this->packageToUpdateRule[$package->getId()]->getLiterals()); - } - - foreach ($literals as $updateLiteral) { - if (!$updateLiteral->equals($literal)) { - $installMeansUpdateMap[$updateLiteral->getPackageId()] = $package; - } - } - } - } - - foreach ($this->decisionQueue as $i => $literal) { - $package = $literal->getPackage(); - - // wanted & installed || !wanted & !installed - if ($literal->isWanted() == (isset($this->installedMap[$package->getId()]))) { - continue; - } - - if ($literal->isWanted()) { - if ($package instanceof AliasPackage) { - $transaction[] = new Operation\MarkAliasInstalledOperation( - $package, $this->decisionQueueWhy[$i] - ); - continue; - } - - if (isset($installMeansUpdateMap[$literal->getPackageId()])) { - - $source = $installMeansUpdateMap[$literal->getPackageId()]; - - $transaction[] = new Operation\UpdateOperation( - $source, $package, $this->decisionQueueWhy[$i] - ); - - // avoid updates to one package from multiple origins - unset($installMeansUpdateMap[$literal->getPackageId()]); - $ignoreRemove[$source->getId()] = true; - } else { - $transaction[] = new Operation\InstallOperation( - $package, $this->decisionQueueWhy[$i] - ); - } - } else if (!isset($ignoreRemove[$package->getId()])) { - if ($package instanceof AliasPackage) { - $transaction[] = new Operation\MarkAliasInstalledOperation( - $package, $this->decisionQueueWhy[$i] - ); - } else { - $transaction[] = new Operation\UninstallOperation( - $package, $this->decisionQueueWhy[$i] - ); - } - } - } - - $allDecidedMap = $this->decisionMap; - foreach ($this->decisionMap as $packageId => $decision) { - if ($decision != 0) { - $package = $this->pool->packageById($packageId); - if ($package instanceof AliasPackage) { - $allDecidedMap[$package->getAliasOf()->getId()] = $decision; - } - } - } - - foreach ($allDecidedMap as $packageId => $decision) { - if ($packageId === 0) { - continue; - } - - if (0 == $decision && isset($this->installedMap[$packageId])) { - $package = $this->pool->packageById($packageId); - - if ($package instanceof AliasPackage) { - $transaction[] = new Operation\MarkAliasInstalledOperation( - $package, null - ); - } else { - $transaction[] = new Operation\UninstallOperation( - $package, null - ); - } - - $this->decisionMap[$packageId] = -1; - } - } - - foreach ($this->decisionMap as $packageId => $decision) { - if ($packageId === 0) { - continue; - } - - if (0 == $decision && isset($this->installedMap[$packageId])) { - $package = $this->pool->packageById($packageId); - - if ($package instanceof AliasPackage) { - $transaction[] = new Operation\MarkAliasInstalledOperation( - $package, null - ); - } else { - $transaction[] = new Operation\UninstallOperation( - $package, null - ); - } - - $this->decisionMap[$packageId] = -1; - } - } - - return array_reverse($transaction); + $transaction = new Transaction($this->policy, $this->pool, $this->installedMap, $this->decisionMap, $this->decisionQueue, $this->decisionQueueWhy); + return $transaction->getOperations(); } protected function literalFromId($id) diff --git a/src/Composer/DependencyResolver/Transaction.php b/src/Composer/DependencyResolver/Transaction.php new file mode 100644 index 000000000..14fe11836 --- /dev/null +++ b/src/Composer/DependencyResolver/Transaction.php @@ -0,0 +1,169 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\DependencyResolver; + +use Composer\Repository\RepositoryInterface; +use Composer\Package\PackageInterface; +use Composer\Package\AliasPackage; +use Composer\DependencyResolver\Operation; + +/** + * @author Nils Adermann + */ +class Transaction +{ + protected $policy; + protected $pool; + protected $installedMap; + protected $decisionMap; + protected $decisionQueue; + protected $decisionQueueWhy; + + public function __construct($policy, $pool, $installedMap, $decisionMap, array $decisionQueue, $decisionQueueWhy) + { + $this->policy = $policy; + $this->pool = $pool; + $this->installedMap = $installedMap; + $this->decisionMap = $decisionMap; + $this->decisionQueue = $decisionQueue; + $this->decisionQueueWhy = $decisionQueueWhy; + } + + public function getOperations() + { + $transaction = array(); + $installMeansUpdateMap = array(); + + foreach ($this->decisionQueue as $i => $literal) { + $package = $literal->getPackage(); + + // !wanted & installed + if (!$literal->isWanted() && isset($this->installedMap[$package->getId()])) { + $updates = $this->policy->findUpdatePackages($this->pool, $this->installedMap, $package); + + $literals = array(new Literal($package, true)); + + foreach ($updates as $update) { + $literals[] = new Literal($update, true); + } + + foreach ($literals as $updateLiteral) { + if (!$updateLiteral->equals($literal)) { + $installMeansUpdateMap[$updateLiteral->getPackageId()] = $package; + } + } + } + } + + foreach ($this->decisionQueue as $i => $literal) { + $package = $literal->getPackage(); + + // wanted & installed || !wanted & !installed + if ($literal->isWanted() == (isset($this->installedMap[$package->getId()]))) { + continue; + } + + if ($literal->isWanted()) { + if ($package instanceof AliasPackage) { + $transaction[] = new Operation\MarkAliasInstalledOperation( + $package, $this->decisionQueueWhy[$i] + ); + continue; + } + + if (isset($installMeansUpdateMap[$literal->getPackageId()])) { + + $source = $installMeansUpdateMap[$literal->getPackageId()]; + + $transaction[] = new Operation\UpdateOperation( + $source, $package, $this->decisionQueueWhy[$i] + ); + + // avoid updates to one package from multiple origins + unset($installMeansUpdateMap[$literal->getPackageId()]); + $ignoreRemove[$source->getId()] = true; + } else { + $transaction[] = new Operation\InstallOperation( + $package, $this->decisionQueueWhy[$i] + ); + } + } else if (!isset($ignoreRemove[$package->getId()])) { + if ($package instanceof AliasPackage) { + $transaction[] = new Operation\MarkAliasInstalledOperation( + $package, $this->decisionQueueWhy[$i] + ); + } else { + $transaction[] = new Operation\UninstallOperation( + $package, $this->decisionQueueWhy[$i] + ); + } + } + } + + $allDecidedMap = $this->decisionMap; + foreach ($this->decisionMap as $packageId => $decision) { + if ($decision != 0) { + $package = $this->pool->packageById($packageId); + if ($package instanceof AliasPackage) { + $allDecidedMap[$package->getAliasOf()->getId()] = $decision; + } + } + } + + foreach ($allDecidedMap as $packageId => $decision) { + if ($packageId === 0) { + continue; + } + + if (0 == $decision && isset($this->installedMap[$packageId])) { + $package = $this->pool->packageById($packageId); + + if ($package instanceof AliasPackage) { + $transaction[] = new Operation\MarkAliasInstalledOperation( + $package, null + ); + } else { + $transaction[] = new Operation\UninstallOperation( + $package, null + ); + } + + $this->decisionMap[$packageId] = -1; + } + } + + foreach ($this->decisionMap as $packageId => $decision) { + if ($packageId === 0) { + continue; + } + + if (0 == $decision && isset($this->installedMap[$packageId])) { + $package = $this->pool->packageById($packageId); + + if ($package instanceof AliasPackage) { + $transaction[] = new Operation\MarkAliasInstalledOperation( + $package, null + ); + } else { + $transaction[] = new Operation\UninstallOperation( + $package, null + ); + } + + $this->decisionMap[$packageId] = -1; + } + } + + return array_reverse($transaction); + } +}