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