Pārlūkot izejas kodu

Rewrote SuggestsCommand

Niels Keurentjes 9 gadi atpakaļ
vecāks
revīzija
d6589ac151
1 mainītis faili ar 70 papildinājumiem un 27 dzēšanām
  1. 70 27
      src/Composer/Command/SuggestsCommand.php

+ 70 - 27
src/Composer/Command/SuggestsCommand.php

@@ -25,14 +25,16 @@ class SuggestsCommand extends Command
             ->setName('suggests')
             ->setDescription('Show package suggestions')
             ->setDefinition(array(
+                new InputOption('by-package', null, InputOption::VALUE_NONE, 'Groups output by suggesting package'),
+                new InputOption('by-suggestion', null, InputOption::VALUE_NONE, 'Groups output by suggested package'),
                 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.
+The <info>%command.name%</info> command shows a sorted list of suggested packages.
 
-With <info>-v</info> you also see which package suggested it and why.
+Enabling <info>-v</info> implies <info>--by-package --by-suggestion</info>, showing both lists.
 
 EOT
             )
@@ -55,44 +57,85 @@ EOT
 
         $filter = $input->getArgument('packages');
 
-        foreach ($packages as $package) {
-            if (empty($package['suggest'])) {
-                continue;
-            }
+        // First assemble list of packages that are installed, replaced or provided
+        $installed = array();
+        foreach($packages as $package) {
+            $installed[] = $package['name'];
 
-            if (!empty($filter) && !in_array($package['name'], $filter)) {
-                continue;
+            if (!empty($package['provide'])) {
+                $installed = array_merge($installed, array_keys($package['provide']));
             }
 
-            $this->printSuggestions($packages, $package['name'], $package['suggest']);
+            if (!empty($package['replace'])) {
+                $installed = array_merge($installed, array_keys($package['replace']));
+            }
         }
-    }
+        sort($installed);
+        $installed = array_unique($installed);
 
-    protected function printSuggestions($installed, $source, $suggestions)
-    {
-        foreach ($suggestions as $suggestion => $reason) {
-            foreach ($installed as $package) {
-                if ($package['name'] === $suggestion) {
-                    continue 2;
+        // Next gather all suggestions that are not in that list
+        $suggesters = array();
+        $suggested = array();
+        foreach ($packages as $package) {
+            if ((empty($filter) || in_array($package['name'], $filter)) && !empty($package['suggest'])) {
+                foreach ($package['suggest'] as $suggestion => $reason) {
+                    if (!in_array($suggestion, $installed)) {
+                        $suggesters[$package['name']][$suggestion] = $reason;
+                        $suggested[$suggestion][$package['name']] = $reason;
+                    }
                 }
             }
+        }
+        ksort($suggesters);
+        ksort($suggested);
+
+        // Determine output mode
+        $mode = 0;
+        $io = $this->getIO();
+        if ($input->getOption('by-package')) {
+            $mode |= 1;
+        }
+        if ($input->getOption('by-suggestion')) {
+            $mode |= 2;
+        }
+        if ($io->isVerbose()) {
+            $mode = ~0;
+        }
 
-            if (empty($reason)) {
-                $reason = '*';
+        // Simple mode
+        if ($mode == 0) {
+            foreach (array_keys($suggested) as $suggestion) {
+                $io->write(sprintf('<info>%s</info>', $suggestion));
             }
+            return;
+        }
+
+        // Grouped by package
+        if ($mode & 1) {
+            foreach ($suggesters as $suggester => $suggestions) {
+                $io->write(sprintf('<comment>%s</comment> suggests:', $suggester));
 
-            $this->printSuggestion($source, $suggestion, $reason);
+                foreach ($suggestions as $suggestion => $reason) {
+                    $io->write(sprintf(' - <info>%s</info>: %s', $suggestion, $reason ?: '*'));
+                }
+                $io->write('');
+            }
         }
-    }
 
-    protected function printSuggestion($package, $suggestion, $reason)
-    {
-        $io = $this->getIO();
+        // Grouped by suggestion
+        if ($mode & 2) {
+            // Improve readability in full mode
+            if ($mode & 1) {
+                $io->write(str_repeat('-', 78));
+            }
+            foreach ($suggested as $suggestion => $suggesters) {
+                $io->write(sprintf('<comment>%s</comment> is suggested by:', $suggestion));
 
-        if ($io->isVerbose()) {
-            $io->write(sprintf('<comment>%s</comment> suggests <info>%s</info>: %s', $package, $suggestion, $reason));
-        } else {
-            $io->write(sprintf('<info>%s</info>', $suggestion));
+                foreach ($suggesters as $suggester => $reason) {
+                    $io->write(sprintf(' - <info>%s</info>: %s', $suggester, $reason ?: '*'));
+                }
+                $io->write('');
+            }
         }
     }
 }