From e4c40c76af373ddd101742264f3c2d851649ebd0 Mon Sep 17 00:00:00 2001 From: Wanderson Date: Wed, 8 Oct 2014 22:45:31 -0300 Subject: [PATCH] Adding Phar archive plugin. Closes #659 Closes #106 --- PHPCI/Plugin/Phar.php | 240 ++++++++++++++++++++++++++++++++ Tests/PHPCI/Plugin/PharTest.php | 201 ++++++++++++++++++++++++++ Tests/temp/.gitignore | 2 + 3 files changed, 443 insertions(+) create mode 100644 PHPCI/Plugin/Phar.php create mode 100644 Tests/PHPCI/Plugin/PharTest.php create mode 100644 Tests/temp/.gitignore diff --git a/PHPCI/Plugin/Phar.php b/PHPCI/Plugin/Phar.php new file mode 100644 index 00000000..03415007 --- /dev/null +++ b/PHPCI/Plugin/Phar.php @@ -0,0 +1,240 @@ +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; + } +} diff --git a/Tests/PHPCI/Plugin/PharTest.php b/Tests/PHPCI/Plugin/PharTest.php new file mode 100644 index 00000000..69f63a6a --- /dev/null +++ b/Tests/PHPCI/Plugin/PharTest.php @@ -0,0 +1,201 @@ +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', '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; + + $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()); + } +} diff --git a/Tests/temp/.gitignore b/Tests/temp/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/Tests/temp/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore