Browse Source

Merge remote-tracking branch 'alcohol/add-suggests-command'

Jordi Boggiano 9 years ago
parent
commit
5ba41514a9
3 changed files with 113 additions and 2 deletions
  1. 14 2
      doc/03-cli.md
  2. 98 0
      src/Composer/Command/SuggestsCommand.php
  3. 1 0
      src/Composer/Console/Application.php

+ 14 - 2
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

+ 98 - 0
src/Composer/Command/SuggestsCommand.php

@@ -0,0 +1,98 @@
+<?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 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(<<<EOT
+
+The <info>%command.name%</info> 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('<comment>%s</comment> suggests <info>%s</info>: %s', $package, $suggestion, $reason));
+        } elseif ($io->isVerbose()) {
+            $io->write(sprintf('<comment>%s</comment> suggests <info>%s</info>', $package, $suggestion));
+        } else {
+            $io->write(sprintf('<info>%s</info>', $suggestion));
+        }
+    }
+}

+ 1 - 0
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();