diff --git a/src/Composer/Command/SuggestsCommand.php b/src/Composer/Command/SuggestsCommand.php index 61875ba0b..2ae4f4414 100644 --- a/src/Composer/Command/SuggestsCommand.php +++ b/src/Composer/Command/SuggestsCommand.php @@ -14,7 +14,7 @@ namespace Composer\Command; use Composer\Repository\PlatformRepository; use Composer\Repository\RootPackageRepository; -use Composer\Repository\CompositeRepository; +use Composer\Repository\InstalledRepository; use Composer\Installer\SuggestedPackagesReporter; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -67,15 +67,10 @@ EOT $installedRepos[] = $composer->getRepositoryManager()->getLocalRepository(); } - $installedRepo = new CompositeRepository($installedRepos); + $installedRepo = new InstalledRepository($installedRepos); $reporter = new SuggestedPackagesReporter($this->getIO()); $filter = $input->getArgument('packages'); - if (empty($filter) && !$input->getOption('all')) { - $filter = array_map(function ($link) { - return $link->getTarget(); - }, array_merge($composer->getPackage()->getRequires(), $composer->getPackage()->getDevRequires())); - } foreach ($installedRepo->getPackages() as $package) { if (!empty($filter) && !in_array($package->getName(), $filter)) { continue; @@ -100,7 +95,7 @@ EOT $mode = SuggestedPackagesReporter::MODE_LIST; } - $reporter->output($mode, $installedRepo); + $reporter->output($mode, $installedRepo, empty($filter) && !$input->getOption('all') ? $composer->getPackage() : null); return 0; } diff --git a/src/Composer/Installer/SuggestedPackagesReporter.php b/src/Composer/Installer/SuggestedPackagesReporter.php index e70422d14..804873883 100644 --- a/src/Composer/Installer/SuggestedPackagesReporter.php +++ b/src/Composer/Installer/SuggestedPackagesReporter.php @@ -14,7 +14,7 @@ namespace Composer\Installer; use Composer\IO\IOInterface; use Composer\Package\PackageInterface; -use Composer\Repository\RepositoryInterface; +use Composer\Repository\InstalledRepository; use Symfony\Component\Console\Formatter\OutputFormatter; /** @@ -98,12 +98,14 @@ class SuggestedPackagesReporter * * Do not list the ones already installed if installed repository provided. * - * @param int $mode One of the MODE_* constants from this class + * @param int $mode One of the MODE_* constants from this class + * @param InstalledRepository $installedRepo If passed in, suggested packages which are installed already will be skipped + * @param PackageInterface $onlyDependentsOf If passed in, only the suggestions from direct dependents of that package will be shown * @return SuggestedPackagesReporter */ - public function output($mode, RepositoryInterface $installedRepo = null) + public function output($mode, InstalledRepository $installedRepo = null, PackageInterface $onlyDependentsOf = null) { - $suggestedPackages = $this->getFilteredSuggestions($installedRepo); + $suggestedPackages = $this->getFilteredSuggestions($installedRepo, $onlyDependentsOf); $suggesters = array(); $suggested = array(); @@ -151,19 +153,27 @@ class SuggestedPackagesReporter } } + if ($onlyDependentsOf) { + $allSuggestedPackages = $this->getFilteredSuggestions($installedRepo); + $diff = count($allSuggestedPackages) - count($suggestedPackages); + if ($diff) { + $this->io->write(''.$diff.' additional suggestions by transitive dependencies can be shown with --all'); + } + } + return $this; } /** * Output number of new suggested packages and a hint to use suggest command. - ** - * Do not list the ones already installed if installed repository provided. * + * @param InstalledRepository $installedRepo If passed in, suggested packages which are installed already will be skipped + * @param PackageInterface $onlyDependentsOf If passed in, only the suggestions from direct dependents of that package will be shown * @return SuggestedPackagesReporter */ - public function outputMinimalistic(RepositoryInterface $installedRepo = null) + public function outputMinimalistic(InstalledRepository $installedRepo = null, PackageInterface $onlyDependentsOf = null) { - $suggestedPackages = $this->getFilteredSuggestions($installedRepo); + $suggestedPackages = $this->getFilteredSuggestions($installedRepo, $onlyDependentsOf); if ($suggestedPackages) { $this->io->writeError(''.count($suggestedPackages).' package suggestions were added by new dependencies, use `composer suggest` to see details.'); } @@ -171,7 +181,12 @@ class SuggestedPackagesReporter return $this; } - private function getFilteredSuggestions(RepositoryInterface $installedRepo = null) + /** + * @param InstalledRepository $installedRepo If passed in, suggested packages which are installed already will be skipped + * @param PackageInterface $onlyDependentsOf If passed in, only the suggestions from direct dependents of that package will be shown + * @return array[] + */ + private function getFilteredSuggestions(InstalledRepository $installedRepo = null, PackageInterface $onlyDependentsOf = null) { $suggestedPackages = $this->getPackages(); $installedNames = array(); @@ -184,9 +199,16 @@ class SuggestedPackagesReporter } } + $sourceFilter = array(); + if ($onlyDependentsOf) { + $sourceFilter = array_map(function ($link) { + return $link->getTarget(); + }, array_merge($onlyDependentsOf->getRequires(), $onlyDependentsOf->getDevRequires())); + } + $suggestions = array(); foreach ($suggestedPackages as $suggestion) { - if (in_array($suggestion['target'], $installedNames)) { + if (in_array($suggestion['target'], $installedNames) || ($sourceFilter && !in_array($suggestion['source'], $sourceFilter))) { continue; }