Skip to content

Commit

Permalink
Add vcs driver for perforce
Browse files Browse the repository at this point in the history
  • Loading branch information
francoispluchino committed Oct 6, 2014
1 parent 506be93 commit 0ec5412
Show file tree
Hide file tree
Showing 7 changed files with 594 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class Assets
'git' => 'Fxp\Composer\AssetPlugin\Repository\AssetVcsRepository',
'hg-bitbucket' => 'Fxp\Composer\AssetPlugin\Repository\AssetVcsRepository',
'hg' => 'Fxp\Composer\AssetPlugin\Repository\AssetVcsRepository',
'perforce' => 'Fxp\Composer\AssetPlugin\Repository\AssetVcsRepository',
'svn' => 'Fxp\Composer\AssetPlugin\Repository\AssetVcsRepository',
);

Expand All @@ -58,6 +59,7 @@ class Assets
'git' => 'Fxp\Composer\AssetPlugin\Repository\Vcs\GitDriver',
'hg-bitbucket' => 'Fxp\Composer\AssetPlugin\Repository\Vcs\HgBitbucketDriver',
'hg' => 'Fxp\Composer\AssetPlugin\Repository\Vcs\HgDriver',
'perforce' => 'Fxp\Composer\AssetPlugin\Repository\Vcs\PerforceDriver',
// svn must be last because identifying a subversion server for sure is practically impossible
'svn' => 'Fxp\Composer\AssetPlugin\Repository\Vcs\SvnDriver',
);
Expand Down
110 changes: 110 additions & 0 deletions Repository/Vcs/PerforceDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?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\Repository\Vcs\PerforceDriver as BasePerforceDriver;
use Fxp\Composer\AssetPlugin\Util\Perforce;

/**
* Perforce vcs driver.
*
* @author François Pluchino <francois.pluchino@gmail.com>
*/
class PerforceDriver extends BasePerforceDriver
{
/**
* @var Perforce
*/
protected $perforce;

/**
* @var array
*/
protected $infoCache = array();

/**
* @var Cache
*/
protected $cache;

/**
* {@inheritDoc}
*/
public function initialize()
{
$this->depot = $this->repoConfig['depot'];
$this->branch = '';
if (!empty($this->repoConfig['branch'])) {
$this->branch = $this->repoConfig['branch'];
}

$this->initAssetPerforce($this->repoConfig);
$this->perforce->p4Login($this->io);
$this->perforce->checkStream($this->depot);

$this->perforce->writeP4ClientSpec();
$this->perforce->connectClient();

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

return true;
}

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

if (!isset($this->infoCache[$identifier])) {
$composer = $this->getComposerContent($identifier);

Util::writeCache($this->cache, $this->repoConfig['asset-type'], $identifier, $composer, true);
$this->infoCache[$identifier] = $composer;
}

return $this->infoCache[$identifier];
}

/**
* Get composer content.
*
* @param string $identifier
*
* @return array
*/
protected function getComposerContent($identifier)
{
$composer = $this->perforce->getComposerInformation($identifier);

if (empty($composer) || !is_array($composer)) {
$composer = array('_nonexistent_package' => true);
}

return $composer;
}

/**
* @param array $repoConfig
*/
private function initAssetPerforce($repoConfig)
{
if (!empty($this->perforce)) {
return;
}

$repoDir = $this->config->get('cache-vcs-dir') . '/' . $this->depot;
$this->perforce = Perforce::create($repoConfig, $this->getUrl(), $repoDir, $this->process, $this->io);
}
}
2 changes: 2 additions & 0 deletions Tests/AssetsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public function testGetVcsRepositoryDrivers()
'git',
'hg-bitbucket',
'hg',
'perforce',
'svn',
), array_keys(Assets::getVcsRepositoryDrivers()));
}
Expand All @@ -57,6 +58,7 @@ public function testGetVcsDrivers()
'git',
'hg-bitbucket',
'hg',
'perforce',
'svn',
), array_keys(Assets::getVcsDrivers()));
}
Expand Down
140 changes: 140 additions & 0 deletions Tests/Repository/Vcs/PerforceDriverTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?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\Test\Repository\Vcs\PerforceDriverTest as BasePerforceDriverTest;
use Fxp\Composer\AssetPlugin\Repository\Vcs\PerforceDriver;
use Fxp\Composer\AssetPlugin\Util\Perforce;

/**
* Tests of vcs perforce repository.
*
* @author François Pluchino <francois.pluchino@gmail.com>
*/
class PerforceDriverTest extends BasePerforceDriverTest
{
/**
* @var PerforceDriver
*/
protected $driver;

/**
* @var Perforce|\PHPUnit_Framework_MockObject_MockObject
*/
protected $perforce;

protected function setUp()
{
parent::setUp();

$this->driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->remoteFileSystem);
$this->overrideDriverInternalPerforce($this->perforce);

}

public function testInitializeCapturesVariablesFromRepoConfig()
{
$driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->remoteFileSystem);
$driver->initialize();
$this->assertEquals(self::TEST_URL, $driver->getUrl());
$this->assertEquals(self::TEST_DEPOT, $driver->getDepot());
$this->assertEquals(self::TEST_BRANCH, $driver->getBranch());
}

/**
* Test that supports() simply return false.
*
* @covers \Composer\Repository\Vcs\PerforceDriver::supports
*
* @return void
*/
public function testSupportsReturnsFalseNoDeepCheck()
{
$this->expectOutputString('');
$this->assertFalse(PerforceDriver::supports($this->io, $this->config, 'existing.url'));
}

public function testPublicRepositoryWithEmptyComposer()
{
$identifier = 'TEST_IDENTIFIER';
$this->perforce->expects($this->any())
->method('getComposerInformation')
->with($this->equalTo($identifier))
->will($this->returnValue(''));

$this->driver->initialize();
$validEmpty = array(
'_nonexistent_package' => true,
);

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

public function testPublicRepositoryWithCodeCache()
{
$identifier = 'TEST_IDENTIFIER';
$this->perforce->expects($this->any())
->method('getComposerInformation')
->with($this->equalTo($identifier))
->will($this->returnValue(array('name' => 'foo')));

$this->driver->initialize();
$composer1 = $this->driver->getComposerInformation($identifier);
$composer2 = $this->driver->getComposerInformation($identifier);

$this->assertNotNull($composer1);
$this->assertNotNull($composer2);
$this->assertSame($composer1, $composer2);
}

public function testPublicRepositoryWithFilesystemCache()
{
$identifier = 'TEST_IDENTIFIER';
$this->perforce->expects($this->any())
->method('getComposerInformation')
->with($this->equalTo($identifier))
->will($this->returnValue(array('name' => 'foo')));

$driver2 = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->remoteFileSystem);
$reflectionClass = new \ReflectionClass($driver2);
$property = $reflectionClass->getProperty('perforce');
$property->setAccessible(true);
$property->setValue($driver2, $this->perforce);

$this->driver->initialize();
$driver2->initialize();

$composer1 = $this->driver->getComposerInformation($identifier);
$composer2 = $driver2->getComposerInformation($identifier);

$this->assertNotNull($composer1);
$this->assertNotNull($composer2);
$this->assertSame($composer1, $composer2);
}

protected function getTestRepoConfig()
{
return array_merge(parent::getTestRepoConfig(), array(
'asset-type' => 'ASSET',
'filename' => 'ASSET.json',
));
}

protected function getMockPerforce()
{
$methods = array('p4login', 'checkStream', 'writeP4ClientSpec', 'connectClient', 'getComposerInformation', 'cleanupClientSpec');

return $this->getMockBuilder('Fxp\Composer\AssetPlugin\Util\Perforce', $methods)
->disableOriginalConstructor()
->getMock();
}
}

0 comments on commit 0ec5412

Please sign in to comment.