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; }
/** * @param array $dependencies * * @return array */ protected function resolveUpdateablePackages(array $dependencies) { $this->versionParser = new VersionParser(); $composer = $this->getComposer(true, false); // init repos $platformOverrides = []; if ($composer) { $platformOverrides = $composer->getConfig()->get('platform') ?: []; } $platformRepo = new PlatformRepository([], $platformOverrides); $phpVersion = $platformRepo->findPackage('php', '*')->getVersion(); $repos = $installedRepo = $this->getComposer()->getRepositoryManager()->getLocalRepository(); $updateablePackages = []; foreach ($dependencies as $dependency) { $packageFilter = $dependency; // show single package or single version if ($packageFilter && false === strpos($packageFilter, '*')) { $package = $this->getPackage($installedRepo, $repos, $dependency, null); if (!$package) { continue; } $latestPackage = $this->findLatestPackage($package, $composer, $phpVersion); if ($package->getVersion() !== $latestPackage->getVersion()) { $updateablePackages[] = $dependency; } } } return $updateablePackages; }
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(''); } } } }
protected function execute(InputInterface $input, OutputInterface $output) { $lock = $this->getComposer()->getLocker()->getLockData(); if (empty($lock)) { throw new \RuntimeException('Lockfile seems to be empty?'); } $packages = $lock['packages']; if (!$input->getOption('no-dev')) { $packages += $lock['packages-dev']; } $filter = $input->getArgument('packages'); // First assemble lookup list of packages that are installed, replaced or provided $installed = array(); foreach ($packages as $package) { $installed[] = $package['name']; if (!empty($package['provide'])) { $installed = array_merge($installed, array_keys($package['provide'])); } if (!empty($package['replace'])) { $installed = array_merge($installed, array_keys($package['replace'])); } } // Undub and sort the install list into a sorted lookup array $installed = array_flip($installed); ksort($installed); // Init platform repo $platform = new PlatformRepository(array(), $this->getComposer()->getConfig()->get('platform') ?: array()); // Next gather all suggestions that are not in that list $suggesters = array(); $suggested = array(); foreach ($packages as $package) { $packageName = $package['name']; if (!empty($filter) && !in_array($packageName, $filter) || empty($package['suggest'])) { continue; } foreach ($package['suggest'] as $suggestion => $reason) { if (false === strpos('/', $suggestion) && !is_null($platform->findPackage($suggestion, '*'))) { continue; } if (!isset($installed[$suggestion])) { $suggesters[$packageName][$suggestion] = $reason; $suggested[$suggestion][$packageName] = $reason; } } } ksort($suggesters); ksort($suggested); // Determine output mode $mode = 0; $io = $this->getIO(); if ($input->getOption('by-package') || $io->isVerbose()) { $mode |= 1; } if ($input->getOption('by-suggestion')) { $mode |= 2; } // Simple mode if ($mode === 0) { foreach (array_keys($suggested) as $suggestion) { $io->write(sprintf('<info>%s</info>', $suggestion)); } return; } // Grouped by package if ($mode & 1) { foreach ($suggesters as $suggester => $suggestions) { $io->write(sprintf('<comment>%s</comment> suggests:', $suggester)); foreach ($suggestions as $suggestion => $reason) { $io->write(sprintf(' - <info>%s</info>: %s', $suggestion, $reason ?: '*')); } $io->write(''); } } // Grouped by suggestion if ($mode & 2) { // Improve readability in full mode if ($mode & 1) { $io->write(str_repeat('-', 78)); } foreach ($suggested as $suggestion => $suggesters) { $io->write(sprintf('<comment>%s</comment> is suggested by:', $suggestion)); foreach ($suggesters as $suggester => $reason) { $io->write(sprintf(' - <info>%s</info>: %s', $suggester, $reason ?: '*')); } $io->write(''); } } }