Skip to content

Commit

Permalink
Add vcs driver for git bitbucket
Browse files Browse the repository at this point in the history
  • Loading branch information
francoispluchino committed Oct 4, 2014
1 parent 9c69ed7 commit 31ea027
Show file tree
Hide file tree
Showing 4 changed files with 299 additions and 15 deletions.
12 changes: 7 additions & 5 deletions Assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,19 @@ class Assets
* @var array
*/
protected static $vcsRepositoryDrivers = array(
'vcs' => 'Fxp\Composer\AssetPlugin\Repository\AssetVcsRepository',
'github' => 'Fxp\Composer\AssetPlugin\Repository\AssetVcsRepository',
'git' => 'Fxp\Composer\AssetPlugin\Repository\AssetVcsRepository',
'vcs' => 'Fxp\Composer\AssetPlugin\Repository\AssetVcsRepository',
'github' => 'Fxp\Composer\AssetPlugin\Repository\AssetVcsRepository',
'git-bitbucket' => 'Fxp\Composer\AssetPlugin\Repository\AssetVcsRepository',
'git' => 'Fxp\Composer\AssetPlugin\Repository\AssetVcsRepository',
);

/**
* @var array
*/
protected static $vcsDrivers = array(
'github' => 'Fxp\Composer\AssetPlugin\Repository\Vcs\GitHubDriver',
'git' => 'Fxp\Composer\AssetPlugin\Repository\Vcs\GitDriver',
'github' => 'Fxp\Composer\AssetPlugin\Repository\Vcs\GitHubDriver',
'git-bitbucket' => 'Fxp\Composer\AssetPlugin\Repository\Vcs\GitBitbucketDriver',
'git' => 'Fxp\Composer\AssetPlugin\Repository\Vcs\GitDriver',
);

/**
Expand Down
99 changes: 99 additions & 0 deletions Repository/Vcs/GitBitbucketDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?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\Cache;
use Composer\Json\JsonFile;
use Composer\Repository\Vcs\GitBitbucketDriver as BaseGitBitbucketDriver;

/**
* Git Bitbucket vcs driver.
*
* @author François Pluchino <francois.pluchino@gmail.com>
*/
class GitBitbucketDriver extends BaseGitBitbucketDriver
{
/**
* @var Cache
*/
protected $cache;

/**
* {@inheritDoc}
*/
public function initialize()
{
parent::initialize();

$this->cache = new Cache($this->io, $this->config->get('cache-repo-dir').'/'.$this->originUrl.'/'.$this->owner.'/'.$this->repository);
}

/**
* {@inheritDoc}
*/
public function getComposerInformation($identifier)
{
$this->infoCache[$identifier] = Util::readCache($this->infoCache, $this->cache, $this->repoConfig['asset-type'], $identifier);

if (!isset($this->infoCache[$identifier])) {
$resource = $this->getScheme() . '://bitbucket.org/'.$this->owner.'/'.$this->repository.'/raw/'.$identifier.'/'.$this->repoConfig['filename'];
$composer = $this->getComposerContent($resource);
$composer = $this->formatComposerContent($composer, $identifier);

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 array
*/
protected function getComposerContent($resource)
{
try {
$composer = $this->getContents($resource);
} catch (\Exception $e) {
$composer = false;
}

if ($composer) {
return (array) JsonFile::parseJson((string) $composer, $resource);
}

return array('_nonexistent_package' => true);
}

/**
* Format composer content.
*
* @param array $composer
* @param string $identifier
*
* @return array
*/
protected function formatComposerContent(array $composer, $identifier)
{
if (!isset($composer['time']) && !array_key_exists('_nonexistent_package', $composer)) {
$resource = $this->getScheme() . '://api.bitbucket.org/1.0/repositories/'.$this->owner.'/'.$this->repository.'/changesets/'.$identifier;
$changeset = JsonFile::parseJson($this->getContents($resource), $resource);
$composer['time'] = $changeset['timestamp'];
}

return $composer;
}
}
22 changes: 12 additions & 10 deletions Tests/AssetsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,34 +23,36 @@ class AssetsTest extends \PHPUnit_Framework_TestCase
public function testGetTypes()
{
$this->assertEquals(array(
"npm",
"bower"
'npm',
'bower',
), Assets::getTypes());
}

public function testGetRegistries()
{
$this->assertEquals(array(
"npm",
"bower"
'npm',
'bower',
), array_keys(Assets::getRegistries()));
}

public function testGetVcsRepositoryDrivers()
{
$this->assertEquals(array(
"vcs",
"github",
"git"
'vcs',
'github',
'git-bitbucket',
'git',
), array_keys(Assets::getVcsRepositoryDrivers()));
}

public function testGetVcsDrivers()
{
$this->assertEquals(array(
"github",
"git"
), array_keys(Assets::getVcsDrivers()));
'github',
'git-bitbucket',
'git',
), array_keys(Assets::getVcsDrivers()));
}

public function testCreationOfInvalidType()
Expand Down
181 changes: 181 additions & 0 deletions Tests/Repository/Vcs/GitBitbucketDriverTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
<?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\Tests\Repository\Vcs;

use Composer\Downloader\TransportException;
use Composer\IO\IOInterface;
use Composer\Util\Filesystem;
use Composer\Config;
use Composer\Util\RemoteFilesystem;
use Fxp\Composer\AssetPlugin\Repository\Vcs\GitBitbucketDriver;

/**
* Tests of vcs git bitbucket repository.
*
* @author François Pluchino <francois.pluchino@gmail.com>
*/
class GitBitbucketDriverTest extends \PHPUnit_Framework_TestCase
{
/**
* @var Config
*/
private $config;

public function setUp()
{
$this->config = new Config();
$this->config->merge(array(
'config' => array(
'home' => sys_get_temp_dir() . '/composer-test',
'cache-repo-dir' => sys_get_temp_dir() . '/composer-test-cache',
),
));
}

public function tearDown()
{
$fs = new Filesystem();
$fs->removeDirectory(sys_get_temp_dir() . '/composer-test');
$fs->removeDirectory(sys_get_temp_dir() . '/composer-test-cache');
}

public function getAssetTypes()
{
return array(
array('npm', 'package.json'),
array('bower', 'bower.json'),
);
}

/**
* @dataProvider getAssetTypes
*/
public function testPublicRepositoryWithComposer($type, $filename)
{
$repoBaseUrl = 'https://bitbucket.org/composer-test/repo-name';
$repoUrl = $repoBaseUrl.'.git';
$repoApiUrl = 'https://api.bitbucket.org/1.0/repositories/composer-test/repo-name';
$identifier = 'v0.0.0';
$sha = 'SOMESHA';

$io = $this->getMock('Composer\IO\IOInterface');
$io->expects($this->any())
->method('isInteractive')
->will($this->returnValue(true));

$remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
->setConstructorArgs(array($io))
->getMock();

$remoteFilesystem->expects($this->at(0))
->method('getContents')
->with($this->equalTo('bitbucket.org'), $this->equalTo($repoApiUrl), $this->equalTo(false))
->will($this->returnValue($this->createJsonComposer(array('main_branch' => 'test_master'))));

$remoteFilesystem->expects($this->at(1))
->method('getContents')
->with($this->equalTo('bitbucket.org'), $this->equalTo($repoBaseUrl.'/raw/'.$identifier.'/'.$filename), $this->equalTo(false))
->will($this->returnValue($this->createJsonComposer(array())));

$repoConfig = array(
'url' => $repoUrl,
'asset-type' => $type,
'filename' => $filename,
);

/* @var IOInterface $io */
/* @var RemoteFilesystem $remoteFilesystem */

$driver = new GitBitbucketDriver($repoConfig, $io, $this->config, null, $remoteFilesystem);
$driver->initialize();
$this->setAttribute($driver, 'tags', array($identifier => $sha));

$this->assertEquals('test_master', $driver->getRootIdentifier());

$dist = $driver->getDist($sha);
$this->assertEquals('zip', $dist['type']);
$this->assertEquals($repoBaseUrl.'/get/SOMESHA.zip', $dist['url']);
$this->assertEquals($sha, $dist['reference']);

$source = $driver->getSource($sha);
$this->assertEquals('git', $source['type']);
$this->assertEquals($repoUrl, $source['url']);
$this->assertEquals($sha, $source['reference']);

$driver->getComposerInformation($identifier);
}

/**
* @dataProvider getAssetTypes
*/
public function testPublicRepositoryWithEmptyComposer($type, $filename)
{
$repoBaseUrl = 'https://bitbucket.org/composer-test/repo-name';
$repoUrl = $repoBaseUrl.'.git';
$identifier = 'v0.0.0';
$io = $this->getMock('Composer\IO\IOInterface');

$remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
->setConstructorArgs(array($io))
->getMock();

$remoteFilesystem->expects($this->at(0))
->method('getContents')
->with($this->equalTo('bitbucket.org'), $this->equalTo($repoBaseUrl.'/raw/'.$identifier.'/'.$filename), $this->equalTo(false))
->will($this->throwException(new TransportException('Not Found', 404)));

$repoConfig = array(
'url' => $repoUrl,
'asset-type' => $type,
'filename' => $filename,
);

/* @var IOInterface $io */
/* @var RemoteFilesystem $remoteFilesystem */

$driver = new GitBitbucketDriver($repoConfig, $io, $this->config, null, $remoteFilesystem);
$driver->initialize();

$validEmpty = array(
'_nonexistent_package' => true,
);

$this->assertSame($validEmpty, $driver->getComposerInformation($identifier));
}

/**
* @param object $object
* @param string $attribute
* @param mixed $value
*/
protected function setAttribute($object, $attribute, $value)
{
$attr = new \ReflectionProperty($object, $attribute);
$attr->setAccessible(true);
$attr->setValue($object, $value);
}

/**
* Creates the json composer content.
*
* @param array $content The composer content
* @param string $name The name of repository
*
* @return string The json content
*/
protected function createJsonComposer(array $content, $name = 'repo-name')
{
return json_encode(array_merge_recursive($content, array(
'name' => $name,
)));
}
}

0 comments on commit 31ea027

Please sign in to comment.