1
0
Fork 0
mirror of https://github.com/composer/composer synced 2025-05-11 09:32:55 +00:00

Remove filterPackages and add RepositoryInterface::search, refactor all commands to use new methods and remove all usage of the full package list for Composer repositories that support providers, fixes #1646

This commit is contained in:
Jordi Boggiano 2013-03-10 13:32:59 +01:00
parent 095852933e
commit be861f090a
11 changed files with 233 additions and 205 deletions

View file

@ -13,8 +13,11 @@
namespace Composer\Command;
use Composer\Composer;
use Composer\DependencyResolver\Pool;
use Composer\DependencyResolver\DefaultPolicy;
use Composer\Factory;
use Composer\Package\CompletePackageInterface;
use Composer\Package\LinkConstraint\VersionConstraint;
use Composer\Package\Version\VersionParser;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
@ -22,6 +25,7 @@ use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Composer\Repository\ArrayRepository;
use Composer\Repository\CompositeRepository;
use Composer\Repository\ComposerRepository;
use Composer\Repository\PlatformRepository;
use Composer\Repository\RepositoryInterface;
@ -122,20 +126,39 @@ EOT
// list packages
$packages = array();
$repos->filterPackages(function ($package) use (&$packages, $platformRepo, $installedRepo) {
if ($platformRepo->hasPackage($package)) {
if ($repos instanceof CompositeRepository) {
$repos = $repos->getRepositories();
} elseif (!is_array($repos)) {
$repos = array($repos);
}
foreach ($repos as $repo) {
if ($repo === $platformRepo) {
$type = '<info>platform</info>:';
} elseif ($installedRepo->hasPackage($package)) {
} elseif (
$repo === $installedRepo
|| ($installedRepo instanceof CompositeRepository && in_array($repo, $installedRepo->getRepositories(), true))
) {
$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;
if ($repo instanceof ComposerRepository && $repo->hasProviders()) {
foreach ($repo->getProviderNames() as $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(), '<')
) {
$packages[$type][$package->getName()] = $package;
}
}
}
}, 'Composer\Package\CompletePackage');
}
$tree = !$input->getOption('platform') && !$input->getOption('installed') && !$input->getOption('available');
$indent = $tree ? ' ' : '';
@ -148,8 +171,12 @@ EOT
$nameLength = $versionLength = 0;
foreach ($packages[$type] as $package) {
$nameLength = max($nameLength, strlen($package->getPrettyName()));
$versionLength = max($versionLength, strlen($this->versionParser->formatVersion($package)));
if (is_object($package)) {
$nameLength = max($nameLength, strlen($package->getPrettyName()));
$versionLength = max($versionLength, strlen($this->versionParser->formatVersion($package)));
} else {
$nameLength = max($nameLength, $package);
}
}
list($width) = $this->getApplication()->getTerminalDimensions();
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
@ -159,19 +186,23 @@ EOT
$writeVersion = !$input->getOption('name-only') && $showVersion && ($nameLength + $versionLength + 3 <= $width);
$writeDescription = !$input->getOption('name-only') && ($nameLength + ($showVersion ? $versionLength : 0) + 24 <= $width);
foreach ($packages[$type] as $package) {
$output->write($indent . str_pad($package->getPrettyName(), $nameLength, ' '), false);
if (is_object($package)) {
$output->write($indent . str_pad($package->getPrettyName(), $nameLength, ' '), false);
if ($writeVersion) {
$output->write(' ' . str_pad($this->versionParser->formatVersion($package), $versionLength, ' '), false);
}
if ($writeDescription) {
$description = strtok($package->getDescription(), "\r\n");
$remaining = $width - $nameLength - $versionLength - 4;
if (strlen($description) > $remaining) {
$description = substr($description, 0, $remaining - 3) . '...';
if ($writeVersion) {
$output->write(' ' . str_pad($this->versionParser->formatVersion($package), $versionLength, ' '), false);
}
$output->write(' ' . $description);
if ($writeDescription) {
$description = strtok($package->getDescription(), "\r\n");
$remaining = $width - $nameLength - $versionLength - 4;
if (strlen($description) > $remaining) {
$description = substr($description, 0, $remaining - 3) . '...';
}
$output->write(' ' . $description);
}
} else {
$output->write($indent . $package);
}
$output->writeln('');
}
@ -195,51 +226,46 @@ EOT
protected function getPackage(RepositoryInterface $installedRepo, RepositoryInterface $repos, $name, $version = null)
{
$name = strtolower($name);
$constraint = null;
if ($version) {
$version = $this->versionParser->normalize($version);
$constraint = new VersionConstraint('=', $version);
}
$match = null;
$matches = array();
$repos->filterPackages(function ($package) use ($name, $version, &$matches) {
if ($package->getName() === $name) {
$matches[] = $package;
}
}, 'Composer\Package\CompletePackage');
$policy = new DefaultPolicy();
$pool = new Pool('dev');
$pool->addRepository($repos);
if (null === $version) {
// search for a locally installed version
foreach ($matches as $package) {
if ($installedRepo->hasPackage($package)) {
$match = $package;
break;
}
$matchedPackage = null;
$matches = $pool->whatProvides($name, $constraint);
foreach ($matches as $index => $package) {
// skip providers/replacers
if ($package->getName() !== $name) {
unset($matches[$index]);
continue;
}
if (!$match) {
// fallback to the highest version
foreach ($matches as $package) {
if (null === $match || version_compare($package->getVersion(), $match->getVersion(), '>=')) {
$match = $package;
}
}
}
} else {
// select the specified version
foreach ($matches as $package) {
if ($package->getVersion() === $version) {
$match = $package;
}
// select an exact match if it is in the installed repo and no specific version was required
if (null === $version && $installedRepo->hasPackage($package)) {
$matchedPackage = $package;
}
$matches[$index] = $package->getId();
}
// select prefered package according to policy rules
if (!$matchedPackage && $matches && $prefered = $policy->selectPreferedPackages($pool, array(), $matches)) {
$matchedPackage = $pool->literalToPackage($prefered[0]);
}
// build versions array
$versions = array();
foreach ($matches as $package) {
$package = $pool->literalToPackage($package);
$versions[$package->getPrettyVersion()] = $package->getVersion();
}
return array($match, $versions);
return array($matchedPackage, $versions);
}
/**