@ -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 ($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 ($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);
}
$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');
if (null === $version) {
// search for a locally installed version
foreach ($matches as $package) {
if ($installedRepo->hasPackage($package)) {
$match = $package;
break;
}
$policy = new DefaultPolicy();
$pool = new Pool('dev');
$pool->addRepository($repos);
$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);
}
/**