/** * Run installation (or update) * * @return int 0 on success or a positive error code on failure * * @throws \Exception */ public function run() { gc_collect_cycles(); gc_disable(); if ($this->dryRun) { $this->verbose = true; $this->runScripts = false; $this->installationManager->addInstaller(new NoopInstaller()); $this->mockLocalRepositories($this->repositoryManager); } // TODO remove this BC feature at some point // purge old require-dev packages to avoid conflicts with the new way of handling dev requirements $devRepo = new InstalledFilesystemRepository(new JsonFile($this->config->get('vendor-dir') . '/composer/installed_dev.json')); if ($devRepo->getPackages()) { $this->io->writeError('<warning>BC Notice: Removing old dev packages to migrate to the new require-dev handling.</warning>'); foreach ($devRepo->getPackages() as $package) { if ($this->installationManager->isPackageInstalled($devRepo, $package)) { $this->installationManager->uninstall($devRepo, new UninstallOperation($package)); } } unlink($this->config->get('vendor-dir') . '/composer/installed_dev.json'); } unset($devRepo, $package); // end BC if ($this->runScripts) { // dispatch pre event $eventName = $this->update ? ScriptEvents::PRE_UPDATE_CMD : ScriptEvents::PRE_INSTALL_CMD; $this->eventDispatcher->dispatchScript($eventName, $this->devMode); } $this->downloadManager->setPreferSource($this->preferSource); $this->downloadManager->setPreferDist($this->preferDist); // clone root package to have one in the installed repo that does not require anything // we don't want it to be uninstallable, but its requirements should not conflict // with the lock file for example $installedRootPackage = clone $this->package; $installedRootPackage->setRequires(array()); $installedRootPackage->setDevRequires(array()); // create installed repo, this contains all local packages + platform packages (php & extensions) $localRepo = $this->repositoryManager->getLocalRepository(); $platformRepo = new PlatformRepository(); $repos = array($localRepo, new InstalledArrayRepository(array($installedRootPackage)), $platformRepo); $installedRepo = new CompositeRepository($repos); if ($this->additionalInstalledRepository) { $installedRepo->addRepository($this->additionalInstalledRepository); } $aliases = $this->getRootAliases(); $this->aliasPlatformPackages($platformRepo, $aliases); try { $this->suggestedPackages = array(); $res = $this->doInstall($localRepo, $installedRepo, $platformRepo, $aliases, $this->devMode); if ($res !== 0) { return $res; } } catch (\Exception $e) { $this->installationManager->notifyInstalls(); throw $e; } $this->installationManager->notifyInstalls(); // output suggestions if we're in dev mode if ($this->devMode) { foreach ($this->suggestedPackages as $suggestion) { $target = $suggestion['target']; foreach ($installedRepo->getPackages() as $package) { if (in_array($target, $package->getNames())) { continue 2; } } $this->io->writeError($suggestion['source'] . ' suggests installing ' . $suggestion['target'] . ' (' . $suggestion['reason'] . ')'); } } # Find abandoned packages and warn user foreach ($localRepo->getPackages() as $package) { if (!$package instanceof CompletePackage || !$package->isAbandoned()) { continue; } $replacement = is_string($package->getReplacementPackage()) ? 'Use ' . $package->getReplacementPackage() . ' instead' : 'No replacement was suggested'; $this->io->writeError(sprintf("<error>Package %s is abandoned, you should avoid using it. %s.</error>", $package->getPrettyName(), $replacement)); } if (!$this->dryRun) { // write lock if ($this->update || !$this->locker->isLocked()) { $localRepo->reload(); // if this is not run in dev mode and the root has dev requires, the lock must // contain null to prevent dev installs from a non-dev lock $devPackages = $this->devMode || !$this->package->getDevRequires() ? array() : null; // split dev and non-dev requirements by checking what would be removed if we update without the dev requirements if ($this->devMode && $this->package->getDevRequires()) { $policy = $this->createPolicy(); $pool = $this->createPool(true); $pool->addRepository($installedRepo, $aliases); // creating requirements request $request = $this->createRequest($pool, $this->package, $platformRepo); $request->updateAll(); foreach ($this->package->getRequires() as $link) { $request->install($link->getTarget(), $link->getConstraint()); } $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, false, $policy, $pool, $installedRepo, $request); $solver = new Solver($policy, $pool, $installedRepo); $ops = $solver->solve($request, $this->ignorePlatformReqs); $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, false, $policy, $pool, $installedRepo, $request, $ops); foreach ($ops as $op) { if ($op->getJobType() === 'uninstall') { $devPackages[] = $op->getPackage(); } } } $platformReqs = $this->extractPlatformRequirements($this->package->getRequires()); $platformDevReqs = $this->devMode ? $this->extractPlatformRequirements($this->package->getDevRequires()) : array(); $updatedLock = $this->locker->setLockData(array_diff($localRepo->getCanonicalPackages(), (array) $devPackages), $devPackages, $platformReqs, $platformDevReqs, $aliases, $this->package->getMinimumStability(), $this->package->getStabilityFlags(), $this->preferStable || $this->package->getPreferStable(), $this->preferLowest); if ($updatedLock) { $this->io->writeError('<info>Writing lock file</info>'); } } if ($this->dumpAutoloader) { // write autoloader if ($this->optimizeAutoloader) { $this->io->writeError('<info>Generating optimized autoload files</info>'); } else { $this->io->writeError('<info>Generating autoload files</info>'); } $this->autoloadGenerator->setDevMode($this->devMode); $this->autoloadGenerator->dump($this->config, $localRepo, $this->package, $this->installationManager, 'composer', $this->optimizeAutoloader); } if ($this->runScripts) { // dispatch post event $eventName = $this->update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD; $this->eventDispatcher->dispatchScript($eventName, $this->devMode); } $vendorDir = $this->config->get('vendor-dir'); if (is_dir($vendorDir)) { touch($vendorDir); } } return 0; }
/** * Run installation (or update) */ public function run() { if ($this->dryRun) { $this->verbose = true; $this->runScripts = false; $this->installationManager->addInstaller(new NoopInstaller()); $this->mockLocalRepositories($this->repositoryManager); } // TODO remove this BC feature at some point // purge old require-dev packages to avoid conflicts with the new way of handling dev requirements $devRepo = new InstalledFilesystemRepository(new JsonFile($this->config->get('vendor-dir') . '/composer/installed_dev.json')); if ($devRepo->getPackages()) { $this->io->write('<warning>BC Notice: Removing old dev packages to migrate to the new require-dev handling.</warning>'); foreach ($devRepo->getPackages() as $package) { if ($this->installationManager->isPackageInstalled($devRepo, $package)) { $this->installationManager->uninstall($devRepo, new UninstallOperation($package)); } } unlink($this->config->get('vendor-dir') . '/composer/installed_dev.json'); } unset($devRepo, $package); // end BC if ($this->preferSource) { $this->downloadManager->setPreferSource(true); } if ($this->preferDist) { $this->downloadManager->setPreferDist(true); } // create installed repo, this contains all local packages + platform packages (php & extensions) $installedRootPackage = clone $this->package; $installedRootPackage->setRequires(array()); $installedRootPackage->setDevRequires(array()); $localRepo = $this->repositoryManager->getLocalRepository(); $platformRepo = new PlatformRepository(); $repos = array($localRepo, new InstalledArrayRepository(array($installedRootPackage)), $platformRepo); $installedRepo = new CompositeRepository($repos); if ($this->additionalInstalledRepository) { $installedRepo->addRepository($this->additionalInstalledRepository); } $aliases = $this->getRootAliases(); $this->aliasPlatformPackages($platformRepo, $aliases); if ($this->runScripts) { // dispatch pre event $eventName = $this->update ? ScriptEvents::PRE_UPDATE_CMD : ScriptEvents::PRE_INSTALL_CMD; $this->eventDispatcher->dispatchCommandEvent($eventName, $this->devMode); } try { $this->suggestedPackages = array(); if (!$this->doInstall($localRepo, $installedRepo, $platformRepo, $aliases, $this->devMode)) { return false; } } catch (\Exception $e) { $this->installationManager->notifyInstalls(); throw $e; } $this->installationManager->notifyInstalls(); // output suggestions foreach ($this->suggestedPackages as $suggestion) { $target = $suggestion['target']; foreach ($installedRepo->getPackages() as $package) { if (in_array($target, $package->getNames())) { continue 2; } } $this->io->write($suggestion['source'] . ' suggests installing ' . $suggestion['target'] . ' (' . $suggestion['reason'] . ')'); } if (!$this->dryRun) { // write lock if ($this->update || !$this->locker->isLocked()) { $localRepo->reload(); // if this is not run in dev mode and the root has dev requires, the lock must // contain null to prevent dev installs from a non-dev lock $devPackages = $this->devMode || !$this->package->getDevRequires() ? array() : null; // split dev and non-dev requirements by checking what would be removed if we update without the dev requirements if ($this->devMode && $this->package->getDevRequires()) { $policy = $this->createPolicy(); $pool = $this->createPool(); $pool->addRepository($installedRepo, $aliases); // creating requirements request $request = $this->createRequest($pool, $this->package, $platformRepo); $request->updateAll(); foreach ($this->package->getRequires() as $link) { $request->install($link->getTarget(), $link->getConstraint()); } $solver = new Solver($policy, $pool, $installedRepo); $ops = $solver->solve($request); foreach ($ops as $op) { if ($op->getJobType() === 'uninstall') { $devPackages[] = $op->getPackage(); } } } $platformReqs = $this->extractPlatformRequirements($this->package->getRequires()); $platformDevReqs = $this->devMode ? $this->extractPlatformRequirements($this->package->getDevRequires()) : array(); $updatedLock = $this->locker->setLockData(array_diff($localRepo->getPackages(), (array) $devPackages), $devPackages, $platformReqs, $platformDevReqs, $aliases, $this->package->getMinimumStability(), $this->package->getStabilityFlags()); if ($updatedLock) { $this->io->write('<info>Writing lock file</info>'); } } // write autoloader $this->io->write('<info>Generating autoload files</info>'); $this->autoloadGenerator->dump($this->config, $localRepo, $this->package, $this->installationManager, 'composer', $this->optimizeAutoloader); if ($this->runScripts) { // dispatch post event $eventName = $this->update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD; $this->eventDispatcher->dispatchCommandEvent($eventName, $this->devMode); } } return true; }
/** * Run installation (or update) * * @throws \Exception * @return int 0 on success or a positive error code on failure */ public function run() { // Disable GC to save CPU cycles, as the dependency solver can create hundreds of thousands // of PHP objects, the GC can spend quite some time walking the tree of references looking // for stuff to collect while there is nothing to collect. This slows things down dramatically // and turning it off results in much better performance. Do not try this at home however. gc_collect_cycles(); gc_disable(); if ($this->dryRun) { $this->verbose = true; $this->runScripts = false; $this->installationManager->addInstaller(new NoopInstaller()); $this->mockLocalRepositories($this->repositoryManager); } if ($this->runScripts) { // dispatch pre event $eventName = $this->update ? ScriptEvents::PRE_UPDATE_CMD : ScriptEvents::PRE_INSTALL_CMD; $this->eventDispatcher->dispatchScript($eventName, $this->devMode); } $this->downloadManager->setPreferSource($this->preferSource); $this->downloadManager->setPreferDist($this->preferDist); // clone root package to have one in the installed repo that does not require anything // we don't want it to be uninstallable, but its requirements should not conflict // with the lock file for example $installedRootPackage = clone $this->package; $installedRootPackage->setRequires(array()); $installedRootPackage->setDevRequires(array()); // create installed repo, this contains all local packages + platform packages (php & extensions) $localRepo = $this->repositoryManager->getLocalRepository(); if (!$this->update && $this->locker->isLocked()) { $platformOverrides = $this->locker->getPlatformOverrides(); } else { $platformOverrides = $this->config->get('platform') ?: array(); } $platformRepo = new PlatformRepository(array(), $platformOverrides); $repos = array($localRepo, new InstalledArrayRepository(array($installedRootPackage)), $platformRepo); $installedRepo = new CompositeRepository($repos); if ($this->additionalInstalledRepository) { $installedRepo->addRepository($this->additionalInstalledRepository); } $aliases = $this->getRootAliases(); $this->aliasPlatformPackages($platformRepo, $aliases); try { $this->suggestedPackages = array(); $res = $this->doInstall($localRepo, $installedRepo, $platformRepo, $aliases, $this->devMode); if ($res !== 0) { return $res; } } catch (\Exception $e) { if (!$this->dryRun) { $this->installationManager->notifyInstalls($this->io); } throw $e; } if (!$this->dryRun) { $this->installationManager->notifyInstalls($this->io); } // output suggestions if we're in dev mode if ($this->devMode) { foreach ($this->suggestedPackages as $suggestion) { $target = $suggestion['target']; foreach ($installedRepo->getPackages() as $package) { if (in_array($target, $package->getNames())) { continue 2; } } $this->io->writeError($suggestion['source'] . ' suggests installing ' . $suggestion['target'] . ' (' . $suggestion['reason'] . ')'); } } # Find abandoned packages and warn user foreach ($localRepo->getPackages() as $package) { if (!$package instanceof CompletePackage || !$package->isAbandoned()) { continue; } $replacement = is_string($package->getReplacementPackage()) ? 'Use ' . $package->getReplacementPackage() . ' instead' : 'No replacement was suggested'; $this->io->writeError(sprintf("<warning>Package %s is abandoned, you should avoid using it. %s.</warning>", $package->getPrettyName(), $replacement)); } if (!$this->dryRun) { // write lock if ($this->update || !$this->locker->isLocked()) { $localRepo->reload(); // if this is not run in dev mode and the root has dev requires, the lock must // contain null to prevent dev installs from a non-dev lock $devPackages = $this->devMode || !$this->package->getDevRequires() ? array() : null; // split dev and non-dev requirements by checking what would be removed if we update without the dev requirements if ($this->devMode && $this->package->getDevRequires()) { $policy = $this->createPolicy(); $pool = $this->createPool(true); $pool->addRepository($installedRepo, $aliases); // creating requirements request $request = $this->createRequest($this->package, $platformRepo); $request->updateAll(); foreach ($this->package->getRequires() as $link) { $request->install($link->getTarget(), $link->getConstraint()); } $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, false, $policy, $pool, $installedRepo, $request); $solver = new Solver($policy, $pool, $installedRepo); $ops = $solver->solve($request, $this->ignorePlatformReqs); $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, false, $policy, $pool, $installedRepo, $request, $ops); foreach ($ops as $op) { if ($op->getJobType() === 'uninstall') { $devPackages[] = $op->getPackage(); } } } $platformReqs = $this->extractPlatformRequirements($this->package->getRequires()); $platformDevReqs = $this->devMode ? $this->extractPlatformRequirements($this->package->getDevRequires()) : array(); $updatedLock = $this->locker->setLockData(array_diff($localRepo->getCanonicalPackages(), (array) $devPackages), $devPackages, $platformReqs, $platformDevReqs, $aliases, $this->package->getMinimumStability(), $this->package->getStabilityFlags(), $this->preferStable || $this->package->getPreferStable(), $this->preferLowest, $this->config->get('platform') ?: array()); if ($updatedLock) { $this->io->writeError('<info>Writing lock file</info>'); } } if ($this->dumpAutoloader) { // write autoloader if ($this->optimizeAutoloader) { $this->io->writeError('<info>Generating optimized autoload files</info>'); } else { $this->io->writeError('<info>Generating autoload files</info>'); } $this->autoloadGenerator->setDevMode($this->devMode); $this->autoloadGenerator->setClassMapAuthoritative($this->classMapAuthoritative); $this->autoloadGenerator->setRunScripts($this->runScripts); $this->autoloadGenerator->dump($this->config, $localRepo, $this->package, $this->installationManager, 'composer', $this->optimizeAutoloader); } if ($this->runScripts) { // dispatch post event $eventName = $this->update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD; $this->eventDispatcher->dispatchScript($eventName, $this->devMode); } $vendorDir = $this->config->get('vendor-dir'); if (is_dir($vendorDir)) { // suppress errors as this fails sometimes on OSX for no apparent reason // see https://github.com/composer/composer/issues/4070#issuecomment-129792748 @touch($vendorDir); } } // re-enable GC except on HHVM which triggers a warning here if (!defined('HHVM_VERSION')) { gc_enable(); } return 0; }
/** * Run installation (or update) * * @throws \Exception * @return int 0 on success or a positive error code on failure */ public function run() { // Disable GC to save CPU cycles, as the dependency solver can create hundreds of thousands // of PHP objects, the GC can spend quite some time walking the tree of references looking // for stuff to collect while there is nothing to collect. This slows things down dramatically // and turning it off results in much better performance. Do not try this at home however. gc_collect_cycles(); gc_disable(); // Force update if there is no lock file present if (!$this->update && !$this->locker->isLocked()) { $this->update = true; } if ($this->dryRun) { $this->verbose = true; $this->runScripts = false; $this->installationManager->addInstaller(new NoopInstaller()); $this->mockLocalRepositories($this->repositoryManager); } if ($this->runScripts) { // dispatch pre event $eventName = $this->update ? ScriptEvents::PRE_UPDATE_CMD : ScriptEvents::PRE_INSTALL_CMD; $this->eventDispatcher->dispatchScript($eventName, $this->devMode); } $this->downloadManager->setPreferSource($this->preferSource); $this->downloadManager->setPreferDist($this->preferDist); // create installed repo, this contains all local packages + platform packages (php & extensions) $localRepo = $this->repositoryManager->getLocalRepository(); if ($this->update) { $platformOverrides = $this->config->get('platform') ?: array(); } else { $platformOverrides = $this->locker->getPlatformOverrides(); } $platformRepo = new PlatformRepository(array(), $platformOverrides); $installedRepo = $this->createInstalledRepo($localRepo, $platformRepo); $aliases = $this->getRootAliases(); $this->aliasPlatformPackages($platformRepo, $aliases); if (!$this->suggestedPackagesReporter) { $this->suggestedPackagesReporter = new SuggestedPackagesReporter($this->io); } try { list($res, $devPackages) = $this->doInstall($localRepo, $installedRepo, $platformRepo, $aliases); if ($res !== 0) { return $res; } } catch (\Exception $e) { if (!$this->dryRun) { $this->installationManager->notifyInstalls($this->io); } throw $e; } if (!$this->dryRun) { $this->installationManager->notifyInstalls($this->io); } // output suggestions if we're in dev mode if ($this->devMode && !$this->skipSuggest) { $this->suggestedPackagesReporter->output($installedRepo); } # Find abandoned packages and warn user foreach ($localRepo->getPackages() as $package) { if (!$package instanceof CompletePackage || !$package->isAbandoned()) { continue; } $replacement = is_string($package->getReplacementPackage()) ? 'Use ' . $package->getReplacementPackage() . ' instead' : 'No replacement was suggested'; $this->io->writeError(sprintf("<warning>Package %s is abandoned, you should avoid using it. %s.</warning>", $package->getPrettyName(), $replacement)); } if (!$this->dryRun) { // write lock if ($this->update) { $localRepo->reload(); $platformReqs = $this->extractPlatformRequirements($this->package->getRequires()); $platformDevReqs = $this->extractPlatformRequirements($this->package->getDevRequires()); $updatedLock = $this->locker->setLockData(array_diff($localRepo->getCanonicalPackages(), $devPackages), $devPackages, $platformReqs, $platformDevReqs, $aliases, $this->package->getMinimumStability(), $this->package->getStabilityFlags(), $this->preferStable || $this->package->getPreferStable(), $this->preferLowest, $this->config->get('platform') ?: array()); if ($updatedLock) { $this->io->writeError('<info>Writing lock file</info>'); } } if ($this->dumpAutoloader) { // write autoloader if ($this->optimizeAutoloader) { $this->io->writeError('<info>Generating optimized autoload files</info>'); } else { $this->io->writeError('<info>Generating autoload files</info>'); } $this->autoloadGenerator->setDevMode($this->devMode); $this->autoloadGenerator->setClassMapAuthoritative($this->classMapAuthoritative); $this->autoloadGenerator->setRunScripts($this->runScripts); $this->autoloadGenerator->dump($this->config, $localRepo, $this->package, $this->installationManager, 'composer', $this->optimizeAutoloader); } if ($this->runScripts) { $devMode = (int) $this->devMode; putenv("COMPOSER_DEV_MODE={$devMode}"); // dispatch post event $eventName = $this->update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD; $this->eventDispatcher->dispatchScript($eventName, $this->devMode); } // force binaries re-generation in case they are missing foreach ($localRepo->getPackages() as $package) { $this->installationManager->ensureBinariesPresence($package); } $vendorDir = $this->config->get('vendor-dir'); if (is_dir($vendorDir)) { // suppress errors as this fails sometimes on OSX for no apparent reason // see https://github.com/composer/composer/issues/4070#issuecomment-129792748 @touch($vendorDir); } } // re-enable GC except on HHVM which triggers a warning here if (!defined('HHVM_VERSION')) { gc_enable(); } return 0; }
/** * Run installation (or update) */ public function run() { if ($this->dryRun) { $this->verbose = true; $this->runScripts = false; $this->installationManager->addInstaller(new NoopInstaller()); $this->mockLocalRepositories($this->repositoryManager); } if ($this->preferSource) { $this->downloadManager->setPreferSource(true); } if ($this->preferDist) { $this->downloadManager->setPreferDist(true); } // create installed repo, this contains all local packages + platform packages (php & extensions) $installedRootPackage = clone $this->package; $installedRootPackage->setRequires(array()); $installedRootPackage->setDevRequires(array()); $platformRepo = new PlatformRepository(); $repos = array_merge($this->repositoryManager->getLocalRepositories(), array(new InstalledArrayRepository(array($installedRootPackage)), $platformRepo)); $installedRepo = new CompositeRepository($repos); if ($this->additionalInstalledRepository) { $installedRepo->addRepository($this->additionalInstalledRepository); } $aliases = $this->getRootAliases(); $this->aliasPlatformPackages($platformRepo, $aliases); if ($this->runScripts) { // dispatch pre event $eventName = $this->update ? ScriptEvents::PRE_UPDATE_CMD : ScriptEvents::PRE_INSTALL_CMD; $this->eventDispatcher->dispatchCommandEvent($eventName, $this->devMode); } try { $this->suggestedPackages = array(); if (!$this->doInstall($this->repositoryManager->getLocalRepository(), $installedRepo, $aliases)) { return false; } if ($this->devMode) { if (!$this->doInstall($this->repositoryManager->getLocalDevRepository(), $installedRepo, $aliases, true)) { return false; } } } catch (\Exception $e) { $this->installationManager->notifyInstalls(); throw $e; } $this->installationManager->notifyInstalls(); // output suggestions foreach ($this->suggestedPackages as $suggestion) { $target = $suggestion['target']; if ($installedRepo->filterPackages(function (PackageInterface $package) use($target) { if (in_array($target, $package->getNames())) { return false; } })) { $this->io->write($suggestion['source'] . ' suggests installing ' . $suggestion['target'] . ' (' . $suggestion['reason'] . ')'); } } if (!$this->dryRun) { // write lock if ($this->update || !$this->locker->isLocked()) { $updatedLock = $this->locker->setLockData($this->repositoryManager->getLocalRepository()->getPackages(), $this->devMode ? $this->repositoryManager->getLocalDevRepository()->getPackages() : null, $aliases, $this->package->getMinimumStability(), $this->package->getStabilityFlags()); if ($updatedLock) { $this->io->write('<info>Writing lock file</info>'); } } // write autoloader $this->io->write('<info>Generating autoload files</info>'); $localRepos = new CompositeRepository($this->repositoryManager->getLocalRepositories()); $this->autoloadGenerator->dump($this->config, $localRepos, $this->package, $this->installationManager, 'composer', $this->optimizeAutoloader); if ($this->runScripts) { // dispatch post event $eventName = $this->update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD; $this->eventDispatcher->dispatchCommandEvent($eventName, $this->devMode); } } return true; }