SearchCommand.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. <?php
  2. /*
  3. * This file is part of Composer.
  4. *
  5. * (c) Nils Adermann <naderman@naderman.de>
  6. * Jordi Boggiano <j.boggiano@seld.be>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Composer\Command;
  12. use Symfony\Component\Console\Input\InputInterface;
  13. use Symfony\Component\Console\Input\InputArgument;
  14. use Symfony\Component\Console\Output\OutputInterface;
  15. use Composer\Repository\CompositeRepository;
  16. use Composer\Repository\PlatformRepository;
  17. use Composer\Repository\ComposerRepository;
  18. use Composer\Package\PackageInterface;
  19. /**
  20. * @author Robert Schönthal <seroscho@googlemail.com>
  21. */
  22. class SearchCommand extends Command
  23. {
  24. protected function configure()
  25. {
  26. $this
  27. ->setName('search')
  28. ->setDescription('Search for packages')
  29. ->setDefinition(array(
  30. new InputArgument('tokens', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'tokens to search for'),
  31. ))
  32. ->setHelp(<<<EOT
  33. The search command searches for packages by its name
  34. <info>php composer.phar search symfony composer</info>
  35. EOT
  36. )
  37. ;
  38. }
  39. protected function execute(InputInterface $input, OutputInterface $output)
  40. {
  41. // init repos
  42. $platformRepo = new PlatformRepository;
  43. if ($composer = $this->getComposer(false)) {
  44. $localRepo = $composer->getRepositoryManager()->getLocalRepository();
  45. $installedRepo = new CompositeRepository(array($localRepo, $platformRepo));
  46. $repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories()));
  47. } else {
  48. $output->writeln('No composer.json found in the current directory, showing packages from packagist.org');
  49. $installedRepo = $platformRepo;
  50. $repos = new CompositeRepository(array($installedRepo, new ComposerRepository(array('url' => 'http://packagist.org'))));
  51. }
  52. $tokens = array_map('strtolower', $input->getArgument('tokens'));
  53. $packages = array();
  54. foreach ($repos->getPackages() as $package) {
  55. foreach ($tokens as $token) {
  56. if ($this->isUnmatchedPackage($package, $token)) {
  57. continue;
  58. }
  59. if (false !== ($pos = strpos($package->getName(), $token))) {
  60. $name = substr($package->getPrettyName(), 0, $pos)
  61. . '<highlight>' . substr($package->getPrettyName(), $pos, strlen($token)) . '</highlight>'
  62. . substr($package->getPrettyName(), $pos + strlen($token));
  63. } else {
  64. $name = $package->getPrettyName();
  65. }
  66. $version = $installedRepo->hasPackage($package) ? '<info>'.$package->getPrettyVersion().'</info>' : $package->getPrettyVersion();
  67. $packages[$name][$package->getPrettyVersion()] = $version;
  68. continue 2;
  69. }
  70. }
  71. foreach ($packages as $name => $versions) {
  72. $output->writeln($name .' <comment>:</comment> '. join(', ', $versions));
  73. }
  74. }
  75. /**
  76. * tries to find a token within the name/keywords/description
  77. *
  78. * @param PackageInterface $package
  79. * @param string $token
  80. * @return boolean
  81. */
  82. private function isUnmatchedPackage(PackageInterface $package, $token)
  83. {
  84. return (false === strpos($package->getName(), $token)) &&
  85. (false === strpos(join(',',$package->getKeywords() ?: array()), $token)) &&
  86. (false === strpos($package->getDescription(), $token))
  87. ;
  88. }
  89. }