Browse Source

Merge pull request #859 from Seldaek/whitelist_fix

Fix update whitelist behavior, fixes #782
Nils Adermann 12 years ago
parent
commit
297bc914fc

+ 36 - 5
src/Composer/Installer.php

@@ -229,7 +229,8 @@ class Installer
             $localRepo,
             $devMode,
             $this->package->getRequires(),
-            $this->package->getDevRequires());
+            $this->package->getDevRequires()
+        );
 
         // creating repository pool
         $pool = new Pool($minimumStability, $stabilityFlags);
@@ -287,11 +288,8 @@ class Installer
         // fix the version of all installed packages (+ platform) that are not
         // in the current local repo to prevent rogue updates (e.g. non-dev
         // updating when in dev)
-        //
-        // if the updateWhitelist is enabled, packages not in it are also fixed
-        // to their currently installed version
         foreach ($installedRepo->getPackages() as $package) {
-            if ($package->getRepository() === $localRepo && (!$this->updateWhitelist || $this->isUpdateable($package))) {
+            if ($package->getRepository() === $localRepo) {
                 continue;
             }
 
@@ -299,6 +297,39 @@ class Installer
             $request->install($package->getName(), $constraint);
         }
 
+        // if the updateWhitelist is enabled, packages not in it are also fixed
+        // to the version specified in the lock, or their currently installed version
+        if ($this->update && $this->updateWhitelist) {
+            if ($this->locker->isLocked($devMode)) {
+                $currentPackages = $this->locker->getLockedPackages($devMode);
+            } else {
+                $currentPackages = $installedRepo->getPackages();
+            }
+
+            // collect links from composer as well as installed packages
+            $candidates = array();
+            foreach ($links as $link) {
+                $candidates[$link->getTarget()] = true;
+            }
+            foreach ($localRepo->getPackages() as $package) {
+                $candidates[$package->getName()] = true;
+            }
+
+            // fix them to the version in lock (or currently installed) if they are not updateable
+            foreach ($candidates as $candidate => $dummy) {
+                foreach ($currentPackages as $curPackage) {
+                    if ($curPackage->getName() === $candidate) {
+                        if ($this->isUpdateable($curPackage)) {
+                            break;
+                        }
+
+                        $constraint = new VersionConstraint('=', $curPackage->getVersion());
+                        $request->install($curPackage->getName(), $constraint);
+                    }
+                }
+            }
+        }
+
         // prepare solver
         $policy = new DefaultPolicy();
         $solver = new Solver($policy, $pool, $installedRepo);

+ 46 - 0
tests/Composer/Test/Fixtures/installer/update-whitelist-reads-lock.test

@@ -0,0 +1,46 @@
+--TEST--
+Limited update takes rules from lock if available, and not from the installed repo + composer.json
+--COMPOSER--
+{
+    "repositories": [
+        {
+            "type": "package",
+            "package": [
+                { "name": "toupdate/installed", "version": "1.1.0" },
+                { "name": "toupdate/installed", "version": "1.0.0" },
+                { "name": "toupdate/notinstalled", "version": "1.1.0" },
+                { "name": "toupdate/notinstalled", "version": "1.0.0" },
+                { "name": "old/installed", "version": "0.9.0" },
+                { "name": "old/installed", "version": "1.0.0" }
+            ]
+        }
+    ],
+    "require": {
+        "toupdate/installed": "1.*",
+        "toupdate/notinstalled": "1.*",
+        "old/installed": "*"
+    }
+}
+--LOCK--
+{
+    "packages": [
+        { "package": "old/installed", "version": "1.0.0" },
+        { "package": "toupdate/installed", "version": "1.0.0" },
+        { "package": "toupdate/notinstalled", "version": "1.0.0" }
+    ],
+    "packages-dev": null,
+    "aliases": [],
+    "minimum-stability": "stable",
+    "stability-flags": []
+}
+--INSTALLED--
+[
+    { "name": "toupdate/installed", "version": "1.0.0" },
+    { "name": "old/installed", "version": "0.9.0" }
+]
+--RUN--
+update toupdate/installed
+--EXPECT--
+Updating old/installed (0.9.0) to old/installed (1.0.0)
+Updating toupdate/installed (1.0.0) to toupdate/installed (1.1.0)
+Installing toupdate/notinstalled (1.0.0)