diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index 97a1bcbc61f3..31299ceff048 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -280,9 +280,7 @@ protected function doInstall($localRepo, $installedRepo, $aliases, $devMode = fa // 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 || in_array($package->getName(), $this->updateWhitelist)) - ) { + if ($package->getRepository() === $localRepo && (!$this->updateWhitelist || $this->isUpdateable($package))) { continue; } @@ -338,7 +336,7 @@ protected function doInstall($localRepo, $installedRepo, $aliases, $devMode = fa // force update to latest on update if ($this->update) { // skip package if the whitelist is enabled and it is not in it - if ($this->updateWhitelist && !in_array($package->getName(), $this->updateWhitelist)) { + if ($this->updateWhitelist && !$this->isUpdateable($package)) { continue; } @@ -452,6 +450,25 @@ private function aliasPackages() return $aliases; } + private function isUpdateable(PackageInterface $package) + { + if (!$this->updateWhitelist) { + throw new \LogicException('isUpdateable should only be called when a whitelist is present'); + } + + if (in_array($package->getName(), $this->updateWhitelist)) { + return true; + } + + foreach ($this->package->getRequires() as $link) { + if ($link->getTarget() === $package->getName()) { + return false; + } + } + + return true; + } + /** * Create Installer * diff --git a/tests/Composer/Test/Fixtures/installer/update-whitelist.test b/tests/Composer/Test/Fixtures/installer/update-whitelist.test new file mode 100644 index 000000000000..79d035c8f1a2 --- /dev/null +++ b/tests/Composer/Test/Fixtures/installer/update-whitelist.test @@ -0,0 +1,33 @@ +--TEST-- +Update with a package whitelist only updates those packages and their dependencies if they are not present in composer.json +--COMPOSER-- +{ + "repositories": [ + { + "type": "package", + "package": [ + { "name": "fixed", "version": "1.1.0" }, + { "name": "fixed", "version": "1.0.0" }, + { "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" } + ] + } + ], + "require": { + "fixed": "1.*", + "whitelisted": "1.*" + } +} +--INSTALLED-- +[ + { "name": "fixed", "version": "1.0.0" }, + { "name": "whitelisted", "version": "1.0.0" }, + { "name": "dependency", "version": "1.0.0" } +] +--RUN-- +update whitelisted +--EXPECT-- +Updating dependency (1.0.0) to dependency (1.1.0) +Updating whitelisted (1.0.0) to whitelisted (1.1.0)