From d6589ac15189cfda7225c950989ece227bc78703 Mon Sep 17 00:00:00 2001 From: Niels Keurentjes Date: Thu, 28 Jan 2016 23:01:04 +0100 Subject: [PATCH] Rewrote SuggestsCommand --- src/Composer/Command/SuggestsCommand.php | 97 +++++++++++++++++------- 1 file changed, 70 insertions(+), 27 deletions(-) diff --git a/src/Composer/Command/SuggestsCommand.php b/src/Composer/Command/SuggestsCommand.php index d59ef1dc6..93aae86a0 100644 --- a/src/Composer/Command/SuggestsCommand.php +++ b/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(<<%command.name% command shows suggested packages. +The %command.name% command shows a sorted list of suggested packages. -With -v you also see which package suggested it and why. +Enabling -v implies --by-package --by-suggestion, 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('%s', $suggestion)); } + return; + } + + // Grouped by package + if ($mode & 1) { + foreach ($suggesters as $suggester => $suggestions) { + $io->write(sprintf('%s suggests:', $suggester)); - $this->printSuggestion($source, $suggestion, $reason); + foreach ($suggestions as $suggestion => $reason) { + $io->write(sprintf(' - %s: %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('%s is suggested by:', $suggestion)); - if ($io->isVerbose()) { - $io->write(sprintf('%s suggests %s: %s', $package, $suggestion, $reason)); - } else { - $io->write(sprintf('%s', $suggestion)); + foreach ($suggesters as $suggester => $reason) { + $io->write(sprintf(' - %s: %s', $suggester, $reason ?: '*')); + } + $io->write(''); + } } } }