1
0
Fork 0

Make sure mirror updates do not fail if there are dev requirements and new requires are present, fixes #9514

pull/9519/head
Jordi Boggiano 2020-11-26 11:27:44 +01:00
parent 08f0af4623
commit 2d025dce05
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC
2 changed files with 100 additions and 25 deletions

View File

@ -24,6 +24,7 @@ use Composer\DependencyResolver\Pool;
use Composer\DependencyResolver\Request;
use Composer\DependencyResolver\Solver;
use Composer\DependencyResolver\SolverProblemsException;
use Composer\DependencyResolver\PolicyInterface;
use Composer\Downloader\DownloadManager;
use Composer\EventDispatcher\EventDispatcher;
use Composer\Installer\InstallationManager;
@ -52,6 +53,7 @@ use Composer\Repository\RootPackageRepository;
use Composer\Repository\PlatformRepository;
use Composer\Repository\RepositoryInterface;
use Composer\Repository\RepositoryManager;
use Composer\Repository\LockArrayRepository;
use Composer\Script\ScriptEvents;
/**
@ -387,22 +389,7 @@ class Installer
}
$request = $this->createRequest($this->fixedRootPackage, $platformRepo, $lockedRepository);
// if we're updating mirrors we want to keep exactly the same versions installed which are in the lock file, but we want current remote metadata
if ($this->updateMirrors && $lockedRepository) {
foreach ($lockedRepository->getPackages() as $lockedPackage) {
// exclude alias packages here as for root aliases, both alias and aliased are
// present in the lock repo and we only want to require the aliased version
if (!$lockedPackage instanceof AliasPackage) {
$request->requireName($lockedPackage->getName(), new Constraint('==', $lockedPackage->getVersion()));
}
}
} else {
$links = array_merge($this->package->getRequires(), $this->package->getDevRequires());
foreach ($links as $link) {
$request->requireName($link->getTarget(), $link->getConstraint());
}
}
$this->requirePackagesForUpdate($request, $lockedRepository, true);
// pass the allow list into the request, so the pool builder can apply it
if ($this->updateAllowList) {
@ -442,7 +429,7 @@ class Installer
$this->io->writeError('Nothing to modify in lock file');
}
$exitCode = $this->extractDevPackages($lockTransaction, $platformRepo, $aliases, $policy);
$exitCode = $this->extractDevPackages($lockTransaction, $platformRepo, $aliases, $policy, $lockedRepository);
if ($exitCode !== 0) {
return $exitCode;
}
@ -555,7 +542,7 @@ class Installer
* Run the solver a second time on top of the existing update result with only the current result set in the pool
* and see what packages would get removed if we only had the non-dev packages in the solver request
*/
protected function extractDevPackages(LockTransaction $lockTransaction, $platformRepo, $aliases, $policy)
protected function extractDevPackages(LockTransaction $lockTransaction, PlatformRepository $platformRepo, array $aliases, PolicyInterface $policy, LockArrayRepository $lockedRepository = null)
{
if (!$this->package->getDevRequires()) {
return 0;
@ -572,11 +559,7 @@ class Installer
$repositorySet->addRepository($resultRepo);
$request = $this->createRequest($this->fixedRootPackage, $platformRepo);
$links = $this->package->getRequires();
foreach ($links as $link) {
$request->requireName($link->getTarget(), $link->getConstraint());
}
$this->requirePackagesForUpdate($request, $lockedRepository, false);
$pool = $repositorySet->createPoolWithAllPackages();
@ -820,7 +803,7 @@ class Installer
* @param RepositoryInterface|null $lockedRepository
* @return Request
*/
private function createRequest(RootPackageInterface $rootPackage, PlatformRepository $platformRepo, $lockedRepository = null)
private function createRequest(RootPackageInterface $rootPackage, PlatformRepository $platformRepo, LockArrayRepository $lockedRepository = null)
{
$request = new Request($lockedRepository);
@ -851,6 +834,33 @@ class Installer
return $request;
}
private function requirePackagesForUpdate(Request $request, LockArrayRepository $lockedRepository = null, $includeDevRequires = true)
{
// if we're updating mirrors we want to keep exactly the same versions installed which are in the lock file, but we want current remote metadata
if ($this->updateMirrors) {
$excludedPackages = array();
if (!$includeDevRequires) {
$excludedPackages = $this->locker->getDevPackageNames();
}
foreach ($lockedRepository->getPackages() as $lockedPackage) {
// exclude alias packages here as for root aliases, both alias and aliased are
// present in the lock repo and we only want to require the aliased version
if (!$lockedPackage instanceof AliasPackage && !in_array($lockedPackage->getName(), $excludedPackages, true)) {
$request->requireName($lockedPackage->getName(), new Constraint('==', $lockedPackage->getVersion()));
}
}
} else {
$links = $this->package->getRequires();
if ($includeDevRequires) {
$links = array_merge($links, $this->package->getDevRequires());
}
foreach ($links as $link) {
$request->requireName($link->getTarget(), $link->getConstraint());
}
}
}
/**
* @param bool $forUpdate
* @return array
@ -870,7 +880,7 @@ class Installer
* @param array $links
* @return array
*/
private function extractPlatformRequirements($links)
private function extractPlatformRequirements(array $links)
{
$platformReqs = array();
foreach ($links as $link) {

View File

@ -0,0 +1,65 @@
--TEST--
Update mirrors with a new root require which is not yet in lock should simply ignore it
--COMPOSER--
{
"repositories": [
{
"type": "package",
"package": [
{"name": "a/a", "version": "1.0.0"},
{"name": "a/a", "version": "1.1.0"},
{"name": "b/b", "version": "1.0.0"},
{"name": "b/b", "version": "1.1.0"},
{"name": "new/req", "version": "1.0.0"},
{"name": "new/req", "version": "1.1.0"}
]
}
],
"require": {
"a/a": "1.*",
"new/req": "1.*"
},
"require-dev": {
"b/b": "1.*"
}
}
--INSTALLED--
[
{"name": "a/a", "version": "1.0.0"},
{"name": "b/b", "version": "1.0.0"}
]
--LOCK--
{
"packages": [
{"name": "a/a", "version": "1.0.0", "type": "library"}
],
"packages-dev": [
{"name": "b/b", "version": "1.0.0", "type": "library"}
],
"aliases": [],
"minimum-stability": "dev",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": []
}
--RUN--
update mirrors
--EXPECT-LOCK--
{
"packages": [
{"name": "a/a", "version": "1.0.0", "type": "library"}
],
"packages-dev": [
{"name": "b/b", "version": "1.0.0", "type": "library"}
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": []
}
--EXPECT--