/** * Executes composer for the extension. */ public function execute(InputInterface $input, OutputInterface $output) { $name = $this->argument('extension'); $update = $this->option('update'); if (!is_dir($path = $this->pagekit['path.extensions'] . "/{$name}") && file_exists("{$path}/extension.json")) { $this->error("Extension not exists '{$path}'"); exit; } $package = json_decode(file_get_contents("{$path}/extension.json"), true); if (!isset($package['composer']) || empty($package['composer'])) { $this->error("Composer not defined in '{$path}/extension.json'"); exit; } $this->loadComposer($path); $io = new ConsoleIO($input, $output, $this->getHelperSet()); $composer = Factory::create($io, $package['composer']); $lockFile = new JsonFile("{$path}/extension.lock"); $locker = new Locker($io, $lockFile, $composer->getRepositoryManager(), $composer->getInstallationManager(), md5(json_encode($package['composer']))); $composer->setLocker($locker); $installed = new JsonFile($this->pagekit['path'] . '/vendor/composer/installed.json'); $internal = new CompositeRepository([]); $internal->addRepository(new InstalledFilesystemRepository($installed)); $installer = Installer::create($io, $composer); $installer->setAdditionalInstalledRepository($internal); $installer->setUpdate($update); return $installer->run(); }
/** * Runs Composer Update command. * * @param array|bool $updates * @return bool */ protected function composerUpdate($updates = false) { $installed = new JsonFile($this->paths['path.vendor'] . '/composer/installed.json'); $internal = new CompositeRepository([]); $internal->addRepository(new InstalledFilesystemRepository($installed)); $composer = $this->getComposer(); $installer = Installer::create($this->getIO(), $composer)->setAdditionalInstalledRepository($internal)->setPreferDist(true)->setOptimizeAutoloader(true)->setUpdate(true); if ($updates) { $installer->setUpdateWhitelist($updates); } $installer->run(); }
/** * 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); } $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; } } // 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; }
/** * 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; }
/** * @return RepositoryInterface */ private function createInstalledRepo(RepositoryInterface $localRepo, PlatformRepository $platformRepo) { // 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()); $repos = array($localRepo, new InstalledArrayRepository(array($installedRootPackage)), $platformRepo); $installedRepo = new CompositeRepository($repos); if ($this->additionalInstalledRepository) { $installedRepo->addRepository($this->additionalInstalledRepository); } return $installedRepo; }
/** * 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; }
/** * Runs Composer Update command. * * @param array|bool $updates * @param array $refresh * @param bool $packagist * @param bool $preferSource * @return bool * @throws \Exception */ protected function composerUpdate($updates = false, $refresh = [], $packagist = false, $preferSource = false) { $installed = new JsonFile($this->paths['path.vendor'] . '/composer/installed.json'); $internal = new CompositeRepository([]); $internal->addRepository(new InstalledFilesystemRepository($installed)); $composer = $this->getComposer($packagist); $composer->getDownloadManager()->setOutputProgress(false); $local = $composer->getRepositoryManager()->getLocalRepository(); foreach ($refresh as $package) { $local->removePackage($package); } $installer = Installer::create($this->getIO(), $composer)->setAdditionalInstalledRepository($internal)->setOptimizeAutoloader(true)->setUpdate(true); if ($preferSource) { $installer->setPreferSource(true); } else { $installer->setPreferDist(true); } if ($updates) { $installer->setUpdateWhitelist($updates)->setWhitelistDependencies(); } $installer->run(); }
/** * Run installation (or update) */ public function run() { if ($this->dryRun) { $this->verbose = true; } if ($this->preferSource) { $this->downloadManager->setPreferSource(true); } // create installed repo, this contains all local packages + platform packages (php & extensions) $repos = array_merge($this->repositoryManager->getLocalRepositories(), array(new PlatformRepository())); $installedRepo = new CompositeRepository($repos); if ($this->additionalInstalledRepository) { $installedRepo->addRepository($this->additionalInstalledRepository); } $aliases = $this->aliasPackages(); if (!$this->dryRun) { // dispatch pre event $eventName = $this->update ? ScriptEvents::PRE_UPDATE_CMD : ScriptEvents::PRE_INSTALL_CMD; $this->eventDispatcher->dispatchCommandEvent($eventName); } $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; } } // dump suggestions foreach ($this->suggestedPackages as $suggestion) { $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); if ($updatedLock) { $this->io->write('<info>Writing lock file</info>'); } } // write autoloader $this->io->write('<info>Generating autoload files</info>'); $generator = new AutoloadGenerator(); $localRepos = new CompositeRepository($this->repositoryManager->getLocalRepositories()); $generator->dump($localRepos, $this->package, $this->installationManager, $this->installationManager->getVendorPath() . '/.composer'); // dispatch post event $eventName = $this->update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD; $this->eventDispatcher->dispatchCommandEvent($eventName); } return true; }
public function install(IOInterface $io, Composer $composer, EventDispatcher $eventDispatcher, $preferSource = false, $dryRun = false, $verbose = false, $noInstallRecommends = false, $installSuggests = false, $update = false, RepositoryInterface $additionalInstalledRepository = null) { if ($dryRun) { $verbose = true; } if ($preferSource) { $composer->getDownloadManager()->setPreferSource(true); } // create local repo, this contains all packages that are installed in the local project $localRepo = $composer->getRepositoryManager()->getLocalRepository(); // create installed repo, this contains all local packages + platform packages (php & extensions) $installedRepo = new CompositeRepository(array($localRepo, new PlatformRepository())); if ($additionalInstalledRepository) { $installedRepo->addRepository($additionalInstalledRepository); } // creating repository pool $pool = new Pool(); $pool->addRepository($installedRepo); foreach ($composer->getRepositoryManager()->getRepositories() as $repository) { $pool->addRepository($repository); } // dispatch pre event if (!$dryRun) { $eventName = $update ? ScriptEvents::PRE_UPDATE_CMD : ScriptEvents::PRE_INSTALL_CMD; $eventDispatcher->dispatchCommandEvent($eventName); } // creating requirements request $installFromLock = false; $request = new Request($pool); if ($update) { $io->write('<info>Updating dependencies</info>'); $installedPackages = $installedRepo->getPackages(); $links = $this->collectLinks($composer->getPackage(), $noInstallRecommends, $installSuggests); $request->updateAll(); foreach ($links as $link) { $request->install($link->getTarget(), $link->getConstraint()); } } elseif ($composer->getLocker()->isLocked()) { $installFromLock = true; $io->write('<info>Installing from lock file</info>'); if (!$composer->getLocker()->isFresh()) { $io->write('<warning>Your lock file is out of sync with your composer.json, run "composer.phar update" to update dependencies</warning>'); } foreach ($composer->getLocker()->getLockedPackages() as $package) { $constraint = new VersionConstraint('=', $package->getVersion()); $request->install($package->getName(), $constraint); } } else { $io->write('<info>Installing dependencies</info>'); $links = $this->collectLinks($composer->getPackage(), $noInstallRecommends, $installSuggests); foreach ($links as $link) { $request->install($link->getTarget(), $link->getConstraint()); } } // prepare solver $installationManager = $composer->getInstallationManager(); $policy = new DependencyResolver\DefaultPolicy(); $solver = new DependencyResolver\Solver($policy, $pool, $installedRepo); // solve dependencies $operations = $solver->solve($request); // execute operations if (!$operations) { $io->write('<info>Nothing to install/update</info>'); } // force dev packages to be updated to latest reference on update if ($update) { foreach ($localRepo->getPackages() as $package) { // skip non-dev packages if (!$package->isDev()) { continue; } // skip packages that will be updated/uninstalled foreach ($operations as $operation) { if ('update' === $operation->getJobType() && $package === $operation->getInitialPackage() || 'uninstall' === $operation->getJobType() && $package === $operation->getPackage()) { continue 2; } } // force update $newPackage = $composer->getRepositoryManager()->findPackage($package->getName(), $package->getVersion()); if ($newPackage && $newPackage->getSourceReference() !== $package->getSourceReference()) { $operations[] = new UpdateOperation($package, $newPackage); } } } foreach ($operations as $operation) { if ($verbose) { $io->write((string) $operation); } if (!$dryRun) { $eventDispatcher->dispatchPackageEvent(constant('Composer\\Script\\ScriptEvents::PRE_PACKAGE_' . strtoupper($operation->getJobType())), $operation); // if installing from lock, restore dev packages' references to their locked state if ($installFromLock) { $package = null; if ('update' === $operation->getJobType()) { $package = $operation->getTargetPackage(); } elseif ('install' === $operation->getJobType()) { $package = $operation->getPackage(); } if ($package && $package->isDev()) { $lockData = $composer->getLocker()->getLockData(); foreach ($lockData['packages'] as $lockedPackage) { if (!empty($lockedPackage['source-reference']) && strtolower($lockedPackage['package']) === $package->getName()) { $package->setSourceReference($lockedPackage['source-reference']); break; } } } } $installationManager->execute($operation); $eventDispatcher->dispatchPackageEvent(constant('Composer\\Script\\ScriptEvents::POST_PACKAGE_' . strtoupper($operation->getJobType())), $operation); } } if (!$dryRun) { if ($update || !$composer->getLocker()->isLocked()) { $composer->getLocker()->lockPackages($localRepo->getPackages()); $io->write('<info>Writing lock file</info>'); } $localRepo->write(); $io->write('<info>Generating autoload files</info>'); $generator = new AutoloadGenerator(); $generator->dump($localRepo, $composer->getPackage(), $installationManager, $installationManager->getVendorPath() . '/.composer'); // dispatch post event $eventName = $update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD; $eventDispatcher->dispatchCommandEvent($eventName); } }
public function run() { if ($this->dryRun) { $this->verbose = true; $this->runScripts = false; $this->installationManager->addInstaller(new NoopInstaller()); $this->mockLocalRepositories($this->repositoryManager); } $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); if ($this->runScripts) { $eventName = $this->update ? ScriptEvents::PRE_UPDATE_CMD : ScriptEvents::PRE_INSTALL_CMD; $this->eventDispatcher->dispatchCommandEvent($eventName, $this->devMode); } $this->downloadManager->setPreferSource($this->preferSource); $this->downloadManager->setPreferDist($this->preferDist); $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); 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(); 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) { if ($this->update || !$this->locker->isLocked()) { $localRepo->reload(); $devPackages = $this->devMode || !$this->package->getDevRequires() ? array() : null; if ($this->devMode && $this->package->getDevRequires()) { $policy = $this->createPolicy(); $pool = $this->createPool(true); $pool->addRepository($installedRepo, $aliases); $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->getCanonicalPackages(), (array) $devPackages), $devPackages, $platformReqs, $platformDevReqs, $aliases, $this->package->getMinimumStability(), $this->package->getStabilityFlags()); if ($updatedLock) { $this->io->write('<info>Writing lock file</info>'); } } if ($this->optimizeAutoloader) { $this->io->write('<info>Generating optimized autoload files</info>'); } else { $this->io->write('<info>Generating autoload files</info>'); } $this->autoloadGenerator->dump($this->config, $localRepo, $this->package, $this->installationManager, 'composer', $this->optimizeAutoloader); if ($this->runScripts) { $eventName = $this->update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD; $this->eventDispatcher->dispatchCommandEvent($eventName, $this->devMode); } } return 0; }
/** * Create a repository search instance. * * @param string $keywords The search keywords. * * @param string $type The desired search type. * * @param Composer $composer The composer instance. * * @param int $threshold The threshold after which to stop searching. * * @return CompositeSearch */ private function getRepositorySearch($keywords, $type, Composer $composer, $threshold) { $repositoryManager = $composer->getRepositoryManager(); $localRepository = $repositoryManager->getLocalRepository(); $repositories = new CompositeRepository([$localRepository]); // If we do not search locally, add the other repositories now. if ('installed' !== $type) { $repositories->addRepository(new CompositeRepository($repositoryManager->getRepositories())); } $repositorySearch = new RepositorySearch($repositories); $repositorySearch->setSatisfactionThreshold($threshold); if (false !== strpos($keywords, '/')) { $repositorySearch->disableSearchType(RepositoryInterface::SEARCH_FULLTEXT); } else { $repositorySearch->disableSearchType(RepositoryInterface::SEARCH_NAME); } $searcher = new CompositeSearch([$repositorySearch]); $searcher->setSatisfactionThreshold($threshold); return $searcher; }
protected function execute(InputInterface $input, OutputInterface $output) { // init repos $platformRepo = new PlatformRepository(); $getRepositories = function (Composer $composer, $dev) { $manager = $composer->getRepositoryManager(); $repos = new CompositeRepository(array($manager->getLocalRepository())); if ($dev) { $repos->addRepository($manager->getLocalDevRepository()); } return $repos; }; if ($input->getOption('self')) { $package = $this->getComposer(false)->getPackage(); $repos = $installedRepo = new ArrayRepository(array($package)); } elseif ($input->getOption('platform')) { $repos = $installedRepo = $platformRepo; } elseif ($input->getOption('installed')) { $repos = $installedRepo = $getRepositories($this->getComposer(), $input->getOption('dev')); } elseif ($composer = $this->getComposer(false)) { $localRepo = $getRepositories($composer, $input->getOption('dev')); $installedRepo = new CompositeRepository(array($localRepo, $platformRepo)); $repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories())); } else { $defaultRepos = Factory::createDefaultRepositories($this->getIO()); $output->writeln('No composer.json found in the current directory, showing packages from ' . implode(', ', array_keys($defaultRepos))); $installedRepo = $platformRepo; $repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos)); } // show single package or single version if ($input->getArgument('package') || !empty($package)) { $versions = array(); if (empty($package)) { list($package, $versions) = $this->getPackage($installedRepo, $repos, $input->getArgument('package'), $input->getArgument('version')); if (!$package) { throw new \InvalidArgumentException('Package ' . $input->getArgument('package') . ' not found'); } } else { $versions = array($package->getPrettyVersion() => $package->getVersion()); } $this->printMeta($input, $output, $package, $versions, $installedRepo, $repos); $this->printLinks($input, $output, $package, 'requires'); $this->printLinks($input, $output, $package, 'devRequires', 'requires (dev)'); if ($package->getSuggests()) { $output->writeln("\n<info>suggests</info>"); foreach ($package->getSuggests() as $suggested => $reason) { $output->writeln($suggested . ' <comment>' . $reason . '</comment>'); } } $this->printLinks($input, $output, $package, 'provides'); $this->printLinks($input, $output, $package, 'conflicts'); $this->printLinks($input, $output, $package, 'replaces'); return; } // list packages $packages = array(); $repos->filterPackages(function ($package) use(&$packages, $platformRepo, $installedRepo) { if ($platformRepo->hasPackage($package)) { $type = '<info>platform</info>:'; } elseif ($installedRepo->hasPackage($package)) { $type = '<info>installed</info>:'; } else { $type = '<comment>available</comment>:'; } if (!isset($packages[$type][$package->getName()]) || version_compare($packages[$type][$package->getName()]->getVersion(), $package->getVersion(), '<')) { $packages[$type][$package->getName()] = $package; } }, 'Composer\\Package\\CompletePackage'); foreach (array('<info>platform</info>:' => true, '<comment>available</comment>:' => false, '<info>installed</info>:' => true) as $type => $showVersion) { if (isset($packages[$type])) { $output->writeln($type); ksort($packages[$type]); foreach ($packages[$type] as $package) { $output->writeln(' ' . $package->getPrettyName() . ' ' . ($showVersion ? '[' . $package->getPrettyVersion() . ']' : '') . ' <comment>:</comment> ' . strtok($package->getDescription(), "\r\n")); } $output->writeln(''); } } }