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\RepositoryInterface;
  15. use Composer\Repository\ArrayRepository;
  16. use Composer\Util\ProcessExecutor;
  17. use Symfony\Component\Console\Input\InputArgument;
  18. use Symfony\Component\Console\Input\InputOption;
  19. use Symfony\Component\Console\Input\InputInterface;
  20. use Symfony\Component\Console\Output\OutputInterface;
  21. /**
  22. * @author Robert Schönthal <seroscho@googlemail.com>
  23. */
  24. class HomeCommand extends Command
  25. {
  26. /**
  27. * {@inheritDoc}
  28. */
  29. protected function configure()
  30. {
  31. $this
  32. ->setName('browse')
  33. ->setAliases(array('home'))
  34. ->setDescription('Opens the package\'s repository URL or homepage in your browser.')
  35. ->setDefinition(array(
  36. new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'Package(s) to browse to.'),
  37. new InputOption('homepage', 'H', InputOption::VALUE_NONE, 'Open the homepage instead of the repository URL.'),
  38. new InputOption('show', 's', InputOption::VALUE_NONE, 'Only show the homepage or repository URL.'),
  39. ))
  40. ->setHelp(<<<EOT
  41. The home command opens or shows a package's repository URL or
  42. homepage in your default browser.
  43. To open the homepage by default, use -H or --homepage.
  44. To show instead of open the repository or homepage URL, use -s or --show.
  45. EOT
  46. );
  47. }
  48. /**
  49. * {@inheritDoc}
  50. */
  51. protected function execute(InputInterface $input, OutputInterface $output)
  52. {
  53. $repos = $this->initializeRepos();
  54. $io = $this->getIO();
  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. $io->writeError('<warning>Package '.$packageName.' not found</warning>');
  71. }
  72. if (!$handled) {
  73. $return = 1;
  74. $io->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. }