Parcourir la source

Merge pull request #1 from naderman/require-update

Whitelist dependencies
Jordi Boggiano il y a 12 ans
Parent
commit
c8edbca9fe

+ 49 - 8
src/Composer/Installer.php

@@ -220,6 +220,8 @@ class Installer
             $stabilityFlags = $this->locker->getStabilityFlags();
         }
 
+        $this->whitelistUpdateDependencies($localRepo, $devMode);
+
         // creating repository pool
         $pool = new Pool($minimumStability, $stabilityFlags);
         $pool->addRepository($installedRepo);
@@ -456,17 +458,56 @@ class Installer
             throw new \LogicException('isUpdateable should only be called when a whitelist is present');
         }
 
-        if (in_array($package->getName(), $this->updateWhitelist)) {
-            return true;
+        return isset($this->updateWhitelist[$package->getName()]);
+    }
+
+    /**
+     * Adds all dependencies of the update whitelist to the whitelist, too.
+     *
+     * @param RepositoryInterface $localRepo
+     * @param boolean $devMode
+     */
+    private function whitelistUpdateDependencies($localRepo, $devMode)
+    {
+        if (!$this->updateWhitelist) {
+            return;
         }
 
-        foreach ($this->package->getRequires() as $link) {
-            if ($link->getTarget() === $package->getName()) {
-                return false;
+        $pool = new Pool;
+        $pool->addRepository($localRepo);
+
+        $seen = array();
+
+        foreach ($this->updateWhitelist as $packageName => $void) {
+            $packageQueue = new \SplQueue;
+
+            foreach ($pool->whatProvides($packageName) as $depPackage) {
+                $packageQueue->enqueue($depPackage);
             }
-        }
 
-        return true;
+            while (!$packageQueue->isEmpty()) {
+                $package = $packageQueue->dequeue();
+                if (isset($seen[$package->getId()])) {
+                    continue;
+                }
+
+                $seen[$package->getId()] = true;
+                $this->updateWhitelist[$package->getName()] = true;
+
+                $requires = $package->getRequires();
+                if ($devMode) {
+                    $requires = array_merge($requires, $package->getDevRequires());
+                }
+
+                foreach ($requires as $require) {
+                    $requirePackages = $pool->whatProvides($require->getTarget());
+
+                    foreach ($requirePackages as $requirePackage) {
+                        $packageQueue->enqueue($requirePackage);
+                    }
+                }
+            }
+        }
     }
 
     /**
@@ -589,7 +630,7 @@ class Installer
      */
     public function setUpdateWhitelist(array $packages)
     {
-        $this->updateWhitelist = array_map('strtolower', $packages);
+        $this->updateWhitelist = array_flip(array_map('strtolower', $packages));
 
         return $this;
     }

+ 11 - 4
tests/Composer/Test/Fixtures/installer/update-whitelist.test

@@ -11,20 +11,27 @@ Update with a package whitelist only updates those packages and their dependenci
                 { "name": "whitelisted", "version": "1.1.0", "require": { "dependency": "1.1.0" } },
                 { "name": "whitelisted", "version": "1.0.0", "require": { "dependency": "1.0.0" } },
                 { "name": "dependency", "version": "1.1.0" },
-                { "name": "dependency", "version": "1.0.0" }
+                { "name": "dependency", "version": "1.0.0" },
+                { "name": "unrelated", "version": "1.1.0", "require": { "unrelated-dependency": "1.*" }  },
+                { "name": "unrelated", "version": "1.0.0", "require": { "unrelated-dependency": "1.*" }  },
+                { "name": "unrelated-dependency", "version": "1.1.0" },
+                { "name": "unrelated-dependency", "version": "1.0.0" }
             ]
         }
     ],
     "require": {
         "fixed": "1.*",
-        "whitelisted": "1.*"
+        "whitelisted": "1.*",
+        "unrelated": "1.*"
     }
 }
 --INSTALLED--
 [
     { "name": "fixed", "version": "1.0.0" },
-    { "name": "whitelisted", "version": "1.0.0" },
-    { "name": "dependency", "version": "1.0.0" }
+    { "name": "whitelisted", "version": "1.0.0", "require": { "dependency": "1.0.0" } },
+    { "name": "dependency", "version": "1.0.0" },
+    { "name": "unrelated", "version": "1.0.0", "require": { "unrelated-dependency": "1.*" } },
+    { "name": "unrelated-dependency", "version": "1.0.0" }
 ]
 --RUN--
 update whitelisted