diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index a4156c38c..ae32d9651 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -220,7 +220,11 @@ class Installer $stabilityFlags = $this->locker->getStabilityFlags(); } - $this->whitelistUpdateDependencies($localRepo, $devMode); + $this->whitelistUpdateDependencies( + $localRepo, + $devMode, + $this->package->getRequires(), + $this->package->getDevRequires()); // creating repository pool $pool = new Pool($minimumStability, $stabilityFlags); @@ -464,15 +468,30 @@ class Installer /** * Adds all dependencies of the update whitelist to the whitelist, too. * + * Packages which are listed as requirements in the root package will be + * skipped including their dependencies, unless they are listed in the + * update whitelist themselves. + * * @param RepositoryInterface $localRepo * @param boolean $devMode + * @param array $rootRequires An array of links to packages in require of the root package + * @param array $rootDevRequires An array of links to packages in require-dev of the root package */ - private function whitelistUpdateDependencies($localRepo, $devMode) + private function whitelistUpdateDependencies($localRepo, $devMode, array $rootRequires, array $rootDevRequires) { if (!$this->updateWhitelist) { return; } + if ($devMode) { + $rootRequires = array_merge($rootRequires, $rootDevRequires); + } + + $skipPackages = array(); + foreach ($rootRequires as $require) { + $skipPackages[$require->getTarget()] = true; + } + $pool = new Pool; $pool->addRepository($localRepo); @@ -503,6 +522,9 @@ class Installer $requirePackages = $pool->whatProvides($require->getTarget()); foreach ($requirePackages as $requirePackage) { + if (isset($skipPackages[$requirePackage->getName()])) { + continue; + } $packageQueue->enqueue($requirePackage); } } diff --git a/tests/Composer/Test/Fixtures/installer/update-whitelist-locked-require.test b/tests/Composer/Test/Fixtures/installer/update-whitelist-locked-require.test new file mode 100644 index 000000000..6586e461f --- /dev/null +++ b/tests/Composer/Test/Fixtures/installer/update-whitelist-locked-require.test @@ -0,0 +1,36 @@ +--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": "whitelisted", "version": "1.1.0", "require": { "dependency": "1.1.0", "fixed-dependency": "1.*" } }, + { "name": "whitelisted", "version": "1.0.0", "require": { "dependency": "1.0.0", "fixed-dependency": "1.*" } }, + { "name": "dependency", "version": "1.1.0" }, + { "name": "dependency", "version": "1.0.0" }, + { "name": "fixed-dependency", "version": "1.1.0", "require": { "fixed-sub-dependency": "1.*" } }, + { "name": "fixed-dependency", "version": "1.0.0", "require": { "fixed-sub-dependency": "1.*" } }, + { "name": "fixed-sub-dependency", "version": "1.1.0" }, + { "name": "fixed-sub-dependency", "version": "1.0.0" } + ] + } + ], + "require": { + "whitelisted": "1.*", + "fixed-dependency": "1.*" + } +} +--INSTALLED-- +[ + { "name": "whitelisted", "version": "1.0.0", "require": { "dependency": "1.0.0", "fixed-dependency": "1.*" } }, + { "name": "dependency", "version": "1.0.0" }, + { "name": "fixed-dependency", "version": "1.0.0", "require": { "fixed-sub-dependency": "1.*" } }, + { "name": "fixed-sub-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) diff --git a/tests/Composer/Test/Fixtures/installer/update-whitelist.test b/tests/Composer/Test/Fixtures/installer/update-whitelist.test index 0edf18ea5..3d7ca30af 100644 --- a/tests/Composer/Test/Fixtures/installer/update-whitelist.test +++ b/tests/Composer/Test/Fixtures/installer/update-whitelist.test @@ -1,5 +1,5 @@ --TEST-- -Update with a package whitelist only updates those packages and their dependencies if they are not present in composer.json +Update with a package whitelist only updates those packages and their dependencies listed as command arguments --COMPOSER-- { "repositories": [