Adding Phar archive plugin.

Closes #659
Closes #106
This commit is contained in:
Wanderson 2014-10-08 22:45:31 -03:00 committed by Dan Cryer
parent c211f92313
commit e4c40c76af
3 changed files with 443 additions and 0 deletions

240
PHPCI/Plugin/Phar.php Normal file
View file

@ -0,0 +1,240 @@
<?php
namespace PHPCI\Plugin;
use Exception;
use PHPCI\Builder;
use PHPCI\Model\Build;
use Phar as PHPPhar;
/**
* Phar Plugin
*/
class Phar implements \PHPCI\Plugin
{
/**
* PHPCI
* @var Builder
*/
protected $phpci;
/**
* Build
* @var Build
*/
protected $build;
/**
* Output Directory
* @var string
*/
protected $directory;
/**
* Phar Filename
* @var string
*/
protected $filename;
/**
* Regular Expression Filename Capture
* @var string
*/
protected $regexp;
/**
* Stub Filename
* @var string
*/
protected $stub;
/**
* Standard Constructor
*
* $options['directory'] Output Directory. Default: %BUILDPATH%
* $options['filename'] Phar Filename. Default: build.phar
* $options['regexp'] Regular Expression Filename Capture. Default: /\.php$/
* $options['stub'] Stub Content. No Default Value
*
* @param Builder $phpci
* @param Build $build
* @param array $options
*/
public function __construct(Builder $phpci, Build $build, array $options = array())
{
// Basic
$this->phpci = $phpci;
$this->build = $build;
// Directory?
if (isset($options['directory'])) {
$this->setDirectory($options['directory']);
}
// Filename?
if (isset($options['filename'])) {
$this->setFilename($options['filename']);
}
// RegExp?
if (isset($options['regexp'])) {
$this->setRegExp($options['regexp']);
}
// Stub?
if (isset($options['stub'])) {
$this->setStub($options['stub']);
}
}
/**
* Returns PHPCI
*
* @return PHPCI
*/
public function getPHPCI()
{
return $this->phpci;
}
/**
* Returns Build
*
* @return Build
*/
public function getBuild()
{
return $this->build;
}
/**
* Directory Setter
*
* @param string $directory Configuration Value
* @return Phar Fluent Interface
*/
public function setDirectory($directory)
{
$this->directory = $directory;
return $this;
}
/**
* Directory Getter
*
* @return string Configurated or Default Value
*/
public function getDirectory()
{
if (!isset($this->directory)) {
$this->setDirectory($this->getPHPCI()->buildPath);
}
return $this->directory;
}
/**
* Filename Setter
*
* @param string $filename Configuration Value
* @return Phar Fluent Interface
*/
public function setFilename($filename)
{
$this->filename = $filename;
return $this;
}
/**
* Filename Getter
*
* @return string Configurated or Default Value
*/
public function getFilename()
{
if (!isset($this->filename)) {
$this->setFilename('build.phar');
}
return $this->filename;
}
/**
* Regular Expression Setter
*
* @param string $regexp Configuration Value
* @return Phar Fluent Interface
*/
public function setRegExp($regexp)
{
$this->regexp = $regexp;
return $this;
}
/**
* Regular Expression Getter
*
* @return string Configurated or Default Value
*/
public function getRegExp()
{
if (!isset($this->regexp)) {
$this->setRegExp('/\.php$/');
}
return $this->regexp;
}
/**
* Stub Filename Setter
*
* @param string $stub Configuration Value
* @return Phar Fluent Interface
*/
public function setStub($stub)
{
$this->stub = $stub;
return $this;
}
/**
* Stub Filename Getter
*
* @return string Configurated Value
*/
public function getStub()
{
return $this->stub;
}
public function getStubContent()
{
$content = '';
$filename = $this->getStub();
if ($filename) {
$content = file_get_contents($this->getPHPCI()->buildPath . '/' . $this->getStub());
}
return $content;
}
// Execution
public function execute()
{
$success = false;
try {
$phar = new PHPPhar($this->getDirectory() . '/' . $this->getFilename(), 0, $this->getFilename());
$phar->buildFromDirectory($this->getPHPCI()->buildPath, $this->getRegExp());
$stub = $this->getStubContent();
if ($stub) {
$phar->setStub($stub);
}
$success = true;
} catch (Exception $e) {
$this->getPHPCI()->log('Phar Plugin Internal Error');
$this->getPHPCI()->log($e->getMessage());
}
return $success;
}
}

View file

@ -0,0 +1,201 @@
<?php
namespace PHPCI\Plugin\Tests;
use PHPCI\Plugin\Phar as PharPlugin;
use Phar as PHPPhar;
use RuntimeException;
class PharTest extends \PHPUnit_Framework_TestCase
{
protected $directory;
protected function tearDown()
{
$this->cleanSource();
}
protected function getPlugin(array $options = array())
{
$build = $this
->getMockBuilder('PHPCI\Model\Build')
->disableOriginalConstructor()
->getMock();
$phpci = $this
->getMockBuilder('PHPCI\Builder')
->disableOriginalConstructor()
->getMock();
return new PharPlugin($phpci, $build, $options);
}
protected function buildTemp()
{
$directory = tempnam(APPLICATION_PATH . '/Tests/temp', 'source');
unlink($directory);
return $directory;
}
protected function buildSource()
{
$directory = $this->buildTemp();
mkdir($directory);
file_put_contents($directory . '/one.php', '<?php echo "one";');
file_put_contents($directory . '/two.php', '<?php echo "two";');
mkdir($directory . '/config');
file_put_contents($directory . '/config/config.ini', '[config]');
mkdir($directory . '/views');
file_put_contents($directory . '/views/index.phtml', '<?php echo "hello";');
$this->directory = $directory;
return $directory;
}
protected function cleanSource()
{
if ($this->directory) {
$filenames = array(
'/build.phar',
'/stub.php',
'/views/index.phtml',
'/views',
'/config/config.ini',
'/config',
'/two.php',
'/one.php',
);
foreach ($filenames as $filename) {
if (is_dir($this->directory . $filename)) {
rmdir($this->directory . $filename);
} else if (is_file($this->directory . $filename)) {
unlink($this->directory . $filename);
}
}
rmdir($this->directory);
$this->directory = null;
}
}
protected function checkReadonly()
{
if (ini_get('phar.readonly')) {
$this->markTestSkipped();
throw new RuntimeException('Readonly Phar');
}
}
public function testPlugin()
{
$plugin = $this->getPlugin();
$this->assertInstanceOf('PHPCI\Plugin', $plugin);
$this->assertInstanceOf('PHPCI\Model\Build', $plugin->getBuild());
$this->assertInstanceOf('PHPCI\Builder', $plugin->getPHPCI());
}
public function testDirectory()
{
$plugin = $this->getPlugin();
$plugin->getPHPCI()->buildPath = 'foo';
$this->assertEquals('foo', $plugin->getDirectory());
$plugin = $this->getPlugin(array('directory' => 'dirname'));
$this->assertEquals('dirname', $plugin->getDirectory());
}
public function testFilename()
{
$plugin = $this->getPlugin();
$this->assertEquals('build.phar', $plugin->getFilename());
$plugin = $this->getPlugin(array('filename' => 'another.phar'));
$this->assertEquals('another.phar', $plugin->getFilename());
}
public function testRegExp()
{
$plugin = $this->getPlugin();
$this->assertEquals('/\.php$/', $plugin->getRegExp());
$plugin = $this->getPlugin(array('regexp' => '/\.(php|phtml)$/'));
$this->assertEquals('/\.(php|phtml)$/', $plugin->getRegExp());
}
public function testStub()
{
$plugin = $this->getPlugin();
$this->assertNull($plugin->getStub());
$plugin = $this->getPlugin(array('stub' => 'stub.php'));
$this->assertEquals('stub.php', $plugin->getStub());
}
public function testExecute()
{
$this->checkReadonly();
$plugin = $this->getPlugin();
$path = $this->buildSource();
$plugin->getPHPCI()->buildPath = $path;
$this->assertTrue($plugin->execute());
$this->assertFileExists($path . '/build.phar');
PHPPhar::loadPhar($path . '/build.phar');
$this->assertFileEquals($path . '/one.php', 'phar://build.phar/one.php');
$this->assertFileEquals($path . '/two.php', 'phar://build.phar/two.php');
$this->assertFileNotExists('phar://build.phar/config/config.ini');
$this->assertFileNotExists('phar://build.phar/views/index.phtml');
}
public function testExecuteRegExp()
{
$this->checkReadonly();
$plugin = $this->getPlugin(array('regexp' => '/\.(php|phtml)$/'));
$path = $this->buildSource();
$plugin->getPHPCI()->buildPath = $path;
$this->assertTrue($plugin->execute());
$this->assertFileExists($path . '/build.phar');
PHPPhar::loadPhar($path . '/build.phar');
$this->assertFileEquals($path . '/one.php', 'phar://build.phar/one.php');
$this->assertFileEquals($path . '/two.php', 'phar://build.phar/two.php');
$this->assertFileNotExists('phar://build.phar/config/config.ini');
$this->assertFileEquals($path . '/views/index.phtml', 'phar://build.phar/views/index.phtml');
}
public function testExecuteStub()
{
$this->checkReadonly();
$content = <<<STUB
<?php
Phar::mapPhar();
__HALT_COMPILER(); ?>
STUB;
$path = $this->buildSource();
file_put_contents($path . '/stub.php', $content);
$plugin = $this->getPlugin(array('stub' => 'stub.php'));
$plugin->getPHPCI()->buildPath = $path;
$this->assertTrue($plugin->execute());
$this->assertFileExists($path . '/build.phar');
$phar = new PHPPhar($path . '/build.phar');
$this->assertEquals($content, trim($phar->getStub())); // + trim because PHP adds newline char
}
public function testExecuteUnknownDirectory()
{
$this->checkReadonly();
$directory = $this->buildTemp();
$plugin = $this->getPlugin(array('directory' => $directory));
$plugin->getPHPCI()->buildPath = $this->buildSource();
$this->assertFalse($plugin->execute());
}
}

2
Tests/temp/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*
!.gitignore