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;
}