Merge pull request #9519 from Seldaek/lock-update-with-new-req
Fix mirror updates when adding new reqs and dev-reqs are presentpull/9532/head
commit
01887a2488
|
@ -24,6 +24,7 @@ use Composer\DependencyResolver\Pool;
|
||||||
use Composer\DependencyResolver\Request;
|
use Composer\DependencyResolver\Request;
|
||||||
use Composer\DependencyResolver\Solver;
|
use Composer\DependencyResolver\Solver;
|
||||||
use Composer\DependencyResolver\SolverProblemsException;
|
use Composer\DependencyResolver\SolverProblemsException;
|
||||||
|
use Composer\DependencyResolver\PolicyInterface;
|
||||||
use Composer\Downloader\DownloadManager;
|
use Composer\Downloader\DownloadManager;
|
||||||
use Composer\EventDispatcher\EventDispatcher;
|
use Composer\EventDispatcher\EventDispatcher;
|
||||||
use Composer\Installer\InstallationManager;
|
use Composer\Installer\InstallationManager;
|
||||||
|
@ -52,6 +53,7 @@ use Composer\Repository\RootPackageRepository;
|
||||||
use Composer\Repository\PlatformRepository;
|
use Composer\Repository\PlatformRepository;
|
||||||
use Composer\Repository\RepositoryInterface;
|
use Composer\Repository\RepositoryInterface;
|
||||||
use Composer\Repository\RepositoryManager;
|
use Composer\Repository\RepositoryManager;
|
||||||
|
use Composer\Repository\LockArrayRepository;
|
||||||
use Composer\Script\ScriptEvents;
|
use Composer\Script\ScriptEvents;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -365,12 +367,10 @@ class Installer
|
||||||
// doing a full update
|
// doing a full update
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->updateAllowList) {
|
if (($this->updateAllowList || $this->updateMirrors) && !$lockedRepository) {
|
||||||
if (!$lockedRepository) {
|
$this->io->writeError('<error>Cannot update ' . ($this->updateMirrors ? 'lock file information' : 'only a partial set of packages') . ' without a lock file present. Run `composer update` to generate a lock file.</error>', true, IOInterface::QUIET);
|
||||||
$this->io->writeError('<error>Cannot update only a partial set of packages without a lock file present.</error>', true, IOInterface::QUIET);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->io->writeError('<info>Loading composer repositories with package information</info>');
|
$this->io->writeError('<info>Loading composer repositories with package information</info>');
|
||||||
|
@ -387,22 +387,7 @@ class Installer
|
||||||
}
|
}
|
||||||
|
|
||||||
$request = $this->createRequest($this->fixedRootPackage, $platformRepo, $lockedRepository);
|
$request = $this->createRequest($this->fixedRootPackage, $platformRepo, $lockedRepository);
|
||||||
|
$this->requirePackagesForUpdate($request, $lockedRepository, 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 && $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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// pass the allow list into the request, so the pool builder can apply it
|
// pass the allow list into the request, so the pool builder can apply it
|
||||||
if ($this->updateAllowList) {
|
if ($this->updateAllowList) {
|
||||||
|
@ -442,7 +427,7 @@ class Installer
|
||||||
$this->io->writeError('Nothing to modify in lock file');
|
$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) {
|
if ($exitCode !== 0) {
|
||||||
return $exitCode;
|
return $exitCode;
|
||||||
}
|
}
|
||||||
|
@ -555,7 +540,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
|
* 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
|
* 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()) {
|
if (!$this->package->getDevRequires()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -572,11 +557,7 @@ class Installer
|
||||||
$repositorySet->addRepository($resultRepo);
|
$repositorySet->addRepository($resultRepo);
|
||||||
|
|
||||||
$request = $this->createRequest($this->fixedRootPackage, $platformRepo);
|
$request = $this->createRequest($this->fixedRootPackage, $platformRepo);
|
||||||
|
$this->requirePackagesForUpdate($request, $lockedRepository, false);
|
||||||
$links = $this->package->getRequires();
|
|
||||||
foreach ($links as $link) {
|
|
||||||
$request->requireName($link->getTarget(), $link->getConstraint());
|
|
||||||
}
|
|
||||||
|
|
||||||
$pool = $repositorySet->createPoolWithAllPackages();
|
$pool = $repositorySet->createPoolWithAllPackages();
|
||||||
|
|
||||||
|
@ -815,12 +796,9 @@ class Installer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param RootPackageInterface $rootPackage
|
|
||||||
* @param PlatformRepository $platformRepo
|
|
||||||
* @param RepositoryInterface|null $lockedRepository
|
|
||||||
* @return Request
|
* @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);
|
$request = new Request($lockedRepository);
|
||||||
|
|
||||||
|
@ -851,6 +829,33 @@ class Installer
|
||||||
return $request;
|
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 = array_flip($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 && !isset($excludedPackages[$lockedPackage->getName()])) {
|
||||||
|
$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
|
* @param bool $forUpdate
|
||||||
* @return array
|
* @return array
|
||||||
|
@ -870,7 +875,7 @@ class Installer
|
||||||
* @param array $links
|
* @param array $links
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
private function extractPlatformRequirements($links)
|
private function extractPlatformRequirements(array $links)
|
||||||
{
|
{
|
||||||
$platformReqs = array();
|
$platformReqs = array();
|
||||||
foreach ($links as $link) {
|
foreach ($links as $link) {
|
||||||
|
|
|
@ -31,7 +31,7 @@ Partial update without lock file should error
|
||||||
--RUN--
|
--RUN--
|
||||||
update b/unstable
|
update b/unstable
|
||||||
--EXPECT-OUTPUT--
|
--EXPECT-OUTPUT--
|
||||||
Cannot update only a partial set of packages without a lock file present.
|
Cannot update only a partial set of packages without a lock file present. Run `composer update` to generate a lock file.
|
||||||
--EXPECT-EXIT-CODE--
|
--EXPECT-EXIT-CODE--
|
||||||
1
|
1
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
|
|
|
@ -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--
|
Loading…
Reference in New Issue