153 lines
4.8 KiB
PHP
153 lines
4.8 KiB
PHP
|
<?php
|
||
|
|
||
|
/*
|
||
|
* This file is part of the Fxp Composer Asset Plugin package.
|
||
|
*
|
||
|
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||
|
*
|
||
|
* For the full copyright and license information, please view the LICENSE
|
||
|
* file that was distributed with this source code.
|
||
|
*/
|
||
|
|
||
|
namespace Fxp\Composer\AssetPlugin\Repository\Vcs;
|
||
|
|
||
|
use Composer\Downloader\TransportException;
|
||
|
use Composer\Json\JsonFile;
|
||
|
|
||
|
/**
|
||
|
* GitHub vcs driver.
|
||
|
*
|
||
|
* @author François Pluchino <francois.pluchino@gmail.com>
|
||
|
*/
|
||
|
class GitHubDriver extends AbstractGitHubDriver
|
||
|
{
|
||
|
/**
|
||
|
* {@inheritdoc}
|
||
|
*/
|
||
|
public function getComposerInformation($identifier)
|
||
|
{
|
||
|
if ($this->gitDriver) {
|
||
|
return $this->gitDriver->getComposerInformation($identifier);
|
||
|
}
|
||
|
|
||
|
$this->infoCache[$identifier] = Util::readCache($this->infoCache, $this->cache, $this->repoConfig['asset-type'], $identifier);
|
||
|
|
||
|
if (!isset($this->infoCache[$identifier])) {
|
||
|
$resource = $this->getApiUrl().'/repos/'.$this->owner.'/'.$this->repository.'/contents/'.$this->repoConfig['filename'].'?ref='.urlencode($identifier);
|
||
|
$composer = $this->getComposerContent($resource);
|
||
|
|
||
|
if ($composer) {
|
||
|
$composer = $this->convertComposerContent($composer, $resource, $identifier);
|
||
|
} else {
|
||
|
$composer = array('_nonexistent_package' => true);
|
||
|
}
|
||
|
|
||
|
Util::writeCache($this->cache, $this->repoConfig['asset-type'], $identifier, $composer);
|
||
|
$this->infoCache[$identifier] = $composer;
|
||
|
}
|
||
|
|
||
|
return $this->infoCache[$identifier];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Gets content of composer information.
|
||
|
*
|
||
|
* @param string $resource
|
||
|
*
|
||
|
* @return null|false|array
|
||
|
*
|
||
|
* @throws \RuntimeException
|
||
|
* @throws \Composer\Downloader\TransportException
|
||
|
* @throws \Exception
|
||
|
*/
|
||
|
protected function getComposerContent($resource)
|
||
|
{
|
||
|
$notFoundRetries = 2;
|
||
|
$composer = null;
|
||
|
|
||
|
while ($notFoundRetries) {
|
||
|
try {
|
||
|
$composer = $this->parseComposerContent($resource);
|
||
|
break;
|
||
|
} catch (TransportException $e) {
|
||
|
if (404 !== $e->getCode()) {
|
||
|
throw $e;
|
||
|
}
|
||
|
|
||
|
// retry fetching if github returns a 404 since they happen randomly
|
||
|
--$notFoundRetries;
|
||
|
$composer = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $composer;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Parse the composer content.
|
||
|
*
|
||
|
* @param string $resource
|
||
|
*
|
||
|
* @return array
|
||
|
*
|
||
|
* @throws \RuntimeException When the resource could not be retrieved
|
||
|
*/
|
||
|
protected function parseComposerContent($resource)
|
||
|
{
|
||
|
$composer = (array) JsonFile::parseJson($this->getContents($resource));
|
||
|
if (empty($composer['content']) || $composer['encoding'] !== 'base64' || !($composer = base64_decode($composer['content']))) {
|
||
|
throw new \RuntimeException('Could not retrieve '.$this->repoConfig['filename'].' from '.$resource);
|
||
|
}
|
||
|
|
||
|
return $composer;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Converts json composer file to array.
|
||
|
*
|
||
|
* @param string $composer
|
||
|
* @param string $resource
|
||
|
* @param string $identifier
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
protected function convertComposerContent($composer, $resource, $identifier)
|
||
|
{
|
||
|
$composer = JsonFile::parseJson($composer, $resource);
|
||
|
$resource = $this->getApiUrl().'/repos/'.$this->owner.'/'.$this->repository.'/commits/'.urlencode($identifier);
|
||
|
$composer = Util::addComposerTime($composer, 'commit.committer.date', $resource, $this);
|
||
|
|
||
|
if (!isset($composer['support']['source'])) {
|
||
|
$label = array_search($identifier, $this->getTags()) ?: array_search($identifier, $this->getBranches()) ?: $identifier;
|
||
|
$composer['support']['source'] = sprintf('https://%s/%s/%s/tree/%s', $this->originUrl, $this->owner, $this->repository, $label);
|
||
|
}
|
||
|
if (!isset($composer['support']['issues']) && $this->hasIssues) {
|
||
|
$composer['support']['issues'] = sprintf('https://%s/%s/%s/issues', $this->originUrl, $this->owner, $this->repository);
|
||
|
}
|
||
|
|
||
|
return $composer;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Setup git driver.
|
||
|
*
|
||
|
* @param string $url
|
||
|
*/
|
||
|
protected function setupGitDriver($url)
|
||
|
{
|
||
|
$this->gitDriver = new GitDriver(
|
||
|
array(
|
||
|
'url' => $url,
|
||
|
'asset-type' => $this->repoConfig['asset-type'],
|
||
|
'filename' => $this->repoConfig['filename'],
|
||
|
'asset-repository-manager' => $this->repoConfig['asset-repository-manager'],
|
||
|
),
|
||
|
$this->io,
|
||
|
$this->config,
|
||
|
$this->process,
|
||
|
$this->remoteFilesystem
|
||
|
);
|
||
|
$this->gitDriver->initialize();
|
||
|
}
|
||
|
}
|