Tweak colors in the output, make sure we load the proper version according to stability flags and add outdated command, refs #5028
parent
9206c646a2
commit
e7069dd5e8
|
@ -313,6 +313,7 @@ php composer.phar show monolog/monolog 1.0.2
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
|
* **--latest (-l):** List all installed packages including their latest version.
|
||||||
* **--all (-a):** List all packages available in all your repositories.
|
* **--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).
|
* **--installed (-i):** List the packages that are installed (this is enabled by default, and deprecated).
|
||||||
* **--platform (-p):** List only platform packages (php & extensions).
|
* **--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.
|
* **--name-only (-N):** List package names only.
|
||||||
* **--path (-P):** List package paths.
|
* **--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
|
## browse / home
|
||||||
|
|
||||||
The `browse` (aliased to `home`) opens a package's repository URL or homepage
|
The `browse` (aliased to `home`) opens a package's repository URL or homepage
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ use Composer\DependencyResolver\Pool;
|
||||||
use Composer\DependencyResolver\DefaultPolicy;
|
use Composer\DependencyResolver\DefaultPolicy;
|
||||||
use Composer\Package\CompletePackageInterface;
|
use Composer\Package\CompletePackageInterface;
|
||||||
use Composer\Package\Version\VersionParser;
|
use Composer\Package\Version\VersionParser;
|
||||||
|
use Composer\Package\BasePackage;
|
||||||
use Composer\Package\Version\VersionSelector;
|
use Composer\Package\Version\VersionSelector;
|
||||||
use Composer\Plugin\CommandEvent;
|
use Composer\Plugin\CommandEvent;
|
||||||
use Composer\Plugin\PluginEvents;
|
use Composer\Plugin\PluginEvents;
|
||||||
|
@ -34,6 +35,8 @@ use Composer\Repository\PlatformRepository;
|
||||||
use Composer\Repository\RepositoryInterface;
|
use Composer\Repository\RepositoryInterface;
|
||||||
use Composer\Repository\RepositoryFactory;
|
use Composer\Repository\RepositoryFactory;
|
||||||
use Composer\Spdx\SpdxLicenses;
|
use Composer\Spdx\SpdxLicenses;
|
||||||
|
use Composer\Composer;
|
||||||
|
use Composer\Semver\Semver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Robert Schönthal <seroscho@googlemail.com>
|
* @author Robert Schönthal <seroscho@googlemail.com>
|
||||||
|
@ -46,9 +49,6 @@ class ShowCommand extends BaseCommand
|
||||||
protected $versionParser;
|
protected $versionParser;
|
||||||
protected $colors;
|
protected $colors;
|
||||||
|
|
||||||
/** @var CompositeRepository */
|
|
||||||
protected $repos;
|
|
||||||
|
|
||||||
/** @var Pool */
|
/** @var Pool */
|
||||||
private $pool;
|
private $pool;
|
||||||
|
|
||||||
|
@ -106,6 +106,7 @@ EOT
|
||||||
$platformOverrides = $composer->getConfig()->get('platform') ?: array();
|
$platformOverrides = $composer->getConfig()->get('platform') ?: array();
|
||||||
}
|
}
|
||||||
$platformRepo = new PlatformRepository(array(), $platformOverrides);
|
$platformRepo = new PlatformRepository(array(), $platformOverrides);
|
||||||
|
$phpVersion = $platformRepo->findPackage('php', '*')->getVersion();
|
||||||
|
|
||||||
if ($input->getOption('self')) {
|
if ($input->getOption('self')) {
|
||||||
$package = $this->getComposer()->getPackage();
|
$package = $this->getComposer()->getPackage();
|
||||||
|
@ -139,6 +140,11 @@ EOT
|
||||||
$composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
|
$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');
|
$packageFilter = $input->getArgument('package');
|
||||||
|
|
||||||
// show single package or single version
|
// show single package or single version
|
||||||
|
@ -157,8 +163,8 @@ EOT
|
||||||
$this->displayPackageTree($package, $installedRepo, $repos);
|
$this->displayPackageTree($package, $installedRepo, $repos);
|
||||||
} else {
|
} else {
|
||||||
$latestVersion = null;
|
$latestVersion = null;
|
||||||
if ($input->getOption('latest')) {
|
if ($input->getOption('latest') && $composer) {
|
||||||
$latestVersion = $this->findBestVersionForPackage($package->getName(), null);
|
$latestVersion = $this->findBestVersionForPackage($package->getName(), $composer, $phpVersion);
|
||||||
}
|
}
|
||||||
$this->printMeta($package, $versions, $installedRepo, $latestVersion);
|
$this->printMeta($package, $versions, $installedRepo, $latestVersion);
|
||||||
$this->printLinks($package, 'requires');
|
$this->printLinks($package, 'requires');
|
||||||
|
@ -285,9 +291,9 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($writeLatest) {
|
if ($writeLatest) {
|
||||||
$latestVersion = $this->findBestVersionForPackage($package->getName());
|
$latestVersion = $this->findBestVersionForPackage($package->getName(), $composer, $phpVersion);
|
||||||
$type = $latestVersion == $package->getFullPrettyVersion() ? 'info' : 'comment';
|
$style = $this->getVersionStyle($latestVersion, $package);
|
||||||
$io->write(' <'.$type.'>' . str_pad($latestVersion, $latestLength, ' ') . '</'.$type.'>', false);
|
$io->write(' <'.$style.'>' . str_pad($latestVersion, $latestLength, ' ') . '</'.$style.'>', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($writeDescription) {
|
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
|
* finds a package by name and version if provided
|
||||||
*
|
*
|
||||||
|
@ -376,7 +398,8 @@ EOT
|
||||||
$io->write('<info>keywords</info> : ' . join(', ', $package->getKeywords() ?: array()));
|
$io->write('<info>keywords</info> : ' . join(', ', $package->getKeywords() ?: array()));
|
||||||
$this->printVersions($package, $versions, $installedRepo);
|
$this->printVersions($package, $versions, $installedRepo);
|
||||||
if ($latestVersion) {
|
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());
|
$io->write('<info>type</info> : ' . $package->getType());
|
||||||
$this->printLicenses($package);
|
$this->printLicenses($package);
|
||||||
|
@ -621,41 +644,30 @@ EOT
|
||||||
* @throws \InvalidArgumentException
|
* @throws \InvalidArgumentException
|
||||||
* @return string|null
|
* @return string|null
|
||||||
*/
|
*/
|
||||||
private function findBestVersionForPackage($name)
|
private function findBestVersionForPackage($name, Composer $composer, $phpVersion)
|
||||||
{
|
{
|
||||||
// find the latest version allowed in this pool
|
// find the latest version allowed in this pool
|
||||||
$versionSelector = new VersionSelector($this->getPool());
|
$versionSelector = new VersionSelector($this->getPool($composer));
|
||||||
$package = $versionSelector->findBestCandidate($name);
|
$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) {
|
if ($package) {
|
||||||
return $package->getPrettyVersion();
|
return $package->getPrettyVersion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getRepos()
|
private function getPool(Composer $composer)
|
||||||
{
|
|
||||||
if (!$this->repos) {
|
|
||||||
$this->repos = new CompositeRepository(array_merge(
|
|
||||||
array(new PlatformRepository),
|
|
||||||
RepositoryFactory::defaultRepos($this->getIO())
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->repos;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getPool()
|
|
||||||
{
|
{
|
||||||
if (!$this->pool) {
|
if (!$this->pool) {
|
||||||
$this->pool = new Pool($this->getMinimumStability());
|
$this->pool = new Pool($composer->getPackage()->getMinimumStability(), $composer->getPackage()->getStabilityFlags());
|
||||||
$this->pool->addRepository($this->getRepos());
|
$this->pool->addRepository(new CompositeRepository($composer->getRepositoryManager()->getRepositories()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->pool;
|
return $this->pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getMinimumStability()
|
|
||||||
{
|
|
||||||
return 'stable';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ class Application extends BaseApplication
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($commandName !== 'global') {
|
if ($commandName !== 'global' && $commandName !== 'outdated') {
|
||||||
$io->writeError(sprintf(
|
$io->writeError(sprintf(
|
||||||
'Running %s (%s) with %s on %s',
|
'Running %s (%s) with %s on %s',
|
||||||
Composer::VERSION,
|
Composer::VERSION,
|
||||||
|
@ -339,6 +339,7 @@ class Application extends BaseApplication
|
||||||
new Command\RemoveCommand(),
|
new Command\RemoveCommand(),
|
||||||
new Command\HomeCommand(),
|
new Command\HomeCommand(),
|
||||||
new Command\ExecCommand(),
|
new Command\ExecCommand(),
|
||||||
|
new Command\OutdatedCommand(),
|
||||||
));
|
));
|
||||||
|
|
||||||
if ('phar:' === substr(__FILE__, 0, 5)) {
|
if ('phar:' === substr(__FILE__, 0, 5)) {
|
||||||
|
|
Loading…
Reference in New Issue