From 137c55124764a25cd61a711bfbe14af433482099 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 30 Apr 2015 16:41:28 +0100 Subject: [PATCH] Check if package URLs are up to date after an update op is done, fixes #3214 --- src/Composer/Installer.php | 44 ++++++++- .../update-dev-packages-updates-repo-url.test | 96 +++++++++++++++++++ 2 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 tests/Composer/Test/Fixtures/installer/update-dev-packages-updates-repo-url.test diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index e1b712954..5d0908918 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -610,6 +610,12 @@ class Installer } } + if (!$this->dryRun) { + // force source/dist urls to be updated for all packages + $operations = $this->processPackageUrls($pool, $policy, $localRepo, $repositories); + $localRepo->write(); + } + return 0; } @@ -860,7 +866,7 @@ class Installer } if ($task === 'force-updates') { - // force installed package to update to referenced version if it does not match the installed version + // force installed package to update to referenced version in root package if it does not match the installed version $references = $this->package->getReferences(); if (isset($references[$package->getName()]) && $references[$package->getName()] !== $package->getSourceReference()) { @@ -894,6 +900,42 @@ class Installer return $normalizedAliases; } + private function processPackageUrls($pool, $policy, $localRepo, $repositories) + { + if (!$this->update) { + return; + } + + foreach ($localRepo->getCanonicalPackages() as $package) { + // find similar packages (name/version) in all repositories + $matches = $pool->whatProvides($package->getName(), new VersionConstraint('=', $package->getVersion())); + foreach ($matches as $index => $match) { + // skip local packages + if (!in_array($match->getRepository(), $repositories, true)) { + unset($matches[$index]); + continue; + } + + // skip providers/replacers + if ($match->getName() !== $package->getName()) { + unset($matches[$index]); + continue; + } + + $matches[$index] = $match->getId(); + } + + // select preferred package according to policy rules + if ($matches && $matches = $policy->selectPreferredPackages($pool, array(), $matches)) { + $newPackage = $pool->literalToPackage($matches[0]); + + // update the dist and source URLs + $package->setSourceUrl($newPackage->getSourceUrl()); + $package->setDistUrl($newPackage->getDistUrl()); + } + } + } + private function aliasPlatformPackages(PlatformRepository $platformRepo, $aliases) { foreach ($aliases as $package => $versions) { diff --git a/tests/Composer/Test/Fixtures/installer/update-dev-packages-updates-repo-url.test b/tests/Composer/Test/Fixtures/installer/update-dev-packages-updates-repo-url.test new file mode 100644 index 000000000..f91a67cea --- /dev/null +++ b/tests/Composer/Test/Fixtures/installer/update-dev-packages-updates-repo-url.test @@ -0,0 +1,96 @@ +--TEST-- +Updating dev packages where no reference change happened triggers a repo url change +--COMPOSER-- +{ + "repositories": [ + { + "type": "package", + "package": [ + { + "name": "a/a", "version": "dev-master", + "extra": { "branch-alias": { "dev-master": "2.1.x-dev" } }, + "source": { "reference": "newmaster", "type": "git", "url": "newurl" } + }, + { + "name": "b/b", "version": "dev-master", + "extra": { "branch-alias": { "dev-master": "2.1.x-dev" } }, + "source": { "reference": "master", "type": "git", "url": "newurl" } + } + ] + } + ], + "require": { + "a/a": "~2.1", + "b/b": "~2.1" + }, + "minimum-stability": "dev" +} +--INSTALLED-- +[ + { + "name": "a/a", "version": "dev-master", "version_normalized": "9999999-dev", + "extra": { "branch-alias": { "dev-master": "2.1.x-dev" } }, + "source": { "reference": "oldmaster", "type": "git", "url": "oldurl" }, + "type": "library" + }, + { + "name": "b/b", "version": "dev-master", "version_normalized": "9999999-dev", + "extra": { "branch-alias": { "dev-master": "2.1.x-dev" } }, + "source": { "reference": "master", "type": "git", "url": "oldurl" }, + "type": "library" + } +] +--LOCK-- +{ + "packages": [ + { + "name": "a/a", "version": "dev-master", + "extra": { "branch-alias": { "dev-master": "2.1.x-dev" } }, + "source": { "reference": "newmaster", "type": "git", "url": "oldurl" }, + "type": "library" + }, + { + "name": "b/b", "version": "dev-master", + "extra": { "branch-alias": { "dev-master": "2.1.x-dev" } }, + "source": { "reference": "master", "type": "git", "url": "oldurl" }, + "type": "library" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} +--RUN-- +update +--EXPECT-LOCK-- +{ + "packages": [ + { + "name": "a/a", "version": "dev-master", + "extra": { "branch-alias": { "dev-master": "2.1.x-dev" } }, + "source": { "reference": "newmaster", "type": "git", "url": "newurl" }, + "type": "library" + }, + { + "name": "b/b", "version": "dev-master", + "extra": { "branch-alias": { "dev-master": "2.1.x-dev" } }, + "source": { "reference": "master", "type": "git", "url": "newurl" }, + "type": "library" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} +--EXPECT-- +Updating a/a (dev-master oldmaster) to a/a (dev-master newmaster)