GitHubDriver.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <?php
  2. namespace Composer\Repository\Vcs;
  3. use Composer\Json\JsonFile;
  4. /**
  5. * @author Jordi Boggiano <j.boggiano@seld.be>
  6. */
  7. class GitHubDriver extends VcsDriver implements VcsDriverInterface
  8. {
  9. protected $owner;
  10. protected $repository;
  11. protected $tags;
  12. protected $branches;
  13. protected $rootIdentifier;
  14. protected $infoCache = array();
  15. public function __construct($url)
  16. {
  17. preg_match('#^(?:https?|http|git)://github\.com/([^/]+)/(.+?)(?:\.git)?$#', $url, $match);
  18. $this->owner = $match[1];
  19. $this->repository = $match[2];
  20. parent::__construct($url);
  21. }
  22. /**
  23. * {@inheritDoc}
  24. */
  25. public function initialize()
  26. {
  27. }
  28. /**
  29. * {@inheritDoc}
  30. */
  31. public function getRootIdentifier()
  32. {
  33. if (null === $this->rootIdentifier) {
  34. $repoData = json_decode(file_get_contents($this->getHttpSupport() . '://api.github.com/repos/'.$this->owner.'/'.$this->repository), true);
  35. $this->rootIdentifier = $repoData['master_branch'] ?: 'master';
  36. }
  37. return $this->rootIdentifier;
  38. }
  39. /**
  40. * {@inheritDoc}
  41. */
  42. public function getUrl()
  43. {
  44. return $this->url;
  45. }
  46. /**
  47. * {@inheritDoc}
  48. */
  49. public function getSource($identifier)
  50. {
  51. $label = array_search($identifier, $this->getTags()) ?: $identifier;
  52. return array('type' => 'git', 'url' => $this->getUrl(), 'reference' => $label);
  53. }
  54. /**
  55. * {@inheritDoc}
  56. */
  57. public function getDist($identifier)
  58. {
  59. $label = array_search($identifier, $this->getTags()) ?: $identifier;
  60. $url = $this->getHttpSupport() . '://github.com/'.$this->owner.'/'.$this->repository.'/zipball/'.$label;
  61. return array('type' => 'zip', 'url' => $url, 'reference' => $label, 'shasum' => '');
  62. }
  63. /**
  64. * {@inheritDoc}
  65. */
  66. public function getComposerInformation($identifier)
  67. {
  68. if (!isset($this->infoCache[$identifier])) {
  69. $composer = @file_get_contents($this->getHttpSupport() . '://raw.github.com/'.$this->owner.'/'.$this->repository.'/'.$identifier.'/composer.json');
  70. if (!$composer) {
  71. throw new \UnexpectedValueException('Failed to retrieve composer information for identifier '.$identifier.' in '.$this->getUrl());
  72. }
  73. $composer = JsonFile::parseJson($composer);
  74. if (!isset($composer['time'])) {
  75. $commit = json_decode(file_get_contents($this->getHttpSupport() . '://api.github.com/repos/'.$this->owner.'/'.$this->repository.'/commits/'.$identifier), true);
  76. $composer['time'] = $commit['commit']['committer']['date'];
  77. }
  78. $this->infoCache[$identifier] = $composer;
  79. }
  80. return $this->infoCache[$identifier];
  81. }
  82. /**
  83. * {@inheritDoc}
  84. */
  85. public function getTags()
  86. {
  87. if (null === $this->tags) {
  88. $tagsData = json_decode(file_get_contents($this->getHttpSupport() . '://api.github.com/repos/'.$this->owner.'/'.$this->repository.'/tags'), true);
  89. $this->tags = array();
  90. foreach ($tagsData as $tag) {
  91. $this->tags[$tag['name']] = $tag['commit']['sha'];
  92. }
  93. }
  94. return $this->tags;
  95. }
  96. /**
  97. * {@inheritDoc}
  98. */
  99. public function getBranches()
  100. {
  101. if (null === $this->branches) {
  102. $branchData = json_decode(file_get_contents($this->getHttpSupport() . '://api.github.com/repos/'.$this->owner.'/'.$this->repository.'/branches'), true);
  103. $this->branches = array();
  104. foreach ($branchData as $branch) {
  105. $this->branches[$branch['name']] = $branch['commit']['sha'];
  106. }
  107. }
  108. return $this->branches;
  109. }
  110. /**
  111. * {@inheritDoc}
  112. */
  113. public function hasComposerFile($identifier)
  114. {
  115. try {
  116. $this->getComposerInformation($identifier);
  117. return true;
  118. } catch (\Exception $e) {
  119. }
  120. return false;
  121. }
  122. /**
  123. * {@inheritDoc}
  124. */
  125. public static function supports($url, $deep = false)
  126. {
  127. return extension_loaded('openssl') && preg_match('#^(?:https?|git)://github\.com/([^/]+)/(.+?)(?:\.git)?$#', $url, $match);
  128. }
  129. }