HomeCommand.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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 Composer\Factory;
  13. use Composer\Package\CompletePackageInterface;
  14. use Composer\Repository\CompositeRepository;
  15. use Composer\Repository\RepositoryInterface;
  16. use Composer\Repository\ArrayRepository;
  17. use Composer\Util\ProcessExecutor;
  18. use Symfony\Component\Console\Input\InputArgument;
  19. use Symfony\Component\Console\Input\InputOption;
  20. use Symfony\Component\Console\Input\InputInterface;
  21. use Symfony\Component\Console\Output\OutputInterface;
  22. /**
  23. * @author Robert Schönthal <seroscho@googlemail.com>
  24. */
  25. class HomeCommand extends Command
  26. {
  27. /**
  28. * {@inheritDoc}
  29. */
  30. protected function configure()
  31. {
  32. $this
  33. ->setName('browse')
  34. ->setAliases(array('home'))
  35. ->setDescription('Opens the package\'s repository URL or homepage in your browser.')
  36. ->setDefinition(array(
  37. new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'Package(s) to browse to.'),
  38. new InputOption('homepage', 'H', InputOption::VALUE_NONE, 'Open the homepage instead of the repository URL.'),
  39. new InputOption('show', 's', InputOption::VALUE_NONE, 'Only show the homepage or repository URL.'),
  40. ))
  41. ->setHelp(<<<EOT
  42. The home command opens or shows a package's repository URL or
  43. homepage in your default browser.
  44. To open the homepage by default, use -H or --homepage.
  45. To show instead of open the repository or homepage URL, use -s or --show.
  46. EOT
  47. );
  48. }
  49. /**
  50. * {@inheritDoc}
  51. */
  52. protected function execute(InputInterface $input, OutputInterface $output)
  53. {
  54. $repos = $this->initializeRepos();
  55. $return = 0;
  56. foreach ($input->getArgument('packages') as $packageName) {
  57. $handled = false;
  58. $packageExists = false;
  59. foreach ($repos as $repo) {
  60. foreach ($repo->findPackages($packageName) as $package) {
  61. $packageExists = true;
  62. if ($this->handlePackage($package, $input->getOption('homepage'), $input->getOption('show'))) {
  63. $handled = true;
  64. break 2;
  65. }
  66. }
  67. }
  68. if (!$packageExists) {
  69. $return = 1;
  70. $this->getIO()->writeError('<warning>Package '.$packageName.' not found</warning>');
  71. }
  72. if (!$handled) {
  73. $return = 1;
  74. $this->getIO()->writeError('<warning>'.($input->getOption('homepage') ? 'Invalid or missing homepage' : 'Invalid or missing repository URL').' for '.$packageName.'</warning>');
  75. }
  76. }
  77. return $return;
  78. }
  79. private function handlePackage(CompletePackageInterface $package, $showHomepage, $showOnly)
  80. {
  81. $support = $package->getSupport();
  82. $url = isset($support['source']) ? $support['source'] : $package->getSourceUrl();
  83. if (!$url || $showHomepage) {
  84. $url = $package->getHomepage();
  85. }
  86. if (!$url || !filter_var($url, FILTER_VALIDATE_URL)) {
  87. return false;
  88. }
  89. if ($showOnly) {
  90. $this->getIO()->write(sprintf('<info>%s</info>', $url));
  91. } else {
  92. $this->openBrowser($url);
  93. }
  94. return true;
  95. }
  96. /**
  97. * opens a url in your system default browser
  98. *
  99. * @param string $url
  100. */
  101. private function openBrowser($url)
  102. {
  103. $url = ProcessExecutor::escape($url);
  104. if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
  105. return passthru('start "web" explorer "' . $url . '"');
  106. }
  107. passthru('which xdg-open', $linux);
  108. passthru('which open', $osx);
  109. if (0 === $linux) {
  110. passthru('xdg-open ' . $url);
  111. } elseif (0 === $osx) {
  112. passthru('open ' . $url);
  113. } else {
  114. $this->getIO()->writeError('no suitable browser opening command found, open yourself: ' . $url);
  115. }
  116. }
  117. /**
  118. * Initializes repositories
  119. *
  120. * Returns an array of repos in order they should be checked in
  121. *
  122. * @return RepositoryInterface[]
  123. */
  124. private function initializeRepos()
  125. {
  126. $composer = $this->getComposer(false);
  127. if ($composer) {
  128. return array_merge(
  129. array(new ArrayRepository(array($composer->getPackage()))), // root package
  130. array($composer->getRepositoryManager()->getLocalRepository()), // installed packages
  131. $composer->getRepositoryManager()->getRepositories() // remotes
  132. );
  133. }
  134. $defaultRepos = Factory::createDefaultRepositories($this->getIO());
  135. return $defaultRepos;
  136. }
  137. }