diff --git a/doc/03-cli.md b/doc/03-cli.md index b8921511c..6182db682 100644 --- a/doc/03-cli.md +++ b/doc/03-cli.md @@ -87,7 +87,7 @@ resolution. installing a package, you can use `--dry-run`. This will simulate the installation and show you what would happen. * **--dev:** Install packages listed in `require-dev` (this is the default behavior). -* **--no-dev:** Skip installing packages listed in `require-dev`. The autoloader +* **--no-dev:** Skip installing packages listed in `require-dev`. The autoloader generation skips the `autoload-dev` rules. * **--no-autoloader:** Skips autoloader generation. * **--no-scripts:** Skips execution of scripts defined in `composer.json`. @@ -294,6 +294,18 @@ in your browser. * **--homepage (-H):** Open the homepage instead of the repository URL. +## suggests + +Lists all packages suggested by currently installed set of packages. You can +optionally pass one or multiple package names in the format of `vendor/package` +to limit output to suggestions made by those packages only. + +### Options + +* **--no-dev:** Excludes suggestions from `require-dev` packages. +* **-v[v]:** Increased verbosity adds suggesting package name (`-v`) and + reason for suggestion (`-vv`). + ## depends The `depends` command tells you which other packages depend on a certain @@ -375,7 +387,7 @@ sudo composer self-update ### Options * **--rollback (-r):** Rollback to the last version you had installed. -* **--clean-backups:** Delete old backups during an update. This makes the +* **--clean-backups:** Delete old backups during an update. This makes the current version of Composer the only backup available after the update. ## config diff --git a/src/Composer/Command/SuggestsCommand.php b/src/Composer/Command/SuggestsCommand.php new file mode 100644 index 000000000..c6f7385fd --- /dev/null +++ b/src/Composer/Command/SuggestsCommand.php @@ -0,0 +1,98 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Command; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class SuggestsCommand extends Command +{ + protected function configure() + { + $this + ->setName('suggests') + ->setDescription('Show package suggestions') + ->setDefinition(array( + new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Exclude suggestions from require-dev packages'), + new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Packages that you want to list suggestions from.'), + )) + ->setHelp(<<%command.name% command shows suggested packages. + +EOT + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $lock = $this->getComposer()->getLocker()->getLockData(); + + if (empty($lock)) { + throw new \RuntimeException('Lockfile seems to be empty?'); + } + + $packages = $lock['packages']; + + if (!$input->getOption('no-dev')) { + $packages += $lock['packages-dev']; + } + + $filter = $input->getArgument('packages'); + + foreach ($packages as $package) { + if (empty($package['suggest'])) { + continue; + } + + if (!empty($filter) && !in_array($package['name'], $filter)) { + continue; + } + + $this->printSuggestions($packages, $package['name'], $package['suggest']); + } + } + + protected function printSuggestions($installed, $source, $suggestions) + { + foreach ($suggestions as $suggestion => $reason) { + foreach ($installed as $package) { + if ($package['name'] === $suggestion) { + continue 2; + } + } + + if (empty($reason)) { + $reason = '*'; + } + + $this->printSuggestion($source, $suggestion, $reason); + } + } + + protected function printSuggestion($package, $suggestion, $reason) + { + $io = $this->getIO(); + + if ($io->isVeryVerbose()) { + $io->write(sprintf('%s suggests %s: %s', $package, $suggestion, $reason)); + } elseif ($io->isVerbose()) { + $io->write(sprintf('%s suggests %s', $package, $suggestion)); + } else { + $io->write(sprintf('%s', $suggestion)); + } + } +} diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php index 8f92c9c55..91ad1f9d4 100644 --- a/src/Composer/Console/Application.php +++ b/src/Composer/Console/Application.php @@ -272,6 +272,7 @@ class Application extends BaseApplication $commands[] = new Command\SearchCommand(); $commands[] = new Command\ValidateCommand(); $commands[] = new Command\ShowCommand(); + $commands[] = new Command\SuggestsCommand(); $commands[] = new Command\RequireCommand(); $commands[] = new Command\DumpAutoloadCommand(); $commands[] = new Command\StatusCommand();