/** * Search for packages. * * @param array $packages Indexed array of package names to search for * @param boolean $onlyname True for name only search, false for full text * * @throws PackageManagerException * * @return array List of matching packages */ public function execute($packages, $onlyname = true) { /** @var \Composer\Composer $composer */ $composer = $this->getComposer(); $io = $this->getIO(); $platformRepo = new PlatformRepository(); if ($composer) { $localRepo = $composer->getRepositoryManager()->getLocalRepository(); $installedRepo = new CompositeRepository([$localRepo, $platformRepo]); $repos = new CompositeRepository(array_merge([$installedRepo], $composer->getRepositoryManager()->getRepositories())); } else { $defaultRepos = RepositoryFactory::defaultRepos($io); //No composer.json found in the current directory, showing packages from local repo $installedRepo = $platformRepo; $repos = new CompositeRepository(array_merge([$installedRepo], $defaultRepos)); } $flags = $onlyname ? RepositoryInterface::SEARCH_NAME : RepositoryInterface::SEARCH_FULLTEXT; try { return $repos->search(implode(' ', $packages), $flags); } catch (\Exception $e) { $msg = sprintf('%s recieved an error from Composer: %s in %s::%s', __METHOD__, $e->getMessage(), $e->getFile(), $e->getLine()); $this->app['logger.system']->critical($msg, ['event' => 'exception', 'exception' => $e]); throw new PackageManagerException($e->getMessage(), $e->getCode(), $e); } }
/** * Execute the command. * * @param InputInterface $input * @param OutputInterface $output * @param bool $inverted Whether to invert matching process (why-not vs why behaviour) * @return int|null Exit code of the operation. */ protected function doExecute(InputInterface $input, OutputInterface $output, $inverted = false) { // Emit command event on startup $composer = $this->getComposer(); $commandEvent = new CommandEvent(PluginEvents::COMMAND, $this->getName(), $input, $output); $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent); // Prepare repositories and set up a pool $platformOverrides = $composer->getConfig()->get('platform') ?: array(); $repository = new CompositeRepository(array(new ArrayRepository(array($composer->getPackage())), $composer->getRepositoryManager()->getLocalRepository(), new PlatformRepository(array(), $platformOverrides))); $pool = new Pool(); $pool->addRepository($repository); // Parse package name and constraint list($needle, $textConstraint) = array_pad(explode(':', $input->getArgument(self::ARGUMENT_PACKAGE)), 2, $input->getArgument(self::ARGUMENT_CONSTRAINT)); // Find packages that are or provide the requested package first $packages = $pool->whatProvides($needle); if (empty($packages)) { throw new \InvalidArgumentException(sprintf('Could not find package "%s" in your project', $needle)); } // If the version we ask for is not installed then we need to locate it in remote repos and add it. // This is needed for why-not to resolve conflicts from an uninstalled version against installed packages. if (!$repository->findPackage($needle, $textConstraint)) { $defaultRepos = new CompositeRepository(RepositoryFactory::defaultRepos($this->getIO())); if ($match = $defaultRepos->findPackage($needle, $textConstraint)) { $repository->addRepository(new ArrayRepository(array(clone $match))); } } // Include replaced packages for inverted lookups as they are then the actual starting point to consider $needles = array($needle); if ($inverted) { foreach ($packages as $package) { $needles = array_merge($needles, array_map(function (Link $link) { return $link->getTarget(); }, $package->getReplaces())); } } // Parse constraint if one was supplied if ('*' !== $textConstraint) { $versionParser = new VersionParser(); $constraint = $versionParser->parseConstraints($textConstraint); } else { $constraint = null; } // Parse rendering options $renderTree = $input->getOption(self::OPTION_TREE); $recursive = $renderTree || $input->getOption(self::OPTION_RECURSIVE); // Resolve dependencies $results = $repository->getDependents($needles, $constraint, $inverted, $recursive); if (empty($results)) { $extra = null !== $constraint ? sprintf(' in versions %smatching %s', $inverted ? 'not ' : '', $textConstraint) : ''; $this->getIO()->writeError(sprintf('<info>There is no installed package depending on "%s"%s</info>', $needle, $extra)); } elseif ($renderTree) { $this->initStyles($output); $root = $packages[0]; $this->getIO()->write(sprintf('<info>%s</info> %s %s', $root->getPrettyName(), $root->getPrettyVersion(), $root->getDescription())); $this->printTree($results); } else { $this->printTable($output, $results); } return 0; }
protected function execute(InputInterface $input, OutputInterface $output) { // init repos $platformRepo = new PlatformRepository(); $io = $this->getIO(); if ($composer = $this->getComposer(false)) { $localRepo = $composer->getRepositoryManager()->getLocalRepository(); $installedRepo = new CompositeRepository(array($localRepo, $platformRepo)); $repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories())); } else { $defaultRepos = RepositoryFactory::defaultRepos($io); $io->writeError('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)); } if ($composer) { $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'search', $input, $output); $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent); } $onlyName = $input->getOption('only-name'); $flags = $onlyName ? RepositoryInterface::SEARCH_NAME : RepositoryInterface::SEARCH_FULLTEXT; $results = $repos->search(implode(' ', $input->getArgument('tokens')), $flags); foreach ($results as $result) { $io->write($result['name'] . (isset($result['description']) ? ' ' . $result['description'] : '')); } }
/** * @param string|JsonFile $json * @param Config $config * * @return \Composer\Package\RootPackageInterface */ public static function loadRootPackageFromJson($json, Config $config = null) { try { $config = null !== $config ? $config : self::loadConfiguration(); $loader = new JsonLoader(new RootPackageLoader(RepositoryFactory::manager(new NullIO(), $config), $config)); $package = $loader->load($json); } catch (Exception $e) { throw RuntimeException::fromAnyException($e); } return $package; }
protected function getRepos() { if (!$this->repos) { $this->repos = new CompositeRepository(array_merge(array(new PlatformRepository()), RepositoryFactory::defaultRepos($this->getIO()))); } return $this->repos; }
/** * Initializes repositories * * Returns an array of repos in order they should be checked in * * @return RepositoryInterface[] */ private function initializeRepos() { $composer = $this->getComposer(false); if ($composer) { return array_merge(array(new ArrayRepository(array($composer->getPackage()))), array($composer->getRepositoryManager()->getLocalRepository()), $composer->getRepositoryManager()->getRepositories()); } return RepositoryFactory::defaultRepos($this->getIO()); }
/** * Creates a Composer instance * * @param IOInterface $io IO instance * @param array|string|null $localConfig either a configuration array or a filename to read from, if null it will * read from the default filename * @param bool $disablePlugins Whether plugins should not be loaded * @param bool $fullLoad Whether to initialize everything or only main project stuff (used when loading the global composer) * @throws \InvalidArgumentException * @throws \UnexpectedValueException * @return Composer */ public function createComposer(IOInterface $io, $localConfig = null, $disablePlugins = false, $cwd = null, $fullLoad = true) { $cwd = $cwd ?: getcwd(); // load Composer configuration if (null === $localConfig) { $localConfig = static::getComposerFile(); } if (is_string($localConfig)) { $composerFile = $localConfig; $file = new JsonFile($localConfig, null, $io); if (!$file->exists()) { if ($localConfig === './composer.json' || $localConfig === 'composer.json') { $message = 'Composer could not find a composer.json file in ' . $cwd; } else { $message = 'Composer could not find the config file: ' . $localConfig; } $instructions = 'To initialize a project, please create a composer.json file as described in the https://getcomposer.org/ "Getting Started" section'; throw new \InvalidArgumentException($message . PHP_EOL . $instructions); } $file->validateSchema(JsonFile::LAX_SCHEMA); $jsonParser = new JsonParser(); try { $jsonParser->parse(file_get_contents($localConfig), JsonParser::DETECT_KEY_CONFLICTS); } catch (DuplicateKeyException $e) { $details = $e->getDetails(); $io->writeError('<warning>Key ' . $details['key'] . ' is a duplicate in ' . $localConfig . ' at line ' . $details['line'] . '</warning>'); } $localConfig = $file->read(); } // Load config and override with local config/auth config $config = static::createConfig($io, $cwd); $config->merge($localConfig); if (isset($composerFile)) { $io->writeError('Loading config file ' . $composerFile, true, IOInterface::DEBUG); $config->setConfigSource(new JsonConfigSource(new JsonFile(realpath($composerFile), null, $io))); $localAuthFile = new JsonFile(dirname(realpath($composerFile)) . '/auth.json', null, $io); if ($localAuthFile->exists()) { $io->writeError('Loading config file ' . $localAuthFile->getPath(), true, IOInterface::DEBUG); $config->merge(array('config' => $localAuthFile->read())); $config->setAuthConfigSource(new JsonConfigSource($localAuthFile, true)); } } $vendorDir = $config->get('vendor-dir'); // initialize composer $composer = new Composer(); $composer->setConfig($config); if ($fullLoad) { // load auth configs into the IO instance $io->loadConfiguration($config); } $rfs = self::createRemoteFilesystem($io, $config); // initialize event dispatcher $dispatcher = new EventDispatcher($composer, $io); $composer->setEventDispatcher($dispatcher); // initialize repository manager $rm = RepositoryFactory::manager($io, $config, $dispatcher, $rfs); $composer->setRepositoryManager($rm); // load local repository $this->addLocalRepository($io, $rm, $vendorDir); // force-set the version of the global package if not defined as // guessing it adds no value and only takes time if (!$fullLoad && !isset($localConfig['version'])) { $localConfig['version'] = '1.0.0'; } // load package $parser = new VersionParser(); $guesser = new VersionGuesser($config, new ProcessExecutor($io), $parser); $loader = new Package\Loader\RootPackageLoader($rm, $config, $parser, $guesser); $package = $loader->load($localConfig, 'Composer\\Package\\RootPackage', $cwd); $composer->setPackage($package); // initialize installation manager $im = $this->createInstallationManager(); $composer->setInstallationManager($im); if ($fullLoad) { // initialize download manager $dm = $this->createDownloadManager($io, $config, $dispatcher, $rfs); $composer->setDownloadManager($dm); // initialize autoload generator $generator = new AutoloadGenerator($dispatcher, $io); $composer->setAutoloadGenerator($generator); } // add installers to the manager (must happen after download manager is created since they read it out of $composer) $this->createDefaultInstallers($im, $composer, $io); if ($fullLoad) { $globalComposer = null; if (realpath($config->get('home')) !== $cwd) { $globalComposer = $this->createGlobalComposer($io, $config, $disablePlugins); } $pm = $this->createPluginManager($io, $composer, $globalComposer, $disablePlugins); $composer->setPluginManager($pm); $pm->loadInstalledPlugins(); } // init locker if possible if ($fullLoad && isset($composerFile)) { $lockFile = "json" === pathinfo($composerFile, PATHINFO_EXTENSION) ? substr($composerFile, 0, -4) . 'lock' : $composerFile . '.lock'; $locker = new Package\Locker($io, new JsonFile($lockFile, null, $io), $rm, $im, file_get_contents($composerFile)); $composer->setLocker($locker); } if ($fullLoad) { $initEvent = new Event(PluginEvents::INIT); $composer->getEventDispatcher()->dispatch($initEvent->getName(), $initEvent); // once everything is initialized we can // purge packages from local repos if they have been deleted on the filesystem if ($rm->getLocalRepository()) { $this->purgePackages($rm->getLocalRepository(), $im); } } return $composer; }
protected function installRootPackage(IOInterface $io, Config $config, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repository = null, $disablePlugins = false, $noScripts = false, $keepVcs = false, $noProgress = false, $ignorePlatformReqs = false, $secureHttp = true) { if (!$secureHttp) { $config->merge(array('config' => array('secure-http' => false))); } if (null === $repository) { $sourceRepo = new CompositeRepository(RepositoryFactory::defaultRepos($io, $config)); } else { $sourceRepo = RepositoryFactory::fromString($io, $config, $repository, true); } $parser = new VersionParser(); $requirements = $parser->parseNameVersionPairs(array($packageName)); $name = strtolower($requirements[0]['name']); if (!$packageVersion && isset($requirements[0]['version'])) { $packageVersion = $requirements[0]['version']; } if (null === $stability) { if (preg_match('{^[^,\\s]*?@(' . implode('|', array_keys(BasePackage::$stabilities)) . ')$}i', $packageVersion, $match)) { $stability = $match[1]; } else { $stability = VersionParser::parseStability($packageVersion); } } $stability = VersionParser::normalizeStability($stability); if (!isset(BasePackage::$stabilities[$stability])) { throw new \InvalidArgumentException('Invalid stability provided (' . $stability . '), must be one of: ' . implode(', ', array_keys(BasePackage::$stabilities))); } $pool = new Pool($stability); $pool->addRepository($sourceRepo); $phpVersion = null; $prettyPhpVersion = null; if (!$ignorePlatformReqs) { $platformOverrides = $config->get('platform') ?: array(); // initialize $this->repos as it is used by the parent InitCommand $platform = new PlatformRepository(array(), $platformOverrides); $phpPackage = $platform->findPackage('php', '*'); $phpVersion = $phpPackage->getVersion(); $prettyPhpVersion = $phpPackage->getPrettyVersion(); } // find the latest version if there are multiple $versionSelector = new VersionSelector($pool); $package = $versionSelector->findBestCandidate($name, $packageVersion, $phpVersion, $stability); if (!$package) { $errorMessage = "Could not find package {$name} with " . ($packageVersion ? "version {$packageVersion}" : "stability {$stability}"); if ($phpVersion && $versionSelector->findBestCandidate($name, $packageVersion, null, $stability)) { throw new \InvalidArgumentException($errorMessage . ' in a version installable using your PHP version ' . $prettyPhpVersion . '.'); } throw new \InvalidArgumentException($errorMessage . '.'); } if (null === $directory) { $parts = explode("/", $name, 2); $directory = getcwd() . DIRECTORY_SEPARATOR . array_pop($parts); } // handler Ctrl+C for unix-like systems if (function_exists('pcntl_signal')) { declare (ticks=100); pcntl_signal(SIGINT, function () use($directory) { $fs = new Filesystem(); $fs->removeDirectory($directory); exit(130); }); } $io->writeError('<info>Installing ' . $package->getName() . ' (' . $package->getFullPrettyVersion(false) . ')</info>'); if ($disablePlugins) { $io->writeError('<info>Plugins have been disabled.</info>'); } if (0 === strpos($package->getPrettyVersion(), 'dev-') && in_array($package->getSourceType(), array('git', 'hg'))) { $package->setSourceReference(substr($package->getPrettyVersion(), 4)); } $dm = $this->createDownloadManager($io, $config); $dm->setPreferSource($preferSource)->setPreferDist($preferDist)->setOutputProgress(!$noProgress); $projectInstaller = new ProjectInstaller($directory, $dm); $im = $this->createInstallationManager(); $im->addInstaller($projectInstaller); $im->install(new InstalledFilesystemRepository(new JsonFile('php://memory')), new InstallOperation($package)); $im->notifyInstalls($io); // collect suggestions $this->suggestedPackagesReporter->addSuggestionsFromPackage($package); $installedFromVcs = 'source' === $package->getInstallationSource(); $io->writeError('<info>Created project in ' . $directory . '</info>'); chdir($directory); $_SERVER['COMPOSER_ROOT_VERSION'] = $package->getPrettyVersion(); putenv('COMPOSER_ROOT_VERSION=' . $_SERVER['COMPOSER_ROOT_VERSION']); return $installedFromVcs; }
protected function execute(InputInterface $input, OutputInterface $output) { $this->versionParser = new VersionParser(); if ($input->getOption('tree')) { $this->initStyles($output); } $composer = $this->getComposer(false); $io = $this->getIO(); if ($input->getOption('installed')) { $io->writeError('<warning>You are using the deprecated option "installed". Only installed packages are shown by default now. The --all option can be used to show all packages.</warning>'); } if ($input->getOption('outdated')) { $input->setOption('latest', true); } if ($input->getOption('direct') && ($input->getOption('all') || $input->getOption('available') || $input->getOption('platform'))) { $io->writeError('The --direct (-D) option is not usable in combination with --all, --platform (-p) or --available (-a)'); return 1; } if ($input->getOption('tree') && ($input->getOption('all') || $input->getOption('available'))) { $io->writeError('The --tree (-t) option is not usable in combination with --all or --available (-a)'); return 1; } // init repos $platformOverrides = array(); if ($composer) { $platformOverrides = $composer->getConfig()->get('platform') ?: array(); } $platformRepo = new PlatformRepository(array(), $platformOverrides); $phpVersion = $platformRepo->findPackage('php', '*')->getVersion(); if ($input->getOption('self')) { $package = $this->getComposer()->getPackage(); $repos = $installedRepo = new ArrayRepository(array($package)); } elseif ($input->getOption('platform')) { $repos = $installedRepo = $platformRepo; } elseif ($input->getOption('available')) { $installedRepo = $platformRepo; if ($composer) { $repos = new CompositeRepository($composer->getRepositoryManager()->getRepositories()); } else { $defaultRepos = RepositoryFactory::defaultRepos($io); $repos = new CompositeRepository($defaultRepos); $io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos))); } } elseif ($input->getOption('all') && $composer) { $localRepo = $composer->getRepositoryManager()->getLocalRepository(); $installedRepo = new CompositeRepository(array($localRepo, $platformRepo)); $repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories())); } elseif ($input->getOption('all')) { $defaultRepos = RepositoryFactory::defaultRepos($io); $io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos))); $installedRepo = $platformRepo; $repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos)); } else { $repos = $installedRepo = $this->getComposer()->getRepositoryManager()->getLocalRepository(); } if ($composer) { $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'show', $input, $output); $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent); } if ($input->getOption('latest') && null === $composer) { $io->writeError('No composer.json found in the current directory, disabling "latest" option'); $input->setOption('latest', false); } $packageFilter = $input->getArgument('package'); // show single package or single version if ($packageFilter && false === strpos($packageFilter, '*') || !empty($package)) { 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()); } if ($input->getOption('tree')) { $this->displayPackageTree($package, $installedRepo, $repos); } else { $latestPackage = null; if ($input->getOption('latest')) { $latestPackage = $this->findLatestPackage($package, $composer, $phpVersion); } $this->printMeta($package, $versions, $installedRepo, $latestPackage); $this->printLinks($package, 'requires'); $this->printLinks($package, 'devRequires', 'requires (dev)'); if ($package->getSuggests()) { $io->write("\n<info>suggests</info>"); foreach ($package->getSuggests() as $suggested => $reason) { $io->write($suggested . ' <comment>' . $reason . '</comment>'); } } $this->printLinks($package, 'provides'); $this->printLinks($package, 'conflicts'); $this->printLinks($package, 'replaces'); } return; } // show tree view if requested if ($input->getOption('tree')) { $rootRequires = $this->getRootRequires(); foreach ($installedRepo->getPackages() as $package) { if (in_array($package->getName(), $rootRequires, true)) { $this->displayPackageTree($package, $installedRepo, $repos); } } return 0; } if ($repos instanceof CompositeRepository) { $repos = $repos->getRepositories(); } elseif (!is_array($repos)) { $repos = array($repos); } // list packages $packages = array(); if (null !== $packageFilter) { $packageFilter = '{^' . str_replace('\\*', '.*?', preg_quote($packageFilter)) . '$}i'; } $packageListFilter = array(); if ($input->getOption('direct')) { $packageListFilter = $this->getRootRequires(); } foreach ($repos as $repo) { if ($repo === $platformRepo) { $type = '<info>platform</info>:'; } elseif ($repo === $installedRepo || $installedRepo instanceof CompositeRepository && in_array($repo, $installedRepo->getRepositories(), true)) { $type = '<info>installed</info>:'; } else { $type = '<comment>available</comment>:'; } if ($repo instanceof ComposerRepository && $repo->hasProviders()) { foreach ($repo->getProviderNames() as $name) { if (!$packageFilter || preg_match($packageFilter, $name)) { $packages[$type][$name] = $name; } } } else { foreach ($repo->getPackages() as $package) { if (!isset($packages[$type][$package->getName()]) || !is_object($packages[$type][$package->getName()]) || version_compare($packages[$type][$package->getName()]->getVersion(), $package->getVersion(), '<')) { if (!$packageFilter || preg_match($packageFilter, $package->getName())) { if (!$packageListFilter || in_array($package->getName(), $packageListFilter, true)) { $packages[$type][$package->getName()] = $package; } } } } } } $showAllTypes = $input->getOption('all'); $showLatest = $input->getOption('latest'); $showMinorOnly = $input->getOption('minor-only'); $indent = $showAllTypes ? ' ' : ''; $latestPackages = array(); foreach (array('<info>platform</info>:' => true, '<comment>available</comment>:' => false, '<info>installed</info>:' => true) as $type => $showVersion) { if (isset($packages[$type])) { if ($showAllTypes) { $io->write($type); } ksort($packages[$type]); $nameLength = $versionLength = $latestLength = 0; foreach ($packages[$type] as $package) { if (is_object($package)) { $nameLength = max($nameLength, strlen($package->getPrettyName())); if ($showVersion) { $versionLength = max($versionLength, strlen($package->getFullPrettyVersion())); if ($showLatest) { $latestPackage = $this->findLatestPackage($package, $composer, $phpVersion, $showMinorOnly); if ($latestPackage === false) { continue; } $latestPackages[$package->getPrettyName()] = $latestPackage; $latestLength = max($latestLength, strlen($latestPackage->getFullPrettyVersion())); } } } else { $nameLength = max($nameLength, $package); } } list($width) = $this->getApplication()->getTerminalDimensions(); if (null === $width) { // In case the width is not detected, we're probably running the command // outside of a real terminal, use space without a limit $width = PHP_INT_MAX; } if (Platform::isWindows()) { $width--; } if ($input->getOption('path') && null === $composer) { $io->writeError('No composer.json found in the current directory, disabling "path" option'); $input->setOption('path', false); } $writePath = !$input->getOption('name-only') && $input->getOption('path'); $writeVersion = !$input->getOption('name-only') && !$input->getOption('path') && $showVersion && $nameLength + $versionLength + 3 <= $width; $writeLatest = $writeVersion && $showLatest && $nameLength + $versionLength + $latestLength + 3 <= $width; $writeDescription = !$input->getOption('name-only') && !$input->getOption('path') && $nameLength + $versionLength + $latestLength + 24 <= $width; foreach ($packages[$type] as $package) { if (is_object($package)) { $latestPackackage = null; if ($showLatest && isset($latestPackages[$package->getPrettyName()])) { $latestPackackage = $latestPackages[$package->getPrettyName()]; } if ($input->getOption('outdated') && $latestPackackage && $latestPackackage->getFullPrettyVersion() === $package->getFullPrettyVersion() && !$latestPackackage->isAbandoned()) { continue; } $io->write($indent . str_pad($package->getPrettyName(), $nameLength, ' '), false); if ($writeVersion) { $io->write(' ' . str_pad($package->getFullPrettyVersion(), $versionLength, ' '), false); } if ($writeLatest && $latestPackackage) { $latestVersion = $latestPackackage->getFullPrettyVersion(); $style = $this->getVersionStyle($latestPackackage, $package); $io->write(' <' . $style . '>' . str_pad($latestVersion, $latestLength, ' ') . '</' . $style . '>', false); } if ($writeDescription) { $description = strtok($package->getDescription(), "\r\n"); $remaining = $width - $nameLength - $versionLength - 4; if ($writeLatest) { $remaining -= $latestLength; } if (strlen($description) > $remaining) { $description = substr($description, 0, $remaining - 3) . '...'; } $io->write(' ' . $description, false); } if ($writePath) { $path = strtok(realpath($composer->getInstallationManager()->getInstallPath($package)), "\r\n"); $io->write(' ' . $path, false); } if ($latestPackackage && $latestPackackage->isAbandoned()) { $replacement = is_string($latestPackackage->getReplacementPackage()) ? 'Use ' . $latestPackackage->getReplacementPackage() . ' instead' : 'No replacement was suggested'; $io->writeError(''); $io->writeError(sprintf("<warning>Package %s is abandoned, you should avoid using it. %s.</warning>", $package->getPrettyName(), $replacement), false); } } else { $io->write($indent . $package, false); } $io->write(''); } if ($showAllTypes) { $io->write(''); } } } }
/** * If the version we ask for is not installed then we need to locate it in * remote repos and add it. * * This is needed for why-not to resolve conflicts from an uninstalled * version against installed packages. * * @param string $packageName Package to inspect. * @param string $textConstraint Optional version constraint * @param bool $onlyLocal * * @return Pool */ private function getRequiredPool($packageName, $textConstraint, $onlyLocal) { if ($onlyLocal === false) { return $this->getPool(); } $composer = $this->getComposer(); $pool = new Pool(); // Prepare repositories and set up a pool $platformOverrides = $composer->getConfig()->get('platform') ?: []; /** @var BasePackage $rootPackage */ $rootPackage = $composer->getPackage(); if ($rootPackage->getRepository() === null) { $packageRepo = new ArrayRepository([$composer->getPackage()]); $localRepo = $composer->getRepositoryManager()->getLocalRepository(); $platformRepo = new PlatformRepository([], $platformOverrides); $compositeRepository = new CompositeRepository([$packageRepo, $localRepo, $platformRepo]); $pool->addRepository($compositeRepository); $defaultRepos = new CompositeRepository(RepositoryFactory::defaultRepos($this->getIO())); $match = $defaultRepos->findPackage($packageName, $textConstraint); if ($match) { $compositeRepository->addRepository(new ArrayRepository([clone $match])); } } return $pool; }
protected function installRootPackage(IOInterface $io, Config $config, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repository = null, $disablePlugins = false, $noScripts = false, $keepVcs = false, $noProgress = false) { if (null === $repository) { $sourceRepo = new CompositeRepository(RepositoryFactory::defaultRepos($io, $config)); } else { $sourceRepo = RepositoryFactory::fromString($io, $config, $repository, true); } $parser = new VersionParser(); $requirements = $parser->parseNameVersionPairs(array($packageName)); $name = strtolower($requirements[0]['name']); if (!$packageVersion && isset($requirements[0]['version'])) { $packageVersion = $requirements[0]['version']; } if (null === $stability) { if (preg_match('{^[^,\\s]*?@(' . implode('|', array_keys(BasePackage::$stabilities)) . ')$}i', $packageVersion, $match)) { $stability = $match[1]; } else { $stability = VersionParser::parseStability($packageVersion); } } $stability = VersionParser::normalizeStability($stability); if (!isset(BasePackage::$stabilities[$stability])) { throw new \InvalidArgumentException('Invalid stability provided (' . $stability . '), must be one of: ' . implode(', ', array_keys(BasePackage::$stabilities))); } $pool = new Pool($stability); $pool->addRepository($sourceRepo); // using those 3 constants to build a version without the 'extra' bit that can contain garbage $phpVersion = PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION . '.' . PHP_RELEASE_VERSION; // find the latest version if there are multiple $versionSelector = new VersionSelector($pool); $package = $versionSelector->findBestCandidate($name, $packageVersion, $phpVersion, $stability); if (!$package) { throw new \InvalidArgumentException("Could not find package {$name}" . ($packageVersion ? " with version {$packageVersion}." : " with stability {$stability}.")); } if (null === $directory) { $parts = explode("/", $name, 2); $directory = getcwd() . DIRECTORY_SEPARATOR . array_pop($parts); } // handler Ctrl+C for unix-like systems if (function_exists('pcntl_signal')) { declare (ticks=100); pcntl_signal(SIGINT, function () use($directory) { $fs = new Filesystem(); $fs->removeDirectory($directory); exit(130); }); } $io->writeError('<info>Installing ' . $package->getName() . ' (' . $package->getFullPrettyVersion(false) . ')</info>'); if ($disablePlugins) { $io->writeError('<info>Plugins have been disabled.</info>'); } if (0 === strpos($package->getPrettyVersion(), 'dev-') && in_array($package->getSourceType(), array('git', 'hg'))) { $package->setSourceReference(substr($package->getPrettyVersion(), 4)); } $dm = $this->createDownloadManager($io, $config); $dm->setPreferSource($preferSource)->setPreferDist($preferDist)->setOutputProgress(!$noProgress); $projectInstaller = new ProjectInstaller($directory, $dm); $im = $this->createInstallationManager(); $im->addInstaller($projectInstaller); $im->install(new InstalledFilesystemRepository(new JsonFile('php://memory')), new InstallOperation($package)); $im->notifyInstalls($io); $installedFromVcs = 'source' === $package->getInstallationSource(); $io->writeError('<info>Created project in ' . $directory . '</info>'); chdir($directory); $_SERVER['COMPOSER_ROOT_VERSION'] = $package->getPrettyVersion(); putenv('COMPOSER_ROOT_VERSION=' . $_SERVER['COMPOSER_ROOT_VERSION']); return $installedFromVcs; }
/** * Retrieves detailed information about a package, or lists all packages available. * * @param string $type Repository type, either: 'self', 'platform', 'installed' or 'available' * @param string $package Package name to show * @param string $version Package version to show * @param boolean $root Query the Bolt parent composer install * * @return array Array of Composer packages */ public function execute($type, $package = '', $version = '', $root = false) { $io = $this->getIO(); if ($root) { $composerJson = $this->app['resources']->getPath('root/composer.json'); $composer = Factory::create($io, $composerJson, true); } else { $composer = $this->getComposer(); } $this->versionParser = new VersionParser(); // Initialize repos. $platformRepo = new PlatformRepository(); switch ($type) { case 'self': $package = $composer->getPackage(); $repos = $installedRepo = new ArrayRepository([$package]); break; case 'platform': $repos = $platformRepo; $installedRepo = $platformRepo; break; case 'installed': $repos = $composer->getRepositoryManager()->getLocalRepository(); $installedRepo = $repos; break; case 'available': $installedRepo = $platformRepo; if ($composer) { $repos = new CompositeRepository($composer->getRepositoryManager()->getRepositories()); } else { // No composer.json found in the current directory, showing available packages from default repos. $defaultRepos = RepositoryFactory::defaultRepos($io); $repos = new CompositeRepository($defaultRepos); } break; default: if ($composer) { $localRepo = $composer->getRepositoryManager()->getLocalRepository(); $installedRepo = new CompositeRepository([$localRepo, $platformRepo]); $merged = array_merge([$installedRepo], $composer->getRepositoryManager()->getRepositories()); $repos = new CompositeRepository($merged); } else { // No composer.json found in the current directory, showing available packages from default repos. $defaultRepos = RepositoryFactory::defaultRepos($io); $installedRepo = $platformRepo; $repos = new CompositeRepository(array_merge([$installedRepo], $defaultRepos)); } } // Single package or single version. if (!empty($package)) { if (is_object($package)) { return [$package->getName() => ['package' => $package, 'versions' => $package->getVersion()]]; } else { return $this->getPackage($installedRepo, $repos, $package, $version); } } $packages = []; if ($repos instanceof CompositeRepository) { $repos = $repos->getRepositories(); } elseif (!is_array($repos)) { $repos = [$repos]; } foreach ($repos as $repo) { if ($repo instanceof ComposerRepository && $repo->hasProviders()) { foreach ($repo->getProviderNames() as $name) { $packages[$name] = $name; } } else { foreach ($repo->getPackages() as $package) { /** @var $package \Composer\Package\PackageInterface */ if (!isset($packages[$type][$package->getName()]) || !is_object($packages[$type][$package->getName()]) || version_compare($packages[$type][$package->getName()]->getVersion(), $package->getVersion(), '<')) { $packages[$package->getName()] = ['package' => $package, 'versions' => $package->getVersion()]; } } } } ksort($packages); return $packages; }
/** * @param array $config package data * @param string $class FQCN to be instantiated * @param string $cwd cwd of the root package to be used to guess the version if it is not provided * @return RootPackageInterface */ public function load(array $config, $class = 'Composer\\Package\\RootPackage', $cwd = null) { if (!isset($config['name'])) { $config['name'] = '__root__'; } $autoVersioned = false; if (!isset($config['version'])) { // override with env var if available if (getenv('COMPOSER_ROOT_VERSION')) { $version = getenv('COMPOSER_ROOT_VERSION'); $commit = null; } else { $versionData = $this->versionGuesser->guessVersion($config, $cwd ?: getcwd()); $version = $versionData['version']; $commit = $versionData['commit']; } if (!$version) { $version = '1.0.0'; $autoVersioned = true; } $config['version'] = $version; if ($commit) { $config['source'] = array('type' => '', 'url' => '', 'reference' => $commit); $config['dist'] = array('type' => '', 'url' => '', 'reference' => $commit); } } $realPackage = $package = parent::load($config, $class); if ($realPackage instanceof AliasPackage) { $realPackage = $package->getAliasOf(); } if ($autoVersioned) { $realPackage->replaceVersion($realPackage->getVersion(), 'No version set (parsed as 1.0.0)'); } if (isset($config['minimum-stability'])) { $realPackage->setMinimumStability(VersionParser::normalizeStability($config['minimum-stability'])); } $aliases = array(); $stabilityFlags = array(); $references = array(); foreach (array('require', 'require-dev') as $linkType) { if (isset($config[$linkType])) { $linkInfo = BasePackage::$supportedLinkTypes[$linkType]; $method = 'get' . ucfirst($linkInfo['method']); $links = array(); foreach ($realPackage->{$method}() as $link) { $links[$link->getTarget()] = $link->getConstraint()->getPrettyString(); } $aliases = $this->extractAliases($links, $aliases); $stabilityFlags = $this->extractStabilityFlags($links, $stabilityFlags, $realPackage->getMinimumStability()); $references = $this->extractReferences($links, $references); } } if (isset($links[$config['name']])) { throw new \InvalidArgumentException(sprintf('Root package \'%s\' cannot require itself in its composer.json' . PHP_EOL . 'Did you accidentally name your root package after an external package?', $config['name'])); } $realPackage->setAliases($aliases); $realPackage->setStabilityFlags($stabilityFlags); $realPackage->setReferences($references); if (isset($config['prefer-stable'])) { $realPackage->setPreferStable((bool) $config['prefer-stable']); } if (isset($config['config'])) { $realPackage->setConfig($config['config']); } $repos = RepositoryFactory::defaultRepos(null, $this->config, $this->manager); foreach ($repos as $repo) { $this->manager->addRepository($repo); } $realPackage->setRepositories($this->config->getRepositories()); return $package; }
protected function selectPackage(IOInterface $io, $packageName, $version = null) { $io->writeError('<info>Searching for the specified package.</info>'); if ($composer = $this->getComposer(false)) { $localRepo = $composer->getRepositoryManager()->getLocalRepository(); $repo = new CompositeRepository(array_merge(array($localRepo), $composer->getRepositoryManager()->getRepositories())); } else { $defaultRepos = RepositoryFactory::defaultRepos($this->getIO()); $io->writeError('No composer.json found in the current directory, searching packages from ' . implode(', ', array_keys($defaultRepos))); $repo = new CompositeRepository($defaultRepos); } $packages = $repo->findPackages($packageName, $version); if (count($packages) > 1) { $package = reset($packages); $io->writeError('<info>Found multiple matches, selected ' . $package->getPrettyString() . '.</info>'); $io->writeError('Alternatives were ' . implode(', ', array_map(function ($p) { return $p->getPrettyString(); }, $packages)) . '.'); $io->writeError('<comment>Please use a more specific constraint to pick a different package.</comment>'); } elseif ($packages) { $package = reset($packages); $io->writeError('<info>Found an exact match ' . $package->getPrettyString() . '.</info>'); } else { $io->writeError('<error>Could not find a package matching ' . $packageName . '.</error>'); return false; } return $package; }