1
0
Fork 0

Tweak colors in the output, make sure we load the proper version according to stability flags and add outdated command, refs #5028

pull/5238/head
Jordi Boggiano 2016-04-22 21:54:04 +01:00
parent 9206c646a2
commit e7069dd5e8
4 changed files with 117 additions and 33 deletions

View File

@ -313,6 +313,7 @@ php composer.phar show monolog/monolog 1.0.2
### Options
* **--latest (-l):** List all installed packages including their latest version.
* **--all (-a):** List all packages available in all your repositories.
* **--installed (-i):** List the packages that are installed (this is enabled by default, and deprecated).
* **--platform (-p):** List only platform packages (php & extensions).
@ -321,6 +322,18 @@ php composer.phar show monolog/monolog 1.0.2
* **--name-only (-N):** List package names only.
* **--path (-P):** List package paths.
## outdated
The `outdated` command shows a list of installed packages including their
current and latest versions. This is basically an alias for `composer show -l`.
The color coding is as such:
- **green**: Dependency is in the latest version and is up to date.
- **yellow**: Dependency has a new version available that includes backwards compatibility breaks according to semver, so upgrade when
you can but it may involve work.
- **red**: Dependency has a new version that is semver-compatible and you should upgrade it.
## browse / home
The `browse` (aliased to `home`) opens a package's repository URL or homepage

View File

@ -0,0 +1,58 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Command;
use Composer\Util\ProcessExecutor;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\OutputInterface;
/**
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
class OutdatedCommand extends ShowCommand
{
protected function configure()
{
$this
->setName('outdated')
->setDescription('Shows a list of installed packages including their latest version.')
->setDefinition(array(
new InputArgument('package', InputArgument::OPTIONAL, 'Package to inspect. Or a name including a wildcard (*) to filter lists of packages instead.'),
))
->setHelp(<<<EOT
The outdated command is just a proxy for `composer show -l`
The color coding for dependency versions is as such:
- green: Dependency is in the latest version and is up to date.
- yellow: Dependency has a new version available that includes backwards
compatibility breaks according to semver, so upgrade when you can but it
may involve work.
- red: Dependency has a new version that is semver-compatible and you should upgrade it.
EOT
)
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// create new input without "global" command prefix
$input = new StringInput('show --latest '.ProcessExecutor::escape($input->getArgument('package')));
return $this->getApplication()->run($input, $output);
}
}

View File

@ -16,6 +16,7 @@ use Composer\DependencyResolver\Pool;
use Composer\DependencyResolver\DefaultPolicy;
use Composer\Package\CompletePackageInterface;
use Composer\Package\Version\VersionParser;
use Composer\Package\BasePackage;
use Composer\Package\Version\VersionSelector;
use Composer\Plugin\CommandEvent;
use Composer\Plugin\PluginEvents;
@ -34,6 +35,8 @@ use Composer\Repository\PlatformRepository;
use Composer\Repository\RepositoryInterface;
use Composer\Repository\RepositoryFactory;
use Composer\Spdx\SpdxLicenses;
use Composer\Composer;
use Composer\Semver\Semver;
/**
* @author Robert Schönthal <seroscho@googlemail.com>
@ -46,9 +49,6 @@ class ShowCommand extends BaseCommand
protected $versionParser;
protected $colors;
/** @var CompositeRepository */
protected $repos;
/** @var Pool */
private $pool;
@ -106,6 +106,7 @@ EOT
$platformOverrides = $composer->getConfig()->get('platform') ?: array();
}
$platformRepo = new PlatformRepository(array(), $platformOverrides);
$phpVersion = $platformRepo->findPackage('php', '*')->getVersion();
if ($input->getOption('self')) {
$package = $this->getComposer()->getPackage();
@ -139,6 +140,11 @@ EOT
$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
@ -157,8 +163,8 @@ EOT
$this->displayPackageTree($package, $installedRepo, $repos);
} else {
$latestVersion = null;
if ($input->getOption('latest')) {
$latestVersion = $this->findBestVersionForPackage($package->getName(), null);
if ($input->getOption('latest') && $composer) {
$latestVersion = $this->findBestVersionForPackage($package->getName(), $composer, $phpVersion);
}
$this->printMeta($package, $versions, $installedRepo, $latestVersion);
$this->printLinks($package, 'requires');
@ -285,9 +291,9 @@ EOT
}
if ($writeLatest) {
$latestVersion = $this->findBestVersionForPackage($package->getName());
$type = $latestVersion == $package->getFullPrettyVersion() ? 'info' : 'comment';
$io->write(' <'.$type.'>' . str_pad($latestVersion, $latestLength, ' ') . '</'.$type.'>', false);
$latestVersion = $this->findBestVersionForPackage($package->getName(), $composer, $phpVersion);
$style = $this->getVersionStyle($latestVersion, $package);
$io->write(' <'.$style.'>' . str_pad($latestVersion, $latestLength, ' ') . '</'.$style.'>', false);
}
if ($writeDescription) {
@ -315,6 +321,22 @@ EOT
}
}
protected function getVersionStyle($latestVersion, $package)
{
if ($latestVersion === $package->getFullPrettyVersion()) {
// print green as it's up to date
return 'info';
}
if ($latestVersion && Semver::satisfies($latestVersion, '^'.$package->getVersion())) {
// print red as it needs an immediate semver-compliant upgrade
return 'highlight';
}
// print yellow as it needs an upgrade but has potential BC breaks so is not urgent
return 'comment';
}
/**
* finds a package by name and version if provided
*
@ -376,7 +398,8 @@ EOT
$io->write('<info>keywords</info> : ' . join(', ', $package->getKeywords() ?: array()));
$this->printVersions($package, $versions, $installedRepo);
if ($latestVersion) {
$io->write('<info>latest</info> : ' . $latestVersion);
$style = $this->getVersionStyle($latestVersion, $package);
$io->write('<info>latest</info> : <'.$style.'>' . $latestVersion . '</'.$style.'>');
}
$io->write('<info>type</info> : ' . $package->getType());
$this->printLicenses($package);
@ -621,41 +644,30 @@ EOT
* @throws \InvalidArgumentException
* @return string|null
*/
private function findBestVersionForPackage($name)
private function findBestVersionForPackage($name, Composer $composer, $phpVersion)
{
// find the latest version allowed in this pool
$versionSelector = new VersionSelector($this->getPool());
$package = $versionSelector->findBestCandidate($name);
$versionSelector = new VersionSelector($this->getPool($composer));
$stability = $composer->getPackage()->getMinimumStability();
$flags = $composer->getPackage()->getStabilityFlags();
if (isset($flags[$name])) {
$stability = array_search($flags[$name], BasePackage::$stabilities, true);
}
$package = $versionSelector->findBestCandidate($name, null, $phpVersion, $stability);
if ($package) {
return $package->getPrettyVersion();
}
}
protected function getRepos()
{
if (!$this->repos) {
$this->repos = new CompositeRepository(array_merge(
array(new PlatformRepository),
RepositoryFactory::defaultRepos($this->getIO())
));
}
return $this->repos;
}
private function getPool()
private function getPool(Composer $composer)
{
if (!$this->pool) {
$this->pool = new Pool($this->getMinimumStability());
$this->pool->addRepository($this->getRepos());
$this->pool = new Pool($composer->getPackage()->getMinimumStability(), $composer->getPackage()->getStabilityFlags());
$this->pool->addRepository(new CompositeRepository($composer->getRepositoryManager()->getRepositories()));
}
return $this->pool;
}
private function getMinimumStability()
{
return 'stable';
}
}

View File

@ -116,7 +116,7 @@ class Application extends BaseApplication
}
}
if ($commandName !== 'global') {
if ($commandName !== 'global' && $commandName !== 'outdated') {
$io->writeError(sprintf(
'Running %s (%s) with %s on %s',
Composer::VERSION,
@ -339,6 +339,7 @@ class Application extends BaseApplication
new Command\RemoveCommand(),
new Command\HomeCommand(),
new Command\ExecCommand(),
new Command\OutdatedCommand(),
));
if ('phar:' === substr(__FILE__, 0, 5)) {