From 90c515522ac9713c1d1dfb6cb3aad5541530abe2 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 28 May 2012 01:25:34 +0200 Subject: [PATCH 1/2] Change whitelist integration test to check it doesn't update unrelated packages --- .../Test/Fixtures/installer/update-whitelist.test | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/Composer/Test/Fixtures/installer/update-whitelist.test b/tests/Composer/Test/Fixtures/installer/update-whitelist.test index 79d035c8f..0edf18ea5 100644 --- a/tests/Composer/Test/Fixtures/installer/update-whitelist.test +++ b/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 From 2d9aa3d49d1c3f366c5ee150e8ebd7fe143a628a Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 28 May 2012 01:58:54 +0200 Subject: [PATCH 2/2] Update dependencies of whitelisted packages, but not random dependencies --- src/Composer/Installer.php | 57 ++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index 31299ceff..ba16eeee4 100644 --- a/src/Composer/Installer.php +++ b/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); + } + + 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); + } + } } } - - return true; } /** @@ -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; }