diff --git a/src/Composer/DependencyResolver/Solver.php b/src/Composer/DependencyResolver/Solver.php index 9edba67ca..97fa67299 100644 --- a/src/Composer/DependencyResolver/Solver.php +++ b/src/Composer/DependencyResolver/Solver.php @@ -1069,8 +1069,31 @@ class Solver //findrecommendedsuggested(solv); //solver_prepare_solutions(solv); + return $this->createTransaction(); + } + + protected function createTransaction() + { $transaction = array(); + $installMeansUpdateMap = array(); + $ignoreRemoveMap = array(); + + foreach ($this->decisionQueue as $i => $literal) { + $package = $literal->getPackage(); + + // !wanted & installed + if (!$literal->isWanted() && $this->installed === $package->getRepository()) { + $updateRule = $this->packageToUpdateRule[$package->getId()]; + + foreach ($updateRule->getLiterals() as $updateLiteral) { + if (!$updateLiteral->equals($literal)) { + $installMeansUpdateMap[$updateLiteral->getPackageId()] = $package; + } + } + } + } + foreach ($this->decisionQueue as $i => $literal) { $package = $literal->getPackage(); @@ -1079,11 +1102,34 @@ class Solver continue; } - $transaction[] = array( - 'job' => ($literal->isWanted()) ? 'install' : 'remove', - 'package' => $package, - 'why' => $this->decisionQueueWhy[$i], - ); + if ($literal->isWanted()) { + if (isset($installMeansUpdateMap[$literal->getPackageId()])) { + $source = $installMeansUpdateMap[$literal->getPackageId()]; + + $transaction[] = array( + 'job' => 'update', + 'from' => $source, + 'to' => $package, + 'why' => $this->decisionQueueWhy[$i], + ); + + // avoid updates to one package from multiple origins + unset($installMeansUpdateMap[$literal->getPackageId()]); + $ignoreRemove[$source->getId()] = true; + } else { + $transaction[] = array( + 'job' => 'install', + 'package' => $package, + 'why' => $this->decisionQueueWhy[$i], + ); + } + } else if (!isset($ignoreRemove[$package->getId()])) { + $transaction[] = array( + 'job' => 'remove', + 'package' => $package, + 'why' => $this->decisionQueueWhy[$i], + ); + } } return array_reverse($transaction); diff --git a/tests/Composer/Test/DependencyResolver/SolverTest.php b/tests/Composer/Test/DependencyResolver/SolverTest.php index 15a1e4ab4..85d46a72f 100644 --- a/tests/Composer/Test/DependencyResolver/SolverTest.php +++ b/tests/Composer/Test/DependencyResolver/SolverTest.php @@ -124,9 +124,7 @@ class SolverTest extends \PHPUnit_Framework_TestCase $this->request->update('A'); $this->checkSolverResult(array( - //array('job' => 'update', 'from' => $packageA, 'to' => $newPackageA), - array('job' => 'remove', 'package' => $packageA), - array('job' => 'install', 'package' => $newPackageA), + array('job' => 'update', 'from' => $packageA, 'to' => $newPackageA), )); } @@ -143,8 +141,6 @@ class SolverTest extends \PHPUnit_Framework_TestCase public function testSolverFull() { - $this->markTestIncomplete(); - $this->repoInstalled->addPackage($packageD = new MemoryPackage('D', '1.0')); $this->repoInstalled->addPackage($oldPackageC = new MemoryPackage('C', '1.0')); @@ -162,10 +158,10 @@ class SolverTest extends \PHPUnit_Framework_TestCase $this->request->remove('D'); $this->checkSolverResult(array( + array('job' => 'update', 'from' => $oldPackageC, 'to' => $packageC), array('job' => 'install', 'package' => $packageB), - array('job' => 'install', 'package' => $packageA), array('job' => 'remove', 'package' => $packageD), - array('job' => 'update', 'from' => $oldPackageC, 'to' => $packageC), + array('job' => 'install', 'package' => $packageA), )); }