From 5c30fcb7770ad6c6298b2e5f1fb6a0ee68e803fb Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 1 Jul 2012 18:03:01 +0200 Subject: [PATCH] Fix update whitelist behavior, fixes #782 --- src/Composer/Installer.php | 41 +++++++++++++++-- .../update-whitelist-reads-lock.test | 46 +++++++++++++++++++ 2 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 tests/Composer/Test/Fixtures/installer/update-whitelist-reads-lock.test diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index d10c438f8..2fe70bbde 100644 --- a/src/Composer/Installer.php +++ b/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); diff --git a/tests/Composer/Test/Fixtures/installer/update-whitelist-reads-lock.test b/tests/Composer/Test/Fixtures/installer/update-whitelist-reads-lock.test new file mode 100644 index 000000000..63c01b7d5 --- /dev/null +++ b/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)