Merge pull request #3986 from Seldaek/partial-update-keep-lock
Partial updates should not corrupt the lock if the installed repo is not up to date with itpull/3130/merge
commit
258fdcb44d
|
@ -358,9 +358,12 @@ class Installer
|
||||||
$repositories = null;
|
$repositories = null;
|
||||||
|
|
||||||
// initialize locker to create aliased packages
|
// initialize locker to create aliased packages
|
||||||
$installFromLock = false;
|
$installFromLock = !$this->update && $this->locker->isLocked();
|
||||||
if (!$this->update && $this->locker->isLocked()) {
|
|
||||||
$installFromLock = true;
|
// initialize locked repo if we are installing from lock or in a partial update
|
||||||
|
// and a lock file is present as we need to force install non-whitelisted lock file
|
||||||
|
// packages in that case
|
||||||
|
if ($installFromLock || (!empty($this->updateWhitelist) && $this->locker->isLocked())) {
|
||||||
try {
|
try {
|
||||||
$lockedRepository = $this->locker->getLockedRepository($withDevReqs);
|
$lockedRepository = $this->locker->getLockedRepository($withDevReqs);
|
||||||
} catch (\RuntimeException $e) {
|
} catch (\RuntimeException $e) {
|
||||||
|
@ -384,18 +387,20 @@ class Installer
|
||||||
|
|
||||||
// creating repository pool
|
// creating repository pool
|
||||||
$policy = $this->createPolicy();
|
$policy = $this->createPolicy();
|
||||||
$pool = $this->createPool($withDevReqs, $lockedRepository);
|
$pool = $this->createPool($withDevReqs, $installFromLock ? $lockedRepository : null);
|
||||||
$pool->addRepository($installedRepo, $aliases);
|
$pool->addRepository($installedRepo, $aliases);
|
||||||
if ($installFromLock) {
|
|
||||||
$pool->addRepository($lockedRepository, $aliases);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$installFromLock) {
|
if (!$installFromLock) {
|
||||||
$repositories = $this->repositoryManager->getRepositories();
|
$repositories = $this->repositoryManager->getRepositories();
|
||||||
foreach ($repositories as $repository) {
|
foreach ($repositories as $repository) {
|
||||||
$pool->addRepository($repository, $aliases);
|
$pool->addRepository($repository, $aliases);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Add the locked repository after the others in case we are doing a
|
||||||
|
// partial update so missing packages can be found there still.
|
||||||
|
// For installs from lock it's the only one added so it is first
|
||||||
|
if ($lockedRepository) {
|
||||||
|
$pool->addRepository($lockedRepository, $aliases);
|
||||||
|
}
|
||||||
|
|
||||||
// creating requirements request
|
// creating requirements request
|
||||||
$request = $this->createRequest($this->package, $platformRepo);
|
$request = $this->createRequest($this->package, $platformRepo);
|
||||||
|
@ -432,16 +437,7 @@ class Installer
|
||||||
// if the updateWhitelist is enabled, packages not in it are also fixed
|
// if the updateWhitelist is enabled, packages not in it are also fixed
|
||||||
// to the version specified in the lock, or their currently installed version
|
// to the version specified in the lock, or their currently installed version
|
||||||
if ($this->updateWhitelist) {
|
if ($this->updateWhitelist) {
|
||||||
if ($this->locker->isLocked()) {
|
$currentPackages = $this->getCurrentPackages($withDevReqs, $installedRepo);
|
||||||
try {
|
|
||||||
$currentPackages = $this->locker->getLockedRepository($withDevReqs)->getPackages();
|
|
||||||
} catch (\RuntimeException $e) {
|
|
||||||
// fetch only non-dev packages from lock if doing a dev update fails due to a previously incomplete lock file
|
|
||||||
$currentPackages = $this->locker->getLockedRepository()->getPackages();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$currentPackages = $installedRepo->getPackages();
|
|
||||||
}
|
|
||||||
|
|
||||||
// collect packages to fixate from root requirements as well as installed packages
|
// collect packages to fixate from root requirements as well as installed packages
|
||||||
$candidates = array();
|
$candidates = array();
|
||||||
|
@ -500,7 +496,7 @@ class Installer
|
||||||
}
|
}
|
||||||
|
|
||||||
// force dev packages to have the latest links if we update or install from a (potentially new) lock
|
// force dev packages to have the latest links if we update or install from a (potentially new) lock
|
||||||
$this->processDevPackages($localRepo, $pool, $policy, $repositories, $lockedRepository, $installFromLock, 'force-links');
|
$this->processDevPackages($localRepo, $pool, $policy, $repositories, $installedRepo, $lockedRepository, $installFromLock, $withDevReqs, 'force-links');
|
||||||
|
|
||||||
// solve dependencies
|
// solve dependencies
|
||||||
$this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, $this->devMode, $policy, $pool, $installedRepo, $request);
|
$this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, $this->devMode, $policy, $pool, $installedRepo, $request);
|
||||||
|
@ -516,7 +512,7 @@ class Installer
|
||||||
}
|
}
|
||||||
|
|
||||||
// force dev packages to be updated if we update or install from a (potentially new) lock
|
// force dev packages to be updated if we update or install from a (potentially new) lock
|
||||||
$operations = $this->processDevPackages($localRepo, $pool, $policy, $repositories, $lockedRepository, $installFromLock, 'force-updates', $operations);
|
$operations = $this->processDevPackages($localRepo, $pool, $policy, $repositories, $installedRepo, $lockedRepository, $installFromLock, $withDevReqs, 'force-updates', $operations);
|
||||||
|
|
||||||
// execute operations
|
// execute operations
|
||||||
if (!$operations) {
|
if (!$operations) {
|
||||||
|
@ -774,7 +770,7 @@ class Installer
|
||||||
return $request;
|
return $request;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processDevPackages($localRepo, $pool, $policy, $repositories, $lockedRepository, $installFromLock, $task, array $operations = null)
|
private function processDevPackages($localRepo, $pool, $policy, $repositories, $installedRepo, $lockedRepository, $installFromLock, $withDevReqs, $task, array $operations = null)
|
||||||
{
|
{
|
||||||
if ($task === 'force-updates' && null === $operations) {
|
if ($task === 'force-updates' && null === $operations) {
|
||||||
throw new \InvalidArgumentException('Missing operations argument');
|
throw new \InvalidArgumentException('Missing operations argument');
|
||||||
|
@ -783,6 +779,10 @@ class Installer
|
||||||
$operations = array();
|
$operations = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$installFromLock && $this->updateWhitelist) {
|
||||||
|
$currentPackages = $this->getCurrentPackages($withDevReqs, $installedRepo);
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($localRepo->getCanonicalPackages() as $package) {
|
foreach ($localRepo->getCanonicalPackages() as $package) {
|
||||||
// skip non-dev packages
|
// skip non-dev packages
|
||||||
if (!$package->isDev()) {
|
if (!$package->isDev()) {
|
||||||
|
@ -823,6 +823,26 @@ class Installer
|
||||||
if ($this->update) {
|
if ($this->update) {
|
||||||
// skip package if the whitelist is enabled and it is not in it
|
// skip package if the whitelist is enabled and it is not in it
|
||||||
if ($this->updateWhitelist && !$this->isUpdateable($package)) {
|
if ($this->updateWhitelist && !$this->isUpdateable($package)) {
|
||||||
|
// check if non-updateable packages are out of date compared to the lock file to ensure we don't corrupt it
|
||||||
|
foreach ($currentPackages as $curPackage) {
|
||||||
|
if ($curPackage->isDev() && $curPackage->getName() === $package->getName() && $curPackage->getVersion() === $package->getVersion()) {
|
||||||
|
if ($task === 'force-links') {
|
||||||
|
$package->setRequires($curPackage->getRequires());
|
||||||
|
$package->setConflicts($curPackage->getConflicts());
|
||||||
|
$package->setProvides($curPackage->getProvides());
|
||||||
|
$package->setReplaces($curPackage->getReplaces());
|
||||||
|
} elseif ($task === 'force-updates') {
|
||||||
|
if (($curPackage->getSourceReference() && $curPackage->getSourceReference() !== $package->getSourceReference())
|
||||||
|
|| ($curPackage->getDistReference() && $curPackage->getDistReference() !== $package->getDistReference())
|
||||||
|
) {
|
||||||
|
$operations[] = new UpdateOperation($package, $curPackage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -880,6 +900,23 @@ class Installer
|
||||||
return $operations;
|
return $operations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the most "current" list of packages that are installed meaning from lock ideally or from installed repo as fallback
|
||||||
|
*/
|
||||||
|
private function getCurrentPackages($withDevReqs, $installedRepo)
|
||||||
|
{
|
||||||
|
if ($this->locker->isLocked()) {
|
||||||
|
try {
|
||||||
|
return $this->locker->getLockedRepository($withDevReqs)->getPackages();
|
||||||
|
} catch (\RuntimeException $e) {
|
||||||
|
// fetch only non-dev packages from lock if doing a dev update fails due to a previously incomplete lock file
|
||||||
|
return $this->locker->getLockedRepository()->getPackages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $installedRepo->getPackages();
|
||||||
|
}
|
||||||
|
|
||||||
private function getRootAliases()
|
private function getRootAliases()
|
||||||
{
|
{
|
||||||
if (!$this->update && $this->locker->isLocked()) {
|
if (!$this->update && $this->locker->isLocked()) {
|
||||||
|
|
|
@ -65,5 +65,5 @@ update c/uptodate
|
||||||
"platform-dev": []
|
"platform-dev": []
|
||||||
}
|
}
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
Updating a/old (0.9.0) to a/old (1.0.0)
|
|
||||||
Updating b/unstable (1.1.0-alpha) to b/unstable (1.0.0)
|
Updating b/unstable (1.1.0-alpha) to b/unstable (1.0.0)
|
||||||
|
Updating a/old (0.9.0) to a/old (1.0.0)
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
--TEST--
|
||||||
|
Partial update forces updates dev reference from lock file for non whitelisted packages
|
||||||
|
--COMPOSER--
|
||||||
|
{
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "package",
|
||||||
|
"package": [
|
||||||
|
{
|
||||||
|
"name": "a/a", "version": "dev-master",
|
||||||
|
"extra": { "branch-alias": { "dev-master": "2.1.x-dev" } },
|
||||||
|
"source": { "reference": "newmaster-a2", "type": "git", "url": "" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "b/b", "version": "dev-master",
|
||||||
|
"extra": { "branch-alias": { "dev-master": "2.1.x-dev" } },
|
||||||
|
"source": { "reference": "newmaster-b2", "type": "git", "url": "" }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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-a", "type": "git", "url": "" },
|
||||||
|
"type": "library"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "b/b", "version": "dev-master", "version_normalized": "9999999-dev",
|
||||||
|
"extra": { "branch-alias": { "dev-master": "2.1.x-dev" } },
|
||||||
|
"source": { "reference": "oldmaster-b", "type": "git", "url": "" },
|
||||||
|
"type": "library"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
--LOCK--
|
||||||
|
{
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "a/a", "version": "dev-master",
|
||||||
|
"extra": { "branch-alias": { "dev-master": "2.1.x-dev" } },
|
||||||
|
"source": { "reference": "newmaster-a", "type": "git", "url": "" },
|
||||||
|
"type": "library"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "b/b", "version": "dev-master",
|
||||||
|
"extra": { "branch-alias": { "dev-master": "2.1.x-dev" } },
|
||||||
|
"source": { "reference": "oldmaster-b", "type": "git", "url": "" },
|
||||||
|
"type": "library"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packages-dev": [],
|
||||||
|
"aliases": [],
|
||||||
|
"minimum-stability": "dev",
|
||||||
|
"stability-flags": [],
|
||||||
|
"prefer-stable": false,
|
||||||
|
"prefer-lowest": false,
|
||||||
|
"platform": [],
|
||||||
|
"platform-dev": []
|
||||||
|
}
|
||||||
|
--RUN--
|
||||||
|
update b/b
|
||||||
|
--EXPECT-LOCK--
|
||||||
|
{
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "a/a", "version": "dev-master",
|
||||||
|
"extra": { "branch-alias": { "dev-master": "2.1.x-dev" } },
|
||||||
|
"source": { "reference": "newmaster-a", "type": "git", "url": "" },
|
||||||
|
"type": "library"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "b/b", "version": "dev-master",
|
||||||
|
"extra": { "branch-alias": { "dev-master": "2.1.x-dev" } },
|
||||||
|
"source": { "reference": "newmaster-b2", "type": "git", "url": "" },
|
||||||
|
"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-a) to a/a (dev-master newmaster-a)
|
||||||
|
Updating b/b (dev-master oldmaster-b) to b/b (dev-master newmaster-b2)
|
|
@ -65,6 +65,6 @@ update b/unstable
|
||||||
"platform-dev": []
|
"platform-dev": []
|
||||||
}
|
}
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
|
Updating b/unstable (1.1.0-alpha) to b/unstable (1.0.0)
|
||||||
Updating a/old (0.9.0) to a/old (1.0.0)
|
Updating a/old (0.9.0) to a/old (1.0.0)
|
||||||
Updating c/uptodate (2.0.0) to c/uptodate (1.0.0)
|
Updating c/uptodate (2.0.0) to c/uptodate (1.0.0)
|
||||||
Updating b/unstable (1.1.0-alpha) to b/unstable (1.0.0)
|
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
--TEST--
|
||||||
|
Partial update installs from lock even if package don't exist in public repo anymore
|
||||||
|
--COMPOSER--
|
||||||
|
{
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "package",
|
||||||
|
"package": [
|
||||||
|
{
|
||||||
|
"name": "a/a", "version": "dev-master",
|
||||||
|
"extra": { "branch-alias": { "dev-master": "2.3.x-dev" } },
|
||||||
|
"source": { "reference": "newmaster-a2", "type": "git", "url": "" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "b/b", "version": "dev-master",
|
||||||
|
"extra": { "branch-alias": { "dev-master": "2.3.x-dev" } },
|
||||||
|
"source": { "reference": "newmaster-b2", "type": "git", "url": "" },
|
||||||
|
"require": { "a/a": "dev-master" }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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-a", "type": "git", "url": "" },
|
||||||
|
"type": "library"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "b/b", "version": "dev-master", "version_normalized": "9999999-dev",
|
||||||
|
"extra": { "branch-alias": { "dev-master": "2.1.x-dev" } },
|
||||||
|
"source": { "reference": "oldmaster-b", "type": "git", "url": "" },
|
||||||
|
"require": { "a/a": "dev-master" },
|
||||||
|
"type": "library"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
--LOCK--
|
||||||
|
{
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "a/a", "version": "dev-master",
|
||||||
|
"extra": { "branch-alias": { "dev-master": "2.2.x-dev" } },
|
||||||
|
"source": { "reference": "newmaster-a", "type": "git", "url": "" },
|
||||||
|
"type": "library"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "b/b", "version": "dev-master",
|
||||||
|
"extra": { "branch-alias": { "dev-master": "2.1.x-dev" } },
|
||||||
|
"source": { "reference": "oldmaster-b", "type": "git", "url": "" },
|
||||||
|
"require": { "a/a": "dev-master" },
|
||||||
|
"type": "library"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packages-dev": [],
|
||||||
|
"aliases": [],
|
||||||
|
"minimum-stability": "dev",
|
||||||
|
"stability-flags": [],
|
||||||
|
"prefer-stable": false,
|
||||||
|
"prefer-lowest": false,
|
||||||
|
"platform": [],
|
||||||
|
"platform-dev": []
|
||||||
|
}
|
||||||
|
--RUN--
|
||||||
|
update b/b
|
||||||
|
--EXPECT-LOCK--
|
||||||
|
{
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "a/a", "version": "dev-master",
|
||||||
|
"extra": { "branch-alias": { "dev-master": "2.2.x-dev" } },
|
||||||
|
"source": { "reference": "newmaster-a", "type": "git", "url": "" },
|
||||||
|
"type": "library"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "b/b", "version": "dev-master",
|
||||||
|
"extra": { "branch-alias": { "dev-master": "2.3.x-dev" } },
|
||||||
|
"source": { "reference": "newmaster-b2", "type": "git", "url": "" },
|
||||||
|
"require": { "a/a": "dev-master" },
|
||||||
|
"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-a) to a/a (dev-master newmaster-a)
|
||||||
|
Updating b/b (dev-master oldmaster-b) to b/b (dev-master newmaster-b2)
|
||||||
|
Marking a/a (2.2.x-dev newmaster-a) as installed, alias of a/a (dev-master newmaster-a)
|
||||||
|
Marking b/b (2.3.x-dev newmaster-b2) as installed, alias of b/b (dev-master newmaster-b2)
|
||||||
|
Marking b/b (2.1.x-dev oldmaster-b) as uninstalled, alias of b/b (dev-master oldmaster-b)
|
||||||
|
Marking a/a (2.1.x-dev oldmaster-a) as uninstalled, alias of a/a (dev-master oldmaster-a)
|
|
@ -31,6 +31,7 @@ Update aliased package does not mess up the lock file
|
||||||
}
|
}
|
||||||
--LOCK--
|
--LOCK--
|
||||||
{
|
{
|
||||||
|
"_": "outdated lock file, should not have to be loaded in an update",
|
||||||
"packages": [
|
"packages": [
|
||||||
{ "package": "a/a", "version": "dev-master", "source-reference": "1234" },
|
{ "package": "a/a", "version": "dev-master", "source-reference": "1234" },
|
||||||
{ "package": "a/a", "version": "dev-master", "alias-pretty-version": "1.0.x-dev", "alias-version": "1.0.9999999.9999999-dev" }
|
{ "package": "a/a", "version": "dev-master", "alias-pretty-version": "1.0.x-dev", "alias-version": "1.0.9999999.9999999-dev" }
|
||||||
|
|
|
@ -43,6 +43,6 @@ Limited update takes rules from lock if available, and not from the installed re
|
||||||
--RUN--
|
--RUN--
|
||||||
update toupdate/installed
|
update toupdate/installed
|
||||||
--EXPECT--
|
--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)
|
Updating toupdate/installed (1.0.0) to toupdate/installed (1.1.0)
|
||||||
|
Updating old/installed (0.9.0) to old/installed (1.0.0)
|
||||||
Installing toupdate/notinstalled (1.0.0)
|
Installing toupdate/notinstalled (1.0.0)
|
||||||
|
|
Loading…
Reference in New Issue