diff --git a/doc/03-cli.md b/doc/03-cli.md index a5e0d5de4..76f0125f8 100644 --- a/doc/03-cli.md +++ b/doc/03-cli.md @@ -408,6 +408,7 @@ php composer.phar show monolog/monolog 1.0.2 * **--tree (-t):** List your dependencies as a tree. If you pass a package name it will show the dependency tree for that package. * **--latest (-l):** List all installed packages including their latest version. * **--outdated (-o):** Implies --latest, but this lists *only* packages that have a newer version available. +* **--no-dev:** Filters dev dependencies from the package list. * **--minor-only (-m):** Use with --latest. Only shows packages that have minor SemVer-compatible updates. * **--direct (-D):** Restricts the list of packages to your direct dependencies. * **--strict:** Return a non-zero exit code when there are outdated packages. @@ -433,6 +434,7 @@ The color coding is as such: * **--strict:** Returns non-zero exit code if any package is outdated. * **--minor-only (-m):** Only shows packages that have minor SemVer-compatible updates. * **--format (-f):** Lets you pick between text (default) or json output format. +* **--no-dev:** Do not show outdated dev dependencies. ## browse / home diff --git a/src/Composer/Command/OutdatedCommand.php b/src/Composer/Command/OutdatedCommand.php index 599087246..b08c3cb46 100644 --- a/src/Composer/Command/OutdatedCommand.php +++ b/src/Composer/Command/OutdatedCommand.php @@ -37,6 +37,7 @@ class OutdatedCommand extends ShowCommand new InputOption('minor-only', 'm', InputOption::VALUE_NONE, 'Show only packages that have minor SemVer-compatible updates. Use with the --outdated option.'), new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text'), new InputOption('ignore', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore specified package(s). Use it with the --outdated option if you don\'t want to be informed about new versions of some packages.'), + new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables search in require-dev packages.'), )) ->setHelp( <<getOption('minor-only')) { $args['--minor-only'] = true; } + if ($input->getOption('no-dev')) { + $args['--no-dev'] = true; + } $args['--format'] = $input->getOption('format'); $args['--ignore'] = $input->getOption('ignore'); diff --git a/src/Composer/Command/ShowCommand.php b/src/Composer/Command/ShowCommand.php index 1396a5c7a..5541b53a8 100644 --- a/src/Composer/Command/ShowCommand.php +++ b/src/Composer/Command/ShowCommand.php @@ -22,6 +22,7 @@ use Composer\Package\Version\VersionParser; use Composer\Package\Version\VersionSelector; use Composer\Plugin\CommandEvent; use Composer\Plugin\PluginEvents; +use Composer\Repository\InstalledArrayRepository; use Composer\Repository\ComposerRepository; use Composer\Repository\CompositeRepository; use Composer\Repository\PlatformRepository; @@ -81,6 +82,7 @@ class ShowCommand extends BaseCommand new InputOption('direct', 'D', InputOption::VALUE_NONE, 'Shows only packages that are directly required by the root package'), new InputOption('strict', null, InputOption::VALUE_NONE, 'Return a non-zero exit code when there are outdated packages'), new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text'), + new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables search in require-dev packages.'), )) ->setHelp( <<getRepositoryManager()->getRepositories())); } else { - $repos = $installedRepo = new InstalledRepository(array($this->getComposer()->getRepositoryManager()->getLocalRepository())); - $rootPkg = $this->getComposer()->getPackage(); + // --installed / default case + if (!$composer) { + $composer = $this->getComposer(); + } + $rootPkg = $composer->getPackage(); + $repos = $installedRepo = new InstalledRepository(array($composer->getRepositoryManager()->getLocalRepository())); + + if ($input->getOption('no-dev')) { + $packages = $this->filterRequiredPackages($installedRepo, $rootPkg); + $repos = $installedRepo = new InstalledRepository(array(new InstalledArrayRepository(array_map(function ($pkg) { return clone $pkg; }, $packages)))); + } + if (!$installedRepo->getPackages() && ($rootPkg->getRequires() || $rootPkg->getDevRequires())) { $io->writeError('No dependencies installed. Try running composer install or update.'); } @@ -1221,4 +1233,31 @@ EOT return $this->repositorySet; } + + /** + * Find package requires and child requires + * + * @param RepositoryInterface $repo + * @param PackageInterface $package + * @param array $bucket + * @return array + */ + private function filterRequiredPackages(RepositoryInterface $repo, PackageInterface $package, $bucket = array()) + { + $requires = $package->getRequires(); + + foreach ($repo->getPackages() as $candidate) { + foreach ($candidate->getNames() as $name) { + if (isset($requires[$name])) { + if (!in_array($candidate, $bucket, true)) { + $bucket[] = $candidate; + $bucket = $this->filterRequiredPackages($repo, $candidate, $bucket); + } + break; + } + } + } + + return $bucket; + } }