1
0
Fork 0

Change installs into updates if there is no lock file, simplify some code, fixes #5034

pull/5035/head
Jordi Boggiano 2016-03-10 18:36:58 +00:00
parent 653326e215
commit 55b0ed8c8b
9 changed files with 116 additions and 132 deletions

View File

@ -171,6 +171,11 @@ class Installer
gc_collect_cycles(); gc_collect_cycles();
gc_disable(); gc_disable();
// Force update if there is no lock file present
if (!$this->update && !$this->locker->isLocked()) {
$this->update = true;
}
if ($this->dryRun) { if ($this->dryRun) {
$this->verbose = true; $this->verbose = true;
$this->runScripts = false; $this->runScripts = false;
@ -196,10 +201,10 @@ class Installer
// create installed repo, this contains all local packages + platform packages (php & extensions) // create installed repo, this contains all local packages + platform packages (php & extensions)
$localRepo = $this->repositoryManager->getLocalRepository(); $localRepo = $this->repositoryManager->getLocalRepository();
if (!$this->update && $this->locker->isLocked()) { if ($this->update) {
$platformOverrides = $this->locker->getPlatformOverrides();
} else {
$platformOverrides = $this->config->get('platform') ?: array(); $platformOverrides = $this->config->get('platform') ?: array();
} else {
$platformOverrides = $this->locker->getPlatformOverrides();
} }
$platformRepo = new PlatformRepository(array(), $platformOverrides); $platformRepo = new PlatformRepository(array(), $platformOverrides);
$repos = array( $repos = array(
@ -261,7 +266,7 @@ class Installer
if (!$this->dryRun) { if (!$this->dryRun) {
// write lock // write lock
if ($this->update || !$this->locker->isLocked()) { if ($this->update) {
$localRepo->reload(); $localRepo->reload();
// if this is not run in dev mode and the root has dev requires, the lock must // if this is not run in dev mode and the root has dev requires, the lock must
@ -362,13 +367,10 @@ class Installer
$lockedRepository = null; $lockedRepository = null;
$repositories = null; $repositories = null;
// initialize locker to create aliased packages
$installFromLock = !$this->update && $this->locker->isLocked();
// initialize locked repo if we are installing from lock or in a partial update // 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 // and a lock file is present as we need to force install non-whitelisted lock file
// packages in that case // packages in that case
if ($installFromLock || (!empty($this->updateWhitelist) && $this->locker->isLocked())) { if (!$this->update || (!empty($this->updateWhitelist) && $this->locker->isLocked())) {
try { try {
$lockedRepository = $this->locker->getLockedRepository($withDevReqs); $lockedRepository = $this->locker->getLockedRepository($withDevReqs);
} catch (\RuntimeException $e) { } catch (\RuntimeException $e) {
@ -392,9 +394,9 @@ class Installer
// creating repository pool // creating repository pool
$policy = $this->createPolicy(); $policy = $this->createPolicy();
$pool = $this->createPool($withDevReqs, $installFromLock ? $lockedRepository : null); $pool = $this->createPool($withDevReqs, $this->update ? null : $lockedRepository);
$pool->addRepository($installedRepo, $aliases); $pool->addRepository($installedRepo, $aliases);
if (!$installFromLock) { if ($this->update) {
$repositories = $this->repositoryManager->getRepositories(); $repositories = $this->repositoryManager->getRepositories();
foreach ($repositories as $repository) { foreach ($repositories as $repository) {
$pool->addRepository($repository, $aliases); $pool->addRepository($repository, $aliases);
@ -410,7 +412,7 @@ class Installer
// creating requirements request // creating requirements request
$request = $this->createRequest($this->package, $platformRepo); $request = $this->createRequest($this->package, $platformRepo);
if (!$installFromLock) { if ($this->update) {
// remove unstable packages from the localRepo if they don't match the current stability settings // remove unstable packages from the localRepo if they don't match the current stability settings
$removedUnstablePackages = array(); $removedUnstablePackages = array();
foreach ($localRepo->getPackages() as $package) { foreach ($localRepo->getPackages() as $package) {
@ -422,9 +424,7 @@ class Installer
$request->remove($package->getName(), new Constraint('=', $package->getVersion())); $request->remove($package->getName(), new Constraint('=', $package->getVersion()));
} }
} }
}
if ($this->update) {
$this->io->writeError('<info>Updating dependencies'.($withDevReqs ? ' (including require-dev)' : '').'</info>'); $this->io->writeError('<info>Updating dependencies'.($withDevReqs ? ' (including require-dev)' : '').'</info>');
$request->updateAll(); $request->updateAll();
@ -466,7 +466,7 @@ class Installer
} }
} }
} }
} elseif ($installFromLock) { } else {
$this->io->writeError('<info>Installing dependencies'.($withDevReqs ? ' (including require-dev)' : '').' from lock file</info>'); $this->io->writeError('<info>Installing dependencies'.($withDevReqs ? ' (including require-dev)' : '').' from lock file</info>');
if (!$this->locker->isFresh()) { if (!$this->locker->isFresh()) {
@ -486,22 +486,10 @@ class Installer
foreach ($this->locker->getPlatformRequirements($withDevReqs) as $link) { foreach ($this->locker->getPlatformRequirements($withDevReqs) as $link) {
$request->install($link->getTarget(), $link->getConstraint()); $request->install($link->getTarget(), $link->getConstraint());
} }
} else {
$this->io->writeError('<info>Installing dependencies'.($withDevReqs ? ' (including require-dev)' : '').'</info>');
if ($withDevReqs) {
$links = array_merge($this->package->getRequires(), $this->package->getDevRequires());
} else {
$links = $this->package->getRequires();
}
foreach ($links as $link) {
$request->install($link->getTarget(), $link->getConstraint());
}
} }
// 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, $installedRepo, $lockedRepository, $installFromLock, $withDevReqs, 'force-links'); $this->processDevPackages($localRepo, $pool, $policy, $repositories, $installedRepo, $lockedRepository, $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);
@ -520,7 +508,7 @@ class Installer
$this->io->writeError("Analyzed ".$solver->getRuleSetSize()." rules to resolve dependencies", true, IOInterface::VERBOSE); $this->io->writeError("Analyzed ".$solver->getRuleSetSize()." rules to resolve dependencies", true, IOInterface::VERBOSE);
// 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, $installedRepo, $lockedRepository, $installFromLock, $withDevReqs, 'force-updates', $operations); $operations = $this->processDevPackages($localRepo, $pool, $policy, $repositories, $installedRepo, $lockedRepository, $withDevReqs, 'force-updates', $operations);
// execute operations // execute operations
if (!$operations) { if (!$operations) {
@ -536,8 +524,8 @@ class Installer
$this->suggestedPackagesReporter->addSuggestionsFromPackage($operation->getPackage()); $this->suggestedPackagesReporter->addSuggestionsFromPackage($operation->getPackage());
} }
// not installing from lock, force dev packages' references if they're in root package refs // updating, force dev packages' references if they're in root package refs
if (!$installFromLock) { if ($this->update) {
$package = null; $package = null;
if ('update' === $operation->getJobType()) { if ('update' === $operation->getJobType()) {
$package = $operation->getTargetPackage(); $package = $operation->getTargetPackage();
@ -687,7 +675,15 @@ class Installer
*/ */
private function createPool($withDevReqs, RepositoryInterface $lockedRepository = null) private function createPool($withDevReqs, RepositoryInterface $lockedRepository = null)
{ {
if (!$this->update && $this->locker->isLocked()) { // install from lock if ($this->update) {
$minimumStability = $this->package->getMinimumStability();
$stabilityFlags = $this->package->getStabilityFlags();
$requires = $this->package->getRequires();
if ($withDevReqs) {
$requires = array_merge($requires, $this->package->getDevRequires());
}
} else {
$minimumStability = $this->locker->getMinimumStability(); $minimumStability = $this->locker->getMinimumStability();
$stabilityFlags = $this->locker->getStabilityFlags(); $stabilityFlags = $this->locker->getStabilityFlags();
@ -697,14 +693,6 @@ class Installer
$constraint->setPrettyString($package->getPrettyVersion()); $constraint->setPrettyString($package->getPrettyVersion());
$requires[$package->getName()] = $constraint; $requires[$package->getName()] = $constraint;
} }
} else {
$minimumStability = $this->package->getMinimumStability();
$stabilityFlags = $this->package->getStabilityFlags();
$requires = $this->package->getRequires();
if ($withDevReqs) {
$requires = array_merge($requires, $this->package->getDevRequires());
}
} }
$rootConstraints = array(); $rootConstraints = array();
@ -730,7 +718,7 @@ class Installer
{ {
$preferStable = null; $preferStable = null;
$preferLowest = null; $preferLowest = null;
if (!$this->update && $this->locker->isLocked()) { if (!$this->update) {
$preferStable = $this->locker->getPreferStable(); $preferStable = $this->locker->getPreferStable();
$preferLowest = $this->locker->getPreferLowest(); $preferLowest = $this->locker->getPreferLowest();
} }
@ -791,13 +779,12 @@ class Installer
* @param array $repositories * @param array $repositories
* @param RepositoryInterface $installedRepo * @param RepositoryInterface $installedRepo
* @param RepositoryInterface $lockedRepository * @param RepositoryInterface $lockedRepository
* @param bool $installFromLock
* @param bool $withDevReqs * @param bool $withDevReqs
* @param string $task * @param string $task
* @param array|null $operations * @param array|null $operations
* @return array * @return array
*/ */
private function processDevPackages($localRepo, $pool, $policy, $repositories, $installedRepo, $lockedRepository, $installFromLock, $withDevReqs, $task, array $operations = null) private function processDevPackages($localRepo, $pool, $policy, $repositories, $installedRepo, $lockedRepository, $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');
@ -806,7 +793,7 @@ class Installer
$operations = array(); $operations = array();
} }
if (!$installFromLock && $this->updateWhitelist) { if ($this->update && $this->updateWhitelist) {
$currentPackages = $this->getCurrentPackages($withDevReqs, $installedRepo); $currentPackages = $this->getCurrentPackages($withDevReqs, $installedRepo);
} }
@ -825,8 +812,81 @@ class Installer
} }
} }
// force update to locked version if it does not match the installed version if ($this->update) {
if ($installFromLock) { // skip package if the whitelist is enabled and it is not in it
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;
}
// find similar packages (name/version) in all repositories
$matches = $pool->whatProvides($package->getName(), new Constraint('=', $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]);
if ($task === 'force-links' && $newPackage) {
$package->setRequires($newPackage->getRequires());
$package->setConflicts($newPackage->getConflicts());
$package->setProvides($newPackage->getProvides());
$package->setReplaces($newPackage->getReplaces());
}
if ($task === 'force-updates' && $newPackage && (
(($newPackage->getSourceReference() && $newPackage->getSourceReference() !== $package->getSourceReference())
|| ($newPackage->getDistReference() && $newPackage->getDistReference() !== $package->getDistReference())
)
)) {
$operations[] = new UpdateOperation($package, $newPackage);
}
}
if ($task === 'force-updates') {
// 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()) {
// changing the source ref to update to will be handled in the operations loop below
$operations[] = new UpdateOperation($package, clone $package);
}
}
} else {
// force update to locked version if it does not match the installed version
foreach ($lockedRepository->findPackages($package->getName()) as $lockedPackage) { foreach ($lockedRepository->findPackages($package->getName()) as $lockedPackage) {
if ($lockedPackage->isDev() && $lockedPackage->getVersion() === $package->getVersion()) { if ($lockedPackage->isDev() && $lockedPackage->getVersion() === $package->getVersion()) {
if ($task === 'force-links') { if ($task === 'force-links') {
@ -845,82 +905,6 @@ class Installer
break; break;
} }
} }
} else {
// force update to latest on update
if ($this->update) {
// skip package if the whitelist is enabled and it is not in it
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;
}
// find similar packages (name/version) in all repositories
$matches = $pool->whatProvides($package->getName(), new Constraint('=', $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]);
if ($task === 'force-links' && $newPackage) {
$package->setRequires($newPackage->getRequires());
$package->setConflicts($newPackage->getConflicts());
$package->setProvides($newPackage->getProvides());
$package->setReplaces($newPackage->getReplaces());
}
if ($task === 'force-updates' && $newPackage && (
(($newPackage->getSourceReference() && $newPackage->getSourceReference() !== $package->getSourceReference())
|| ($newPackage->getDistReference() && $newPackage->getDistReference() !== $package->getDistReference())
)
)) {
$operations[] = new UpdateOperation($package, $newPackage);
}
}
}
if ($task === 'force-updates') {
// 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()) {
// changing the source ref to update to will be handled in the operations loop below
$operations[] = new UpdateOperation($package, clone $package);
}
}
} }
} }
@ -952,10 +936,10 @@ class Installer
*/ */
private function getRootAliases() private function getRootAliases()
{ {
if (!$this->update && $this->locker->isLocked()) { if ($this->update) {
$aliases = $this->locker->getAliases();
} else {
$aliases = $this->package->getAliases(); $aliases = $this->package->getAliases();
} else {
$aliases = $this->locker->getAliases();
} }
$normalizedAliases = array(); $normalizedAliases = array();

View File

@ -7,7 +7,7 @@ Installing seld/jsonlint (1.0.0)
Created project in %testDir% Created project in %testDir%
Loading composer repositories with package information Loading composer repositories with package information
Installing dependencies (including require-dev) Updating dependencies (including require-dev)
Nothing to install or update Nothing to install or update
Writing lock file Writing lock file
Generating autoload files Generating autoload files

View File

@ -25,7 +25,7 @@ Abandoned packages are flagged
install install
--EXPECT-OUTPUT-- --EXPECT-OUTPUT--
Loading composer repositories with package information Loading composer repositories with package information
Installing dependencies (including require-dev) Updating dependencies (including require-dev)
<warning>Package a/a is abandoned, you should avoid using it. No replacement was suggested.</warning> <warning>Package a/a is abandoned, you should avoid using it. No replacement was suggested.</warning>
<warning>Package c/c is abandoned, you should avoid using it. Use b/b instead.</warning> <warning>Package c/c is abandoned, you should avoid using it. Use b/b instead.</warning>
Writing lock file Writing lock file

View File

@ -22,7 +22,7 @@ Broken dependencies should not lead to a replacer being installed which is not m
install install
--EXPECT-OUTPUT-- --EXPECT-OUTPUT--
Loading composer repositories with package information Loading composer repositories with package information
Installing dependencies (including require-dev) Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages. Your requirements could not be resolved to an installable set of packages.
Problem 1 Problem 1

View File

@ -32,7 +32,7 @@ install
--EXPECT-OUTPUT-- --EXPECT-OUTPUT--
Loading composer repositories with package information Loading composer repositories with package information
Installing dependencies (including require-dev) Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages. Your requirements could not be resolved to an installable set of packages.
Problem 1 Problem 1

View File

@ -20,7 +20,7 @@ Suggestions are not displayed for installed packages
install install
--EXPECT-OUTPUT-- --EXPECT-OUTPUT--
Loading composer repositories with package information Loading composer repositories with package information
Installing dependencies (including require-dev) Updating dependencies (including require-dev)
Writing lock file Writing lock file
Generating autoload files Generating autoload files

View File

@ -18,7 +18,7 @@ Suggestions are not displayed in non-dev mode
install --no-dev install --no-dev
--EXPECT-OUTPUT-- --EXPECT-OUTPUT--
Loading composer repositories with package information Loading composer repositories with package information
Installing dependencies Updating dependencies
Writing lock file Writing lock file
Generating autoload files Generating autoload files

View File

@ -20,7 +20,7 @@ Suggestions are not displayed for packages if they are replaced
install install
--EXPECT-OUTPUT-- --EXPECT-OUTPUT--
Loading composer repositories with package information Loading composer repositories with package information
Installing dependencies (including require-dev) Updating dependencies (including require-dev)
Writing lock file Writing lock file
Generating autoload files Generating autoload files

View File

@ -18,7 +18,7 @@ Suggestions are displayed
install install
--EXPECT-OUTPUT-- --EXPECT-OUTPUT--
Loading composer repositories with package information Loading composer repositories with package information
Installing dependencies (including require-dev) Updating dependencies (including require-dev)
a/a suggests installing b/b (an obscure reason) a/a suggests installing b/b (an obscure reason)
Writing lock file Writing lock file
Generating autoload files Generating autoload files