瀏覽代碼

Separate transaction generation from solving and properly identify updates

Nils Adermann 13 年之前
父節點
當前提交
0f6fb9b692
共有 2 個文件被更改,包括 54 次插入12 次删除
  1. 51 5
      src/Composer/DependencyResolver/Solver.php
  2. 3 7
      tests/Composer/Test/DependencyResolver/SolverTest.php

+ 51 - 5
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);

+ 3 - 7
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),
         ));
     }