From 02fefe99858a1b656324f21ad25ff0512244cb5c Mon Sep 17 00:00:00 2001 From: David Epely Date: Sat, 19 Oct 2013 16:49:52 +0200 Subject: [PATCH 01/39] fix error on missing files until installation is done --- bootstrap.php | 6 ++++-- public/install.php | 2 +- vars.php | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/bootstrap.php b/bootstrap.php index 17aaf608..67b9fbaf 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -47,7 +47,9 @@ $conf['b8']['app']['namespace'] = 'PHPCI'; $conf['b8']['app']['default_controller'] = 'Home'; $conf['b8']['view']['path'] = dirname(__FILE__) . '/PHPCI/View/'; -$config = new b8\Config($conf); -$config->loadYaml(dirname(__FILE__) . '/PHPCI/config.yml'); +if (file_exists(dirname(__FILE__) . '/PHPCI/config.yml')) { + $config = new b8\Config($conf); + $config->loadYaml(dirname(__FILE__) . '/PHPCI/config.yml'); +} require_once(dirname(__FILE__) . '/vars.php'); diff --git a/public/install.php b/public/install.php index e08e647e..d792bdae 100644 --- a/public/install.php +++ b/public/install.php @@ -5,7 +5,7 @@ require_once(dirname(__FILE__) . '/../vars.php'); $installStage = 'start'; $formAction = ''; $config = array(); -$ciUrl = ($_SERVER['HTTPS'] == "on" ? 'https' : 'http') . '://'; +$ciUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on" ? 'https' : 'http') . '://'; $ciUrl .= $_SERVER['HTTP_HOST']; $ciUrl .= str_replace('/install.php', '', $_SERVER['REQUEST_URI']); diff --git a/vars.php b/vars.php index 89a1d81e..5725805e 100644 --- a/vars.php +++ b/vars.php @@ -7,7 +7,7 @@ if (!defined('APPLICATION_PATH')) { } // Define our PHPCI_URL, if not already defined: -if (!defined('PHPCI_URL')) { +if (!defined('PHPCI_URL') && isset($config)) { define('PHPCI_URL', $config->get('phpci.url', '') . '/'); } From 03a81a3283d73ae55bf98c79e7b29075dc10643c Mon Sep 17 00:00:00 2001 From: meadsteve Date: Mon, 25 Nov 2013 21:19:48 +0000 Subject: [PATCH 02/39] fix whitespace. --- Tests/PHPCI/Plugin/EmailTest.php | 186 +++++++++++----------- Tests/PHPCI/Plugin/PHPUnitTest.php | 240 +++++++++++++++-------------- 2 files changed, 225 insertions(+), 201 deletions(-) diff --git a/Tests/PHPCI/Plugin/EmailTest.php b/Tests/PHPCI/Plugin/EmailTest.php index 1343068c..1899c99c 100644 --- a/Tests/PHPCI/Plugin/EmailTest.php +++ b/Tests/PHPCI/Plugin/EmailTest.php @@ -1,32 +1,33 @@ mockBuild = $this->getMock( - '\PHPCI\Model\Build', - array('getLog', 'getStatus'), - array(), - "mockBuild", - false - ); + '\PHPCI\Model\Build', + array('getLog', 'getStatus'), + array(), + "mockBuild", + false + ); $this->mockBuild->expects($this->any()) ->method('getLog') @@ -56,27 +57,33 @@ class EmailTest extends \PHPUnit_Framework_TestCase ->method('getStatus') ->will($this->returnValue(\PHPCI\Model\Build::STATUS_SUCCESS)); - $this->mockCiBuilder = $this->getMock( - '\PHPCI\Builder', - array('getSystemConfig', - 'getBuildProjectTitle', - 'getBuild', - 'log'), - array(), - "mockBuilder", - false - ); + $this->mockCiBuilder = $this->getMock( + '\PHPCI\Builder', + array( + 'getSystemConfig', + 'getBuildProjectTitle', + 'getBuild', + 'log' + ), + array(), + "mockBuilder", + false + ); $this->mockCiBuilder->buildPath = "/"; $this->mockCiBuilder->expects($this->any()) ->method('getSystemConfig') ->with('phpci') - ->will($this->returnValue(array( - 'email_settings' => array( - 'from_address' => "test-from-address@example.com" + ->will( + $this->returnValue( + array( + 'email_settings' => array( + 'from_address' => "test-from-address@example.com" + ) + ) ) - ))); + ); $this->mockCiBuilder->expects($this->any()) ->method('getBuildProjectTitle') ->will($this->returnValue('Test-Project')); @@ -85,53 +92,55 @@ class EmailTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue($this->mockBuild)); $this->mockMailer = $this->getMock( - '\Swift_Mailer', - array('send'), - array(), - "mockMailer", - false - ); + '\Swift_Mailer', + array('send'), + array(), + "mockMailer", + false + ); - $this->loadEmailPluginWithOptions(); - } + $this->loadEmailPluginWithOptions(); + } - protected function loadEmailPluginWithOptions($arrOptions = array()) - { - $this->testedEmailPlugin = new EmailPlugin( + protected function loadEmailPluginWithOptions($arrOptions = array()) + { + $this->testedEmailPlugin = new EmailPlugin( $this->mockCiBuilder, $this->mockBuild, $this->mockMailer, $arrOptions ); - } + } - /** - * @covers PHPUnit::execute - */ - public function testExecute_ReturnsFalseWithoutArgs() - { - $returnValue = $this->testedEmailPlugin->execute(); + /** + * @covers PHPUnit::execute + */ + public function testExecute_ReturnsFalseWithoutArgs() + { + $returnValue = $this->testedEmailPlugin->execute(); // As no addresses will have been mailed as non are configured. - $expectedReturn = false; + $expectedReturn = false; - $this->assertEquals($expectedReturn, $returnValue); - } + $this->assertEquals($expectedReturn, $returnValue); + } - /** - * @covers PHPUnit::execute - */ - public function testExecute_BuildsBasicEmails() - { - $this->loadEmailPluginWithOptions(array( - 'addresses' => array('test-receiver@example.com') - )); + /** + * @covers PHPUnit::execute + */ + public function testExecute_BuildsBasicEmails() + { + $this->loadEmailPluginWithOptions( + array( + 'addresses' => array('test-receiver@example.com') + ) + ); /** @var \Swift_Message $actualMail */ $actualMail = null; $this->catchMailPassedToSend($actualMail); - $returnValue = $this->testedEmailPlugin->execute(); - $expectedReturn = true; + $returnValue = $this->testedEmailPlugin->execute(); + $expectedReturn = true; $this->assertSystemMail( 'test-receiver@example.com', @@ -141,14 +150,14 @@ class EmailTest extends \PHPUnit_Framework_TestCase $actualMail ); - $this->assertEquals($expectedReturn, $returnValue); + $this->assertEquals($expectedReturn, $returnValue); - } + } /** - * @covers PHPUnit::sendEmail - */ + * @covers PHPUnit::sendEmail + */ public function testSendEmail_CallsMailerSend() { $this->mockMailer->expects($this->once()) @@ -157,8 +166,8 @@ class EmailTest extends \PHPUnit_Framework_TestCase } /** - * @covers PHPUnit::sendEmail - */ + * @covers PHPUnit::sendEmail + */ public function testSendEmail_BuildsAMessageObject() { $subject = "Test mail"; @@ -172,8 +181,8 @@ class EmailTest extends \PHPUnit_Framework_TestCase } /** - * @covers PHPUnit::sendEmail - */ + * @covers PHPUnit::sendEmail + */ public function testSendEmail_BuildsExpectedMessage() { $subject = "Test mail"; @@ -200,7 +209,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase } /** - * @param \Swift_Message $actualMail passed by ref and populated with + * @param \Swift_Message $actualMail passed by ref and populated with * the message object the mock mailer * receives. */ @@ -227,14 +236,17 @@ class EmailTest extends \PHPUnit_Framework_TestCase * @param string $expectedSubject * @param \Swift_Message $actualMail */ - protected function assertSystemMail($expectedToAddress, - $expectedFromAddress, - $expectedBody, - $expectedSubject, - $actualMail) - { - if (! ($actualMail instanceof \Swift_Message)) { - $type = is_object($actualMail) ? get_class($actualMail) : gettype($actualMail); + protected function assertSystemMail( + $expectedToAddress, + $expectedFromAddress, + $expectedBody, + $expectedSubject, + $actualMail + ) { + if (!($actualMail instanceof \Swift_Message)) { + $type = is_object($actualMail) ? get_class($actualMail) : gettype( + $actualMail + ); throw new \Exception("Expected Swift_Message got " . $type); } $this->assertEquals( diff --git a/Tests/PHPCI/Plugin/PHPUnitTest.php b/Tests/PHPCI/Plugin/PHPUnitTest.php index 5809ac67..dec0dd3f 100644 --- a/Tests/PHPCI/Plugin/PHPUnitTest.php +++ b/Tests/PHPCI/Plugin/PHPUnitTest.php @@ -1,71 +1,73 @@ mockCiBuilder = $this->getMock( - '\PHPCI\Builder', - array(), - array(), - "mockBuilder", - false - ); - $this->mockCiBuilder->buildPath = "/"; + /** + * @var \PHPUnit_Framework_MockObject_MockObject $mockCiBuilder + */ + protected $mockBuild; + + public function setUp() + { + $this->mockCiBuilder = $this->getMock( + '\PHPCI\Builder', + array('findBinary'), + array(), + "mockBuilder", + false + ); + $this->mockCiBuilder->buildPath = "/"; $this->mockBuild = $this->getMock( - '\PHPCI\Model\Build', - array(), - array(), - "MockBuild", - false - ); + '\PHPCI\Model\Build', + array(), + array(), + "MockBuild", + false + ); - $this->loadPhpUnitWithOptions(); - } + $this->loadPhpUnitWithOptions(); + } - protected function loadPhpUnitWithOptions($arrOptions = array()) - { - $this->testedPhpUnit = new PHPUnit($this->mockCiBuilder,$this->mockBuild, $arrOptions); - } + protected function loadPhpUnitWithOptions($arrOptions = array()) + { + $this->testedPhpUnit = new PHPUnit($this->mockCiBuilder, $this->mockBuild, $arrOptions); + } /** * @param \PHPUnit_Framework_MockObject_Matcher_Invocation $expectation */ - protected function expectFindBinaryToBeCalled($expectation) { + protected function expectFindBinaryToBeCalled($expectation) + { $this->mockCiBuilder->expects($expectation) - ->method("findBinary") - ->will($this->returnValue("phpunit")); + ->method("findBinary") + ->will($this->returnValue("phpunit")); } /** @@ -74,89 +76,99 @@ class PHPUnitTest extends \PHPUnit_Framework_TestCase public function expectExectuteCommandToBeCalled($expectation) { $this->mockCiBuilder->expects($expectation) - ->method("executeCommand"); + ->method("executeCommand"); } - /** - * @covers PHPUnit::execute - */ - public function testExecute_ReturnsTrueWithoutArgs() - { - $returnValue = $this->testedPhpUnit->execute(); - $expectedReturn = true; + /** + * @covers PHPUnit::execute + */ + public function testExecute_ReturnsTrueWithoutArgs() + { + $returnValue = $this->testedPhpUnit->execute(); + $expectedReturn = true; - $this->assertEquals($expectedReturn, $returnValue); - } + $this->assertEquals($expectedReturn, $returnValue); + } - /** - * @covers PHPUnit::execute - * @covers PHPUnit::runDir - */ - public function testExecute_CallsExecuteCommandOnceWhenGivenStringDirectory() - { - chdir('/'); + /** + * @covers PHPUnit::execute + * @covers PHPUnit::runDir + */ + public function testExecute_CallsExecuteCommandOnceWhenGivenStringDirectory( + ) + { + chdir('/'); - $this->loadPhpUnitWithOptions(array( - 'directory' => "Fake/Test/Path" - )); - - $this->expectFindBinaryToBeCalled($this->once()); - $this->expectExectuteCommandToBeCalled($this->once()); - - $returnValue = $this->testedPhpUnit->execute(); - } - - /** - * @covers PHPUnit::execute - * @covers PHPUnit::runConfigFile - */ - public function testExecute_CallsExecuteCommandOnceWhenGivenStringConfig() - { - chdir('/'); - - $this->loadPhpUnitWithOptions(array( - 'config' => "Fake/Test/config.xml" - )); + $this->loadPhpUnitWithOptions( + array( + 'directory' => "Fake/Test/Path" + ) + ); $this->expectFindBinaryToBeCalled($this->once()); $this->expectExectuteCommandToBeCalled($this->once()); $returnValue = $this->testedPhpUnit->execute(); - } + } - /** - * @covers PHPUnit::execute - * @covers PHPUnit::runDir - */ - public function testExecute_CallsExecuteCommandManyTimesWhenGivenArrayDirectory() - { - chdir('/'); + /** + * @covers PHPUnit::execute + * @covers PHPUnit::runConfigFile + */ + public function testExecute_CallsExecuteCommandOnceWhenGivenStringConfig() + { + chdir('/'); - $this->loadPhpUnitWithOptions(array( - 'directory' => array(0, 1) - )); + $this->loadPhpUnitWithOptions( + array( + 'config' => "Fake/Test/config.xml" + ) + ); - $this->mockCiBuilder->expects($this->at(0))->method("executeCommand"); - $this->mockCiBuilder->expects($this->at(1))->method("executeCommand"); + $this->expectFindBinaryToBeCalled($this->once()); + $this->expectExectuteCommandToBeCalled($this->once()); - $returnValue = $this->testedPhpUnit->execute(); - } + $returnValue = $this->testedPhpUnit->execute(); + } - /** - * @covers PHPUnit::execute - * @covers PHPUnit::runConfigFile - */ - public function testExecute_CallsExecuteCommandManyTimesWhenGivenArrayConfig() - { - chdir('/'); + /** + * @covers PHPUnit::execute + * @covers PHPUnit::runDir + */ + public function testExecute_CallsExecuteCommandManyTimesWhenGivenArrayDirectory( + ) + { + chdir('/'); - $this->loadPhpUnitWithOptions(array( - 'config' => array(0, 1) - )); + $this->loadPhpUnitWithOptions( + array( + 'directory' => array(0, 1) + ) + ); - $this->mockCiBuilder->expects($this->at(0))->method("executeCommand"); - $this->mockCiBuilder->expects($this->at(1))->method("executeCommand"); + $this->mockCiBuilder->expects($this->at(0))->method("executeCommand"); + $this->mockCiBuilder->expects($this->at(1))->method("executeCommand"); - $returnValue = $this->testedPhpUnit->execute(); - } + $returnValue = $this->testedPhpUnit->execute(); + } + + /** + * @covers PHPUnit::execute + * @covers PHPUnit::runConfigFile + */ + public function testExecute_CallsExecuteCommandManyTimesWhenGivenArrayConfig() + { + chdir('/'); + + $this->loadPhpUnitWithOptions( + array( + 'config' => array(0, 1) + ) + ); + + $this->mockCiBuilder->expects($this->at(0))->method("executeCommand"); + $this->mockCiBuilder->expects($this->at(1))->method("executeCommand"); + + $returnValue = $this->testedPhpUnit->execute(); + } } \ No newline at end of file From a2c25d2d8f30868b0a29264f1886268cc0dc0544 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Mon, 25 Nov 2013 21:30:10 +0000 Subject: [PATCH 03/39] fix builder mocking --- Tests/PHPCI/Plugin/EmailTest.php | 2 +- Tests/PHPCI/Plugin/PHPUnitTest.php | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Tests/PHPCI/Plugin/EmailTest.php b/Tests/PHPCI/Plugin/EmailTest.php index 1899c99c..84618001 100644 --- a/Tests/PHPCI/Plugin/EmailTest.php +++ b/Tests/PHPCI/Plugin/EmailTest.php @@ -66,7 +66,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase 'log' ), array(), - "mockBuilder", + "mockBuilder_email", false ); diff --git a/Tests/PHPCI/Plugin/PHPUnitTest.php b/Tests/PHPCI/Plugin/PHPUnitTest.php index dec0dd3f..e135cb81 100644 --- a/Tests/PHPCI/Plugin/PHPUnitTest.php +++ b/Tests/PHPCI/Plugin/PHPUnitTest.php @@ -37,9 +37,9 @@ class PHPUnitTest extends \PHPUnit_Framework_TestCase { $this->mockCiBuilder = $this->getMock( '\PHPCI\Builder', - array('findBinary'), + array('findBinary', 'executeCommand'), array(), - "mockBuilder", + "mockBuilder_phpUnit", false ); $this->mockCiBuilder->buildPath = "/"; @@ -94,8 +94,7 @@ class PHPUnitTest extends \PHPUnit_Framework_TestCase * @covers PHPUnit::execute * @covers PHPUnit::runDir */ - public function testExecute_CallsExecuteCommandOnceWhenGivenStringDirectory( - ) + public function testExecute_CallsExecuteCommandOnceWhenGivenStringDirectory() { chdir('/'); From 080784adc5e8cae1abe9fe77e2d65aa7f6f5af63 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Mon, 25 Nov 2013 21:48:21 +0000 Subject: [PATCH 04/39] fix test expectations to be exact in phpunit --- Tests/PHPCI/Plugin/PHPUnitTest.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Tests/PHPCI/Plugin/PHPUnitTest.php b/Tests/PHPCI/Plugin/PHPUnitTest.php index e135cb81..211d06e2 100644 --- a/Tests/PHPCI/Plugin/PHPUnitTest.php +++ b/Tests/PHPCI/Plugin/PHPUnitTest.php @@ -134,19 +134,18 @@ class PHPUnitTest extends \PHPUnit_Framework_TestCase * @covers PHPUnit::execute * @covers PHPUnit::runDir */ - public function testExecute_CallsExecuteCommandManyTimesWhenGivenArrayDirectory( - ) + public function testExecute_CallsExecuteCommandManyTimesWhenGivenArrayDirectory() { chdir('/'); $this->loadPhpUnitWithOptions( array( - 'directory' => array(0, 1) + 'directory' => array("dir1", "dir2") ) ); - $this->mockCiBuilder->expects($this->at(0))->method("executeCommand"); - $this->mockCiBuilder->expects($this->at(1))->method("executeCommand"); + $this->expectFindBinaryToBeCalled($this->exactly(2)); + $this->expectExectuteCommandToBeCalled($this->exactly(2)); $returnValue = $this->testedPhpUnit->execute(); } @@ -161,12 +160,12 @@ class PHPUnitTest extends \PHPUnit_Framework_TestCase $this->loadPhpUnitWithOptions( array( - 'config' => array(0, 1) + 'config' => array("configfile1.xml", "configfile2.xml") ) ); - $this->mockCiBuilder->expects($this->at(0))->method("executeCommand"); - $this->mockCiBuilder->expects($this->at(1))->method("executeCommand"); + $this->expectFindBinaryToBeCalled($this->exactly(2)); + $this->expectExectuteCommandToBeCalled($this->exactly(2)); $returnValue = $this->testedPhpUnit->execute(); } From 6d5bceea16c00b7f8a1ba419d0dd005edb3f0b5b Mon Sep 17 00:00:00 2001 From: meadsteve Date: Mon, 25 Nov 2013 21:49:14 +0000 Subject: [PATCH 05/39] fix copy-paste mistake in phpunit plugin runDir() --- PHPCI/Plugin/PhpUnit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PHPCI/Plugin/PhpUnit.php b/PHPCI/Plugin/PhpUnit.php index 9b905fb6..fde1b2fa 100755 --- a/PHPCI/Plugin/PhpUnit.php +++ b/PHPCI/Plugin/PhpUnit.php @@ -128,7 +128,7 @@ class PhpUnit implements \PHPCI\Plugin protected function runDir($dirPath) { if (is_array($dirPath)) { - return $this->recurseArg($dirPath, array($this, "runConfigFile")); + return $this->recurseArg($dirPath, array($this, "runDir")); } else { $curdir = getcwd(); chdir($this->phpci->buildPath); From 35bc3dad3114df649ad269b8ebbf5dcfbf368c6a Mon Sep 17 00:00:00 2001 From: Ondrej Huta Date: Wed, 27 Nov 2013 11:42:34 +0100 Subject: [PATCH 06/39] Fix the SettingsController 5.4 call --- PHPCI/Controller/SettingsController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PHPCI/Controller/SettingsController.php b/PHPCI/Controller/SettingsController.php index 9fce197d..d5b4a894 100644 --- a/PHPCI/Controller/SettingsController.php +++ b/PHPCI/Controller/SettingsController.php @@ -101,7 +101,7 @@ class SettingsController extends Controller $dumper = new Dumper(); $yaml = $dumper->dump($this->settings); file_put_contents(APPLICATION_PATH . 'PHPCI/config.yml', $yaml); - if(error_get_last()) return error_get_last()['message']; + if ($error_get_last = error_get_last()) { return $error_get_last['message']; } } protected function getGithubForm() From 77cfd1e5b2c713b92211981b022ac4f513f9c776 Mon Sep 17 00:00:00 2001 From: Ondrej Huta Date: Wed, 27 Nov 2013 11:54:17 +0100 Subject: [PATCH 07/39] Fix the SettingsController 5.4 call (refactor) --- PHPCI/Controller/SettingsController.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/PHPCI/Controller/SettingsController.php b/PHPCI/Controller/SettingsController.php index d5b4a894..6f8f544c 100644 --- a/PHPCI/Controller/SettingsController.php +++ b/PHPCI/Controller/SettingsController.php @@ -101,7 +101,10 @@ class SettingsController extends Controller $dumper = new Dumper(); $yaml = $dumper->dump($this->settings); file_put_contents(APPLICATION_PATH . 'PHPCI/config.yml', $yaml); - if ($error_get_last = error_get_last()) { return $error_get_last['message']; } + if (error_get_last()) { + $error_get_last = error_get_last(); + return $error_get_last['message']; + } } protected function getGithubForm() From 02dff2b081a6f4c0b22ce4dd468561b106a9cc6f Mon Sep 17 00:00:00 2001 From: Ondrej Huta Date: Wed, 27 Nov 2013 12:06:29 +0100 Subject: [PATCH 08/39] Proposed enhancement - fix for #221 GitlabBuild --- PHPCI/Model/Base/ProjectBase.php | 12 ++++++++++-- PHPCI/Model/Build/GitlabBuild.php | 8 ++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/PHPCI/Model/Base/ProjectBase.php b/PHPCI/Model/Base/ProjectBase.php index e3e12ecc..c16d3ee5 100644 --- a/PHPCI/Model/Base/ProjectBase.php +++ b/PHPCI/Model/Base/ProjectBase.php @@ -215,11 +215,19 @@ class ProjectBase extends Model /** * Get the value of AccessInformation / access_information. * + * @param string|null $key Key of desired information + * * @return string */ - public function getAccessInformation() + public function getAccessInformation($key = null) { - $rtn = $this->data['access_information']; + if (is_null($key)) { + $rtn = $this->data['access_information']; + } else if (isset($this->data['access_information'][$key])) { + $rtn = $this->data['access_information'][$key]; + } else { + $rtn = null; + } return $rtn; } diff --git a/PHPCI/Model/Build/GitlabBuild.php b/PHPCI/Model/Build/GitlabBuild.php index f3f75ebe..98be17c8 100644 --- a/PHPCI/Model/Build/GitlabBuild.php +++ b/PHPCI/Model/Build/GitlabBuild.php @@ -25,7 +25,7 @@ class GitlabBuild extends RemoteGitBuild */ public function getCommitLink() { - $domain = $this->getProject()->getAccessInformation()["domain"]; + $domain = $this->getProject()->getAccessInformation("domain"); return 'http://' . $domain . '/' . $this->getProject()->getReference() . '/commit/' . $this->getCommitId(); } @@ -34,7 +34,7 @@ class GitlabBuild extends RemoteGitBuild */ public function getBranchLink() { - $domain = $this->getProject()->getAccessInformation()["domain"]; + $domain = $this->getProject()->getAccessInformation("domain"); return 'http://' . $domain . '/' . $this->getProject()->getReference() . '/tree/' . $this->getBranch(); } @@ -46,8 +46,8 @@ class GitlabBuild extends RemoteGitBuild $key = trim($this->getProject()->getGitKey()); if (!empty($key)) { - $user = $this->getProject()->getAccessInformation()["user"]; - $domain = $this->getProject()->getAccessInformation()["domain"]; + $user = $this->getProject()->getAccessInformation("user"); + $domain = $this->getProject()->getAccessInformation("domain"); return $user . '@' . $domain . ':' . $this->getProject()->getReference() . '.git'; } } From 27e3b8b469fb3672e0d372da7f35837e60c7097f Mon Sep 17 00:00:00 2001 From: Pavel Pavlov Date: Wed, 27 Nov 2013 18:09:14 +0400 Subject: [PATCH 09/39] UI Improvement: Modal confirmation dialog --- PHPCI/Controller/BuildController.php | 6 + PHPCI/View/BuildsTable.phtml | 2 +- PHPCI/View/Home/index.phtml | 8 +- public/assets/js/phpci.js | 194 +++++++++++++++++++++++++++ 4 files changed, 206 insertions(+), 4 deletions(-) diff --git a/PHPCI/Controller/BuildController.php b/PHPCI/Controller/BuildController.php index 8c183774..f4a1d9c8 100644 --- a/PHPCI/Controller/BuildController.php +++ b/PHPCI/Controller/BuildController.php @@ -129,6 +129,12 @@ class BuildController extends \PHPCI\Controller } $build = $this->buildStore->getById($buildId); + + if (!$build) { + $this->response->setResponseCode(404); + return '404 - Not Found'; + } + $this->buildStore->delete($build); header('Location: '.PHPCI_URL.'project/view/' . $build->getProjectId()); diff --git a/PHPCI/View/BuildsTable.phtml b/PHPCI/View/BuildsTable.phtml index e38d8580..c2330d29 100644 --- a/PHPCI/View/BuildsTable.phtml +++ b/PHPCI/View/BuildsTable.phtml @@ -73,7 +73,7 @@ switch($build->getStatus()) diff --git a/PHPCI/View/Home/index.phtml b/PHPCI/View/Home/index.phtml index 68a0f26f..bfb90694 100644 --- a/PHPCI/View/Home/index.phtml +++ b/PHPCI/View/Home/index.phtml @@ -58,8 +58,10 @@ \ No newline at end of file diff --git a/public/assets/js/phpci.js b/public/assets/js/phpci.js index d662825b..8f338b53 100644 --- a/public/assets/js/phpci.js +++ b/public/assets/js/phpci.js @@ -1,3 +1,32 @@ +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind + * for the details of code below + */ +if (!Function.prototype.bind) { + Function.prototype.bind = function (oThis) { + if (typeof this !== "function") { + // closest thing possible to the ECMAScript 5 internal IsCallable function + throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); + } + + var aArgs = Array.prototype.slice.call(arguments, 1), + fToBind = this, + fNOP = function () { + }, + fBound = function () { + return fToBind.apply(this instanceof fNOP && oThis + ? this + : oThis, + aArgs.concat(Array.prototype.slice.call(arguments))); + }; + + fNOP.prototype = this.prototype; + fBound.prototype = new fNOP(); + + return fBound; + }; +} + /** * Used for delete buttons in the system, just to prevent accidental clicks. */ @@ -13,6 +42,171 @@ function confirmDelete(url) } } +/** + * Used for delete build buttons in the system, just to prevent accidental clicks. + */ +function confirmDeleteBuild(url) { + + var dialog = new PHPCIConfirmDialog({ + message: 'This build will be permanently deleted. Are you sure?', + confirmBtnCaption: 'Delete', + /* + confirm-btn click handler + */ + confirmed: function (e) { + var dialog = this; + e.preventDefault(); + + /* + Call delete URL + */ + $.ajax({ + url: url, + 'success': function () { + if (refreshBuildsTable) { + dialog.$dialog.on('hidden.bs.modal', function () { + refreshBuildsTable(); + }); + } + + dialog.showStatusMessage('Successfully deleted!', 1000); + }, + 'error': function (data) { + dialog.showStatusMessage('Deletion failed! Server says "' + data.statusText + '"'); + } + }); + } + }); + + dialog.show(); +} + +/** + * PHPCIConfirmDialog constructor options object + * @type {{message: string, title: string, confirmBtnCaption: string, cancelBtnCaption: string, confirmed: Function}} + */ +var PHPCIConfirmDialogOptions = { + message: 'The action will be performed and cannot be undone. Are you sure?', + title: 'Confirmation Dialog', + confirmBtnCaption: 'Ok', + cancelBtnCaption: 'Cancel', + confirmed: function (e) { + this.close(); + } +}; + +var PHPCIConfirmDialog = Class.extend({ + /** + * @param {PHPCIConfirmDialogOptions} options + */ + init: function (options) { + + options = options ? $.extend(PHPCIConfirmDialogOptions, options) : PHPCIConfirmDialogOptions; + + if (!$('#confirm-dialog').length) { + /* + Add the dialog html to a page on first use. No need to have it there before first use. + */ + $('body').append( + '' + ); + } + + /* + Define dialog controls + */ + this.$dialog = $('#confirm-dialog'); + this.$cancelBtn = this.$dialog.find('div.modal-footer button.btn-default'); + this.$confirmBtn = this.$dialog.find('div.modal-footer button.btn-primary'); + this.$title = this.$dialog.find('h4.modal-title'); + this.$body = this.$dialog.find('div.modal-body'); + + /* + Initialize its values + */ + this.$title.html(options.title ? options.title : PHPCIConfirmDialogOptions.title); + this.$body.html(options.message ? options.message : PHPCIConfirmDialogOptions.message); + this.$confirmBtn.html( + options.confirmBtnCaption ? options.confirmBtnCaption : PHPCIConfirmDialogOptions.confirmBtnCaption + ); + + this.$cancelBtn.html( + options.cancelBtnCaption ? options.cancelBtnCaption : PHPCIConfirmDialogOptions.cancelBtnCaption + ); + + /* + Events + */ + this.confirmBtnClick = options.confirmed; + + /* + Re-bind on click handler + */ + this.$confirmBtn.unbind('click'); + this.$confirmBtn.click(this.onConfirm.bind(this)); + + /* + Restore state if was changed previously + */ + this.$cancelBtn.show(); + this.$confirmBtn.show(); + }, + + /** + * Show dialog + */ + show: function () { + this.$dialog.modal('show'); + }, + + /** + * Hide dialog + */ + close: function () { + this.$dialog.modal('hide'); + }, + + onConfirm: function (e) { + $(this).attr('disabled', 'disabled'); + this.confirmBtnClick(e); + }, + + showStatusMessage: function (message, closeTimeout) { + this.$confirmBtn.hide(); + this.$cancelBtn.html('Close'); + + /* + Status message + */ + this.$body.html(message); + + if (closeTimeout) { + window.setTimeout(function () { + /* + Hide the dialog + */ + this.close(); + }.bind(this), closeTimeout); + } + } +}); + /** * Used to initialise the project form: */ From f7e396d04cb3b627a7252a785e004706e7e3caf6 Mon Sep 17 00:00:00 2001 From: Pavel Pavlov Date: Wed, 27 Nov 2013 18:14:40 +0400 Subject: [PATCH 10/39] Fixed merging bug --- PHPCI/View/Home/index.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PHPCI/View/Home/index.phtml b/PHPCI/View/Home/index.phtml index bfb90694..5e48573c 100644 --- a/PHPCI/View/Home/index.phtml +++ b/PHPCI/View/Home/index.phtml @@ -63,5 +63,5 @@ $('#latest-builds').load('home/latest'); }; -}, 10000); + setInterval(refreshBuildsTable, 10000); \ No newline at end of file From 6c0aed7f28edd905d12ac28926112930e0707580 Mon Sep 17 00:00:00 2001 From: Pavel Pavlov Date: Wed, 27 Nov 2013 21:04:24 +0400 Subject: [PATCH 11/39] UI Improvement: Modal confirmation dialog for deletion actions --- PHPCI/View/BuildsTable.phtml | 2 +- PHPCI/View/Project/view.phtml | 4 +++- PHPCI/View/User/index.phtml | 2 +- public/assets/js/phpci.js | 37 +++++++++++++---------------------- 4 files changed, 19 insertions(+), 26 deletions(-) diff --git a/PHPCI/View/BuildsTable.phtml b/PHPCI/View/BuildsTable.phtml index c2330d29..09cdd09b 100644 --- a/PHPCI/View/BuildsTable.phtml +++ b/PHPCI/View/BuildsTable.phtml @@ -73,7 +73,7 @@ switch($build->getStatus()) diff --git a/PHPCI/View/Project/view.phtml b/PHPCI/View/Project/view.phtml index 762e476a..2fd6cf6d 100644 --- a/PHPCI/View/Project/view.phtml +++ b/PHPCI/View/Project/view.phtml @@ -92,7 +92,9 @@ $(function() { $('#delete-project').on('click', function (e) { e.preventDefault(); - confirmDelete("project/delete/getId(); ?>"); + confirmDelete( + "project/delete/getId(); ?>", "Project" + ).onClose = function () {window.location = '/'}; }); }) diff --git a/PHPCI/View/User/index.phtml b/PHPCI/View/User/index.phtml index bcdcb7f1..86d6c61d 100644 --- a/PHPCI/View/User/index.phtml +++ b/PHPCI/View/User/index.phtml @@ -50,7 +50,7 @@ diff --git a/public/assets/js/phpci.js b/public/assets/js/phpci.js index 8f338b53..179597c3 100644 --- a/public/assets/js/phpci.js +++ b/public/assets/js/phpci.js @@ -30,25 +30,10 @@ if (!Function.prototype.bind) { /** * Used for delete buttons in the system, just to prevent accidental clicks. */ -function confirmDelete(url) -{ - if(confirm('Are you sure you want to delete this?')) - { - window.location.href = url; - } - else - { - return false; - } -} - -/** - * Used for delete build buttons in the system, just to prevent accidental clicks. - */ -function confirmDeleteBuild(url) { +function confirmDelete(url, subject, reloadAfter) { var dialog = new PHPCIConfirmDialog({ - message: 'This build will be permanently deleted. Are you sure?', + message: subject + ' will be permanently deleted. Are you sure?', confirmBtnCaption: 'Delete', /* confirm-btn click handler @@ -62,11 +47,11 @@ function confirmDeleteBuild(url) { */ $.ajax({ url: url, - 'success': function () { - if (refreshBuildsTable) { - dialog.$dialog.on('hidden.bs.modal', function () { - refreshBuildsTable(); - }); + 'success': function (data) { + if (reloadAfter) { + dialog.onClose = function () { + window.location.reload(); + }; } dialog.showStatusMessage('Successfully deleted!', 1000); @@ -79,6 +64,7 @@ function confirmDeleteBuild(url) { }); dialog.show(); + return dialog; } /** @@ -156,11 +142,14 @@ var PHPCIConfirmDialog = Class.extend({ this.confirmBtnClick = options.confirmed; /* - Re-bind on click handler + Re-bind handlers */ this.$confirmBtn.unbind('click'); this.$confirmBtn.click(this.onConfirm.bind(this)); + this.$confirmBtn.unbind('hidden.bs.modal'); + this.$dialog.on('hidden.bs.modal', function () {this.onClose()}.bind(this)); + /* Restore state if was changed previously */ @@ -187,6 +176,8 @@ var PHPCIConfirmDialog = Class.extend({ this.confirmBtnClick(e); }, + onClose: function () {}, + showStatusMessage: function (message, closeTimeout) { this.$confirmBtn.hide(); this.$cancelBtn.html('Close'); From 9891a4be62be2a7472ba0a366d7851a990071371 Mon Sep 17 00:00:00 2001 From: Steve B Date: Thu, 28 Nov 2013 14:05:26 +0000 Subject: [PATCH 12/39] force plugin factory to only build plugins matching interface. --- PHPCI/Plugin/Util/Factory.php | 9 +++++++ Tests/PHPCI/Plugin/Util/ExamplePlugins.php | 31 ++++++++++++++++++---- Tests/PHPCI/Plugin/Util/FactoryTest.php | 6 +++++ bootstrap.php | 28 ------------------- 4 files changed, 41 insertions(+), 33 deletions(-) diff --git a/PHPCI/Plugin/Util/Factory.php b/PHPCI/Plugin/Util/Factory.php index 4e6065e6..c0234374 100644 --- a/PHPCI/Plugin/Util/Factory.php +++ b/PHPCI/Plugin/Util/Factory.php @@ -9,6 +9,8 @@ class Factory { const TYPE_ARRAY = "array"; const TYPE_CALLABLE = "callable"; + const INTERFACE_PHPCI_PLUGIN = '\PHPCI\Plugin'; + private $currentPluginOptions; /** @@ -45,6 +47,7 @@ class Factory { * * @param $className * @param array $options + * @throws \InvalidArgumentException if $className doesn't represent a valid plugin * @return \PHPCI\Plugin */ public function buildPlugin($className, array $options = array()) @@ -53,6 +56,12 @@ class Factory { $reflectedPlugin = new \ReflectionClass($className); + if (!$reflectedPlugin->implementsInterface(self::INTERFACE_PHPCI_PLUGIN)) { + throw new \InvalidArgumentException( + "Requested class must implement " . self:: INTERFACE_PHPCI_PLUGIN + ); + } + $constructor = $reflectedPlugin->getConstructor(); if ($constructor) { diff --git a/Tests/PHPCI/Plugin/Util/ExamplePlugins.php b/Tests/PHPCI/Plugin/Util/ExamplePlugins.php index 9b5067a7..bc67bd3f 100644 --- a/Tests/PHPCI/Plugin/Util/ExamplePlugins.php +++ b/Tests/PHPCI/Plugin/Util/ExamplePlugins.php @@ -5,18 +5,28 @@ use PHPCI\Builder; use PHPCI\Model\Build; use PHPCI\Plugin; -class ExamplePluginWithNoConstructorArgs { - +class ExamplePluginWithNoConstructorArgs implements Plugin +{ + public function execute() + { + } } -class ExamplePluginWithSingleOptionalArg { +class ExamplePluginWithSingleOptionalArg implements Plugin +{ function __construct($optional = null) { } + + public function execute() + { + + } } -class ExamplePluginWithSingleRequiredArg { +class ExamplePluginWithSingleRequiredArg implements Plugin +{ public $RequiredArgument; @@ -24,9 +34,15 @@ class ExamplePluginWithSingleRequiredArg { { $this->RequiredArgument = $requiredArgument; } + + public function execute() + { + + } } -class ExamplePluginWithSingleTypedRequiredArg { +class ExamplePluginWithSingleTypedRequiredArg implements Plugin +{ public $RequiredArgument; @@ -34,6 +50,11 @@ class ExamplePluginWithSingleTypedRequiredArg { { $this->RequiredArgument = $requiredArgument; } + + public function execute() + { + + } } class ExamplePluginFull implements Plugin { diff --git a/Tests/PHPCI/Plugin/Util/FactoryTest.php b/Tests/PHPCI/Plugin/Util/FactoryTest.php index fb2794c8..be5c5f6f 100644 --- a/Tests/PHPCI/Plugin/Util/FactoryTest.php +++ b/Tests/PHPCI/Plugin/Util/FactoryTest.php @@ -49,6 +49,12 @@ class FactoryTest extends \PHPUnit_Framework_TestCase { $this->assertInstanceOf($expectedPluginClass, $plugin); } + public function testBuildPluginFailsForNonPluginClasses() + { + $this->setExpectedException('InvalidArgumentException', 'Requested class must implement \PHPCI\Plugin'); + $plugin = $this->testedFactory->buildPlugin("stdClass"); + } + public function testBuildPluginWorksWithSingleOptionalArgConstructor() { $namespace = '\\PHPCI\\Plugin\\Tests\\Util\\'; diff --git a/bootstrap.php b/bootstrap.php index 17aaf608..afb67c31 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -1,14 +1,5 @@ loadYaml(dirname(__FILE__) . '/PHPCI/config.yml'); - -require_once(dirname(__FILE__) . '/vars.php'); From aca6af3fece240a91fb1a92ec0116bd95bff8068 Mon Sep 17 00:00:00 2001 From: Steve B Date: Thu, 28 Nov 2013 14:12:50 +0000 Subject: [PATCH 13/39] add test for non-function loader in plugin factory. --- Tests/PHPCI/Plugin/Util/FactoryTest.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Tests/PHPCI/Plugin/Util/FactoryTest.php b/Tests/PHPCI/Plugin/Util/FactoryTest.php index be5c5f6f..3265e07c 100644 --- a/Tests/PHPCI/Plugin/Util/FactoryTest.php +++ b/Tests/PHPCI/Plugin/Util/FactoryTest.php @@ -37,10 +37,16 @@ class FactoryTest extends \PHPUnit_Framework_TestCase { public function testRegisterResourceThrowsExceptionWithoutTypeAndName() { - $this->setExpectedException("InvalidArgumentException"); + $this->setExpectedException('InvalidArgumentException', 'Type or Name must be specified'); $this->testedFactory->registerResource($this->resourceLoader, null, null); } + public function testRegisterResourceThrowsExceptionIfLoaderIsntFunction() + { + $this->setExpectedException('InvalidArgumentException', '$loader is expected to be a function'); + $this->testedFactory->registerResource(array("dummy"), "TestName", "TestClass"); + } + public function testBuildPluginWorksWithConstructorlessPlugins() { $namespace = '\\PHPCI\\Plugin\\Tests\\Util\\'; From 99adec03d53cb2d1ff2fde66aa6f76b873eff251 Mon Sep 17 00:00:00 2001 From: Steve B Date: Thu, 28 Nov 2013 14:23:11 +0000 Subject: [PATCH 14/39] allow non phpci native plugins. --- PHPCI/Builder.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index c58bd928..1f526b35 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -418,10 +418,17 @@ class Builder implements LoggerAwareInterface */ protected function executePlugin($plugin, $options) { - // Figure out the class name and check the plugin exists: - $class = str_replace('_', ' ', $plugin); - $class = ucwords($class); - $class = 'PHPCI\\Plugin\\' . str_replace(' ', '', $class); + // Any plugin name without a namespace separator is a PHPCI built in plugin + // if not we assume it's a fully name-spaced class name that implements the plugin interface. + // If not the factory will throw an exception. + if (strpos($plugin, "/") === false) { + $class = str_replace('_', ' ', $plugin); + $class = ucwords($class); + $class = 'PHPCI\\Plugin\\' . str_replace(' ', '', $class); + } + else { + $class = $plugin; + } if (!class_exists($class)) { $this->logFailure('Plugin does not exist: ' . $plugin, $ex); From 4f1d81e6fde4f3f8d9876ad176ba8acd6c058268 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Thu, 28 Nov 2013 21:04:27 +0000 Subject: [PATCH 15/39] update loggerConfig constructor to take array by default to make unit testing simpler. --- PHPCI/Helper/LoggerConfig.php | 29 +++++++++++++++++++++-------- console | 2 +- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/PHPCI/Helper/LoggerConfig.php b/PHPCI/Helper/LoggerConfig.php index 014805f2..1e130e1a 100644 --- a/PHPCI/Helper/LoggerConfig.php +++ b/PHPCI/Helper/LoggerConfig.php @@ -13,18 +13,31 @@ class LoggerConfig { private $config; /** - * The file specified is expected to return an array. Where each key - * is the name of a logger. The value of each key should be an array or - * a function that returns an array of LogHandlers. - * @param $logConfigFilePath + * The filepath is expected to return an array which will be + * passed to the normal constructor. + * + * @param string $filePath + * @return LoggerConfig */ - function __construct($logConfigFilePath) { - if (file_exists($logConfigFilePath)) { - $this->config = require_once($logConfigFilePath); + public static function newFromFile($filePath) + { + if (file_exists($filePath)) { + $configArray = require($filePath); } else { - $this->config = array(); + $configArray = array(); } + return new self($configArray); + } + + /** + * Each key of the array is the name of a logger. The value of + * each key should be an array or a function that returns an + * array of LogHandlers. + * @param array $configArray + */ + function __construct(array $configArray = array()) { + $this->config = $configArray; } /** diff --git a/console b/console index 3358dce7..baa0e13a 100644 --- a/console +++ b/console @@ -20,7 +20,7 @@ use PHPCI\Command\DaemonCommand; use PHPCI\Command\PollCommand; use Symfony\Component\Console\Application; -$loggerConfig = new \PHPCI\Helper\LoggerConfig(__DIR__ . "/loggerconfig.php"); +$loggerConfig = \PHPCI\Helper\LoggerConfig::newFromFile(__DIR__ . "/loggerconfig.php"); $application = new Application(); From f1052443ab18ab6a0772a85decd7398e1d234cb0 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Thu, 28 Nov 2013 21:17:01 +0000 Subject: [PATCH 16/39] add basic type checking for LoggerConfig::GetFor --- Tests/PHPCI/Helper/LoggerConfigTest.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 Tests/PHPCI/Helper/LoggerConfigTest.php diff --git a/Tests/PHPCI/Helper/LoggerConfigTest.php b/Tests/PHPCI/Helper/LoggerConfigTest.php new file mode 100644 index 00000000..a18f504a --- /dev/null +++ b/Tests/PHPCI/Helper/LoggerConfigTest.php @@ -0,0 +1,19 @@ +getFor("something"); + $this->assertInstanceOf('\Psr\Log\LoggerInterface', $logger); + } + + public function testGetFor_ReturnsMonologInstance() + { + $config = new \PHPCI\Helper\LoggerConfig(array()); + $logger = $config->getFor("something"); + $this->assertInstanceOf('\Monolog\Logger', $logger); + } +} + \ No newline at end of file From c8dc8a67b7e70a283f6196d9b53deb0fb85ff465 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Thu, 28 Nov 2013 21:18:11 +0000 Subject: [PATCH 17/39] Fix casing in LoggerConfig. --- PHPCI/Helper/LoggerConfig.php | 2 +- console | 8 ++++---- phpci.yml | 20 ++++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/PHPCI/Helper/LoggerConfig.php b/PHPCI/Helper/LoggerConfig.php index 1e130e1a..de1b2a67 100644 --- a/PHPCI/Helper/LoggerConfig.php +++ b/PHPCI/Helper/LoggerConfig.php @@ -46,7 +46,7 @@ class LoggerConfig { * @param $name * @return Logger */ - public function GetFor($name) { + public function getFor($name) { $handlers = $this->getHandlers(self::KEY_AlwaysLoaded); $handlers = array_merge($handlers, $this->getHandlers($name)); return new Logger($name, $handlers); diff --git a/console b/console index baa0e13a..f855f5ab 100644 --- a/console +++ b/console @@ -24,11 +24,11 @@ $loggerConfig = \PHPCI\Helper\LoggerConfig::newFromFile(__DIR__ . "/loggerconfig $application = new Application(); -$application->add(new RunCommand($loggerConfig->GetFor('RunCommand'))); +$application->add(new RunCommand($loggerConfig->getFor('RunCommand'))); $application->add(new InstallCommand); -$application->add(new UpdateCommand($loggerConfig->GetFor('UpdateCommand'))); +$application->add(new UpdateCommand($loggerConfig->getFor('UpdateCommand'))); $application->add(new GenerateCommand); -$application->add(new DaemonCommand($loggerConfig->GetFor('DaemonCommand'))); -$application->add(new PollCommand($loggerConfig->GetFor('PollCommand'))); +$application->add(new DaemonCommand($loggerConfig->getFor('DaemonCommand'))); +$application->add(new PollCommand($loggerConfig->getFor('PollCommand'))); $application->run(); diff --git a/phpci.yml b/phpci.yml index 42b2dba3..52b13952 100644 --- a/phpci.yml +++ b/phpci.yml @@ -2,7 +2,6 @@ build_settings: verbose: false ignore: - "vendor" - - "Tests" - "PHPCI/Command" # PHPMD complains about un-used parameters, but they are required. - "public/install.php" # PHPCS really doesn't like PHP mixed with HTML (and so it shouldn't) irc: @@ -13,14 +12,15 @@ build_settings: test: php_mess_detector: - php_code_sniffer: - standard: "PSR2" - php_loc: +phpunit: + directory: + "Tests/" -success: - irc: - message: "Build Success. %PROJECT_TITLE% - %COMMIT% - %BUILD_URI%" -failure: - irc: - message: "Build Failed. %PROJECT_TITLE% - %COMMIT% - %BUILD_URI%" \ No newline at end of file +#success: +# irc: +# message: "Build Success. %PROJECT_TITLE% - %COMMIT% - %BUILD_URI%" + +#failure: +# irc: +# message: "Build Failed. %PROJECT_TITLE% - %COMMIT% - %BUILD_URI%" \ No newline at end of file From ee9871e4a8e8b10bf4abee1878f514eb2db5cec8 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Thu, 28 Nov 2013 21:36:56 +0000 Subject: [PATCH 18/39] add tests to LoggerConfig for handler attaching. --- Tests/PHPCI/Helper/LoggerConfigTest.php | 60 ++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/Tests/PHPCI/Helper/LoggerConfigTest.php b/Tests/PHPCI/Helper/LoggerConfigTest.php index a18f504a..95ea3d62 100644 --- a/Tests/PHPCI/Helper/LoggerConfigTest.php +++ b/Tests/PHPCI/Helper/LoggerConfigTest.php @@ -1,19 +1,75 @@ getFor("something"); $this->assertInstanceOf('\Psr\Log\LoggerInterface', $logger); } public function testGetFor_ReturnsMonologInstance() { - $config = new \PHPCI\Helper\LoggerConfig(array()); + $config = new LoggerConfig(array()); $logger = $config->getFor("something"); $this->assertInstanceOf('\Monolog\Logger', $logger); } + + public function testGetFor_AttachesAlwaysPresentHandlers() + { + $expectedHandler = new Monolog\Handler\NullHandler(); + $config = new LoggerConfig(array( + LoggerConfig::KEY_AlwaysLoaded => function() use ($expectedHandler) { + return array($expectedHandler); + } + )); + + /** @var \Monolog\Logger $logger */ + $logger = $config->getFor("something"); + $actualHandler = $logger->popHandler(); + + $this->assertEquals($expectedHandler, $actualHandler); + } + + public function testGetFor_AttachesSpecificHandlers() + { + $expectedHandler = new Monolog\Handler\NullHandler(); + $config = new LoggerConfig(array( + "Specific" => function() use ($expectedHandler) { + return array($expectedHandler); + } + )); + + /** @var \Monolog\Logger $logger */ + $logger = $config->getFor("Specific"); + $actualHandler = $logger->popHandler(); + + $this->assertSame($expectedHandler, $actualHandler); + } + + public function testGetFor_IgnoresAlternativeHandlers() + { + $expectedHandler = new Monolog\Handler\NullHandler(); + $alternativeHandler = new Monolog\Handler\NullHandler(); + + $config = new LoggerConfig(array( + "Specific" => function() use ($expectedHandler) { + return array($expectedHandler); + }, + "Other" => function() use ($alternativeHandler) { + return array($alternativeHandler); + } + )); + + /** @var \Monolog\Logger $logger */ + $logger = $config->getFor("Specific"); + $actualHandler = $logger->popHandler(); + + $this->assertSame($expectedHandler, $actualHandler); + $this->assertNotSame($alternativeHandler, $actualHandler); + } } \ No newline at end of file From 4b16077428e8e67f3af720feac5406694076a4dd Mon Sep 17 00:00:00 2001 From: meadsteve Date: Fri, 29 Nov 2013 10:12:22 +0000 Subject: [PATCH 19/39] revert accidental change to phpci.yml --- phpci.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/phpci.yml b/phpci.yml index 52b13952..42b2dba3 100644 --- a/phpci.yml +++ b/phpci.yml @@ -2,6 +2,7 @@ build_settings: verbose: false ignore: - "vendor" + - "Tests" - "PHPCI/Command" # PHPMD complains about un-used parameters, but they are required. - "public/install.php" # PHPCS really doesn't like PHP mixed with HTML (and so it shouldn't) irc: @@ -12,15 +13,14 @@ build_settings: test: php_mess_detector: -phpunit: - directory: - "Tests/" + php_code_sniffer: + standard: "PSR2" + php_loc: +success: + irc: + message: "Build Success. %PROJECT_TITLE% - %COMMIT% - %BUILD_URI%" -#success: -# irc: -# message: "Build Success. %PROJECT_TITLE% - %COMMIT% - %BUILD_URI%" - -#failure: -# irc: -# message: "Build Failed. %PROJECT_TITLE% - %COMMIT% - %BUILD_URI%" \ No newline at end of file +failure: + irc: + message: "Build Failed. %PROJECT_TITLE% - %COMMIT% - %BUILD_URI%" \ No newline at end of file From a942525f84f1717b60ffe8c44e431bc75b40effa Mon Sep 17 00:00:00 2001 From: "steve.brazier" Date: Fri, 6 Dec 2013 09:59:07 +0000 Subject: [PATCH 20/39] switch to correct namespace separator in plugin construction. --- PHPCI/Builder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index 1f526b35..701ee463 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -421,7 +421,7 @@ class Builder implements LoggerAwareInterface // Any plugin name without a namespace separator is a PHPCI built in plugin // if not we assume it's a fully name-spaced class name that implements the plugin interface. // If not the factory will throw an exception. - if (strpos($plugin, "/") === false) { + if (strpos($plugin, '\\') === false) { $class = str_replace('_', ' ', $plugin); $class = ucwords($class); $class = 'PHPCI\\Plugin\\' . str_replace(' ', '', $class); From 9207c39105bb4b52da2464f896bd64124bfc988a Mon Sep 17 00:00:00 2001 From: "steve.brazier" Date: Fri, 6 Dec 2013 09:59:32 +0000 Subject: [PATCH 21/39] remove non existent variable. --- PHPCI/Builder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index 701ee463..0f6877c5 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -431,7 +431,7 @@ class Builder implements LoggerAwareInterface } if (!class_exists($class)) { - $this->logFailure('Plugin does not exist: ' . $plugin, $ex); + $this->logFailure('Plugin does not exist: ' . $plugin); return false; } From 912776801df4687ad05e006c26dba10c1a54c79e Mon Sep 17 00:00:00 2001 From: meadsteve Date: Fri, 6 Dec 2013 11:26:56 +0000 Subject: [PATCH 22/39] move plugin execution code in to helper class. --- PHPCI/Builder.php | 104 +++++---------------------------- PHPCI/Plugin/Util/Executor.php | 104 +++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 91 deletions(-) create mode 100644 PHPCI/Plugin/Util/Executor.php diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index 0f6877c5..7b88d629 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -92,9 +92,9 @@ class Builder implements LoggerAwareInterface public $quiet = false; /** - * @var \PHPCI\Plugin\Util\Factory + * @var \PHPCI\Plugin\Util\Executor */ - protected $pluginFactory; + protected $pluginExecutor; /** * Set up the builder. @@ -108,7 +108,7 @@ class Builder implements LoggerAwareInterface } $this->build = $build; $this->store = Store\Factory::getStore('Build'); - $this->setupPluginFactory($build); + $this->pluginExecutor = new Plugin\Util\Executor($this->buildPluginFactory($build), $this); } /** @@ -170,19 +170,19 @@ class Builder implements LoggerAwareInterface // Run the core plugin stages: foreach (array('setup', 'test', 'complete') as $stage) { - $this->executePlugins($stage); + $this->pluginExecutor->executePlugins($this->config, $stage); } // Failed build? Execute failure plugins and then mark the build as failed. if (!$this->success) { - $this->executePlugins('failure'); + $this->pluginExecutor->executePlugins($this->config, 'failure'); throw new \Exception('BUILD FAILED!'); } // If we got this far, the build was successful! if ($this->success) { $this->build->setStatus(2); - $this->executePlugins('success'); + $this->pluginExecutor->executePlugins($this->config, 'success'); $this->logSuccess('BUILD SUCCESSFUL!'); } @@ -372,86 +372,6 @@ class Builder implements LoggerAwareInterface return true; } - /** - * Execute a the appropriate set of plugins for a given build stage. - */ - protected function executePlugins($stage) - { - // Ignore any stages for which we don't have plugins set: - if (!array_key_exists( - $stage, - $this->config - ) || !is_array($this->config[$stage]) - ) { - return; - } - - foreach ($this->config[$stage] as $plugin => $options) { - $this->log('RUNNING PLUGIN: ' . $plugin); - - // Is this plugin allowed to fail? - if ($stage == 'test' && !isset($options['allow_failures'])) { - $options['allow_failures'] = false; - } - - // Try and execute it: - if ($this->executePlugin($plugin, $options)) { - - // Execution was successful: - $this->logSuccess('PLUGIN STATUS: SUCCESS!'); - - } else { - - // If we're in the "test" stage and the plugin is not allowed to fail, - // then mark the build as failed: - if ($stage == 'test' && !$options['allow_failures']) { - $this->success = false; - } - - $this->logFailure('PLUGIN STATUS: FAILED'); - } - } - } - - /** - * Executes a given plugin, with options and returns the result. - */ - protected function executePlugin($plugin, $options) - { - // Any plugin name without a namespace separator is a PHPCI built in plugin - // if not we assume it's a fully name-spaced class name that implements the plugin interface. - // If not the factory will throw an exception. - if (strpos($plugin, '\\') === false) { - $class = str_replace('_', ' ', $plugin); - $class = ucwords($class); - $class = 'PHPCI\\Plugin\\' . str_replace(' ', '', $class); - } - else { - $class = $plugin; - } - - if (!class_exists($class)) { - $this->logFailure('Plugin does not exist: ' . $plugin); - return false; - } - - $rtn = true; - - // Try running it: - try { - $obj = $this->pluginFactory->buildPlugin($class, $options); - - if (!$obj->execute()) { - $rtn = false; - } - } catch (\Exception $ex) { - $this->logFailure('EXCEPTION: ' . $ex->getMessage(), $ex); - $rtn = false; - } - - return $rtn; - } - /** * Find a binary required by a plugin. * @param $binary @@ -506,12 +426,12 @@ class Builder implements LoggerAwareInterface return $this->logger; } - private function setupPluginFactory(Build $build) + private function buildPluginFactory(Build $build) { - $this->pluginFactory = new Plugin\Util\Factory(); + $pluginFactory = new Plugin\Util\Factory(); $self = $this; - $this->pluginFactory->registerResource( + $pluginFactory->registerResource( function () use($self) { return $self; }, @@ -519,7 +439,7 @@ class Builder implements LoggerAwareInterface 'PHPCI\Builder' ); - $this->pluginFactory->registerResource( + $pluginFactory->registerResource( function () use($build) { return $build; }, @@ -527,7 +447,7 @@ class Builder implements LoggerAwareInterface 'PHPCI\Model\Build' ); - $this->pluginFactory->registerResource( + $pluginFactory->registerResource( function () use ($self) { $factory = new MailerFactory($self->getSystemConfig('phpci')); return $factory->getSwiftMailerFromConfig(); @@ -535,5 +455,7 @@ class Builder implements LoggerAwareInterface null, 'Swift_Mailer' ); + + return $pluginFactory; } } diff --git a/PHPCI/Plugin/Util/Executor.php b/PHPCI/Plugin/Util/Executor.php new file mode 100644 index 00000000..99521f57 --- /dev/null +++ b/PHPCI/Plugin/Util/Executor.php @@ -0,0 +1,104 @@ +pluginFactory = $pluginFactory; + $this->builder = $builder; + } + + /** + * Execute a the appropriate set of plugins for a given build stage. + * @param array $config PHPCI configuration + * @param string $stage + */ + public function executePlugins(&$config, $stage) + { + // Ignore any stages for which we don't have plugins set: + if (!array_key_exists($stage, $config) || !is_array($config[$stage])) { + return; + } + + foreach ($config[$stage] as $plugin => $options) { + $this->builder->log('RUNNING PLUGIN: ' . $plugin); + + // Is this plugin allowed to fail? + if ($stage == 'test' && !isset($options['allow_failures'])) { + $options['allow_failures'] = false; + } + + // Try and execute it: + if ($this->executePlugin($plugin, $options)) { + + // Execution was successful: + $this->builder->logSuccess('PLUGIN STATUS: SUCCESS!'); + + } else { + + // If we're in the "test" stage and the plugin is not allowed to fail, + // then mark the build as failed: + if ($stage == 'test' && !$options['allow_failures']) { + $this->success = false; + } + + $this->builder->logFailure('PLUGIN STATUS: FAILED'); + } + } + } + + /** + * Executes a given plugin, with options and returns the result. + */ + public function executePlugin($plugin, $options) + { + // Any plugin name without a namespace separator is a PHPCI built in plugin + // if not we assume it's a fully name-spaced class name that implements the plugin interface. + // If not the factory will throw an exception. + if (strpos($plugin, '\\') === false) { + $class = str_replace('_', ' ', $plugin); + $class = ucwords($class); + $class = 'PHPCI\\Plugin\\' . str_replace(' ', '', $class); + } + else { + $class = $plugin; + } + + if (!class_exists($class)) { + $this->builder->logFailure('Plugin does not exist: ' . $plugin); + return false; + } + + $rtn = true; + + // Try running it: + try { + $obj = $this->pluginFactory->buildPlugin($class, $options); + + if (!$obj->execute()) { + $rtn = false; + } + } catch (\Exception $ex) { + $this->builder->logFailure('EXCEPTION: ' . $ex->getMessage(), $ex); + $rtn = false; + } + + return $rtn; + } + +} \ No newline at end of file From 6aed18158b9babbfd292a3e4decbf56fee199164 Mon Sep 17 00:00:00 2001 From: "steve.brazier" Date: Fri, 6 Dec 2013 11:31:39 +0000 Subject: [PATCH 23/39] extract the success/failure logging of the builder to an interface. --- PHPCI/BuildLogger.php | 31 +++++++++++++++++++++++++++++++ PHPCI/Builder.php | 2 +- PHPCI/Plugin/Util/Executor.php | 20 ++++++++++---------- 3 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 PHPCI/BuildLogger.php diff --git a/PHPCI/BuildLogger.php b/PHPCI/BuildLogger.php new file mode 100644 index 00000000..ccb6288a --- /dev/null +++ b/PHPCI/BuildLogger.php @@ -0,0 +1,31 @@ + */ -class Builder implements LoggerAwareInterface +class Builder implements LoggerAwareInterface, BuildLogger { /** * @var string diff --git a/PHPCI/Plugin/Util/Executor.php b/PHPCI/Plugin/Util/Executor.php index 99521f57..7ea194eb 100644 --- a/PHPCI/Plugin/Util/Executor.php +++ b/PHPCI/Plugin/Util/Executor.php @@ -2,25 +2,25 @@ namespace PHPCI\Plugin\Util; -use PHPCI\Builder; +use PHPCI\BuildLogger; class Executor { /** - * @var Builder + * @var BuildLogger */ - protected $builder; + protected $logger; /** * @var Factory */ protected $pluginFactory; - function __construct(Factory $pluginFactory, Builder $builder) + function __construct(Factory $pluginFactory, BuildLogger $logger) { $this->pluginFactory = $pluginFactory; - $this->builder = $builder; + $this->logger = $logger; } /** @@ -36,7 +36,7 @@ class Executor } foreach ($config[$stage] as $plugin => $options) { - $this->builder->log('RUNNING PLUGIN: ' . $plugin); + $this->logger->log('RUNNING PLUGIN: ' . $plugin); // Is this plugin allowed to fail? if ($stage == 'test' && !isset($options['allow_failures'])) { @@ -47,7 +47,7 @@ class Executor if ($this->executePlugin($plugin, $options)) { // Execution was successful: - $this->builder->logSuccess('PLUGIN STATUS: SUCCESS!'); + $this->logger->logSuccess('PLUGIN STATUS: SUCCESS!'); } else { @@ -57,7 +57,7 @@ class Executor $this->success = false; } - $this->builder->logFailure('PLUGIN STATUS: FAILED'); + $this->logger->logFailure('PLUGIN STATUS: FAILED'); } } } @@ -80,7 +80,7 @@ class Executor } if (!class_exists($class)) { - $this->builder->logFailure('Plugin does not exist: ' . $plugin); + $this->logger->logFailure('Plugin does not exist: ' . $plugin); return false; } @@ -94,7 +94,7 @@ class Executor $rtn = false; } } catch (\Exception $ex) { - $this->builder->logFailure('EXCEPTION: ' . $ex->getMessage(), $ex); + $this->logger->logFailure('EXCEPTION: ' . $ex->getMessage(), $ex); $rtn = false; } From 0b130a42db4e286bcb7fe167206d916472972b19 Mon Sep 17 00:00:00 2001 From: "steve.brazier" Date: Fri, 6 Dec 2013 12:51:12 +0000 Subject: [PATCH 24/39] add prophecy and phpunit integration to make mocking a bit simpler. --- composer.json | 3 +- composer.lock | 141 +++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 125 insertions(+), 19 deletions(-) diff --git a/composer.json b/composer.json index 59d9c930..a52e8fb6 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,8 @@ "symfony/console" : "2.*", "psr/log": "1.0.0", "monolog/monolog": "1.6.0", - "pimple/pimple": "1.1.*" + "pimple/pimple": "1.1.*", + "phpspec/prophecy-phpunit": "1.*" }, "suggest": { diff --git a/composer.lock b/composer.lock index 278e483a..0a80a55b 100644 --- a/composer.lock +++ b/composer.lock @@ -3,7 +3,7 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "2f0615871ce4ee1eb8e4642bf0c731da", + "hash": "d0c90323aa9c3dcabd7d2075483de4a3", "packages": [ { "name": "block8/b8framework", @@ -153,6 +153,111 @@ ], "time": "2013-07-28 22:38:30" }, + { + "name": "phpspec/prophecy", + "version": "v1.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "79d9c8bd94801bffbf9b56964f6438762da6d8cd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/79d9c8bd94801bffbf9b56964f6438762da6d8cd", + "reference": "79d9c8bd94801bffbf9b56964f6438762da6d8cd", + "shasum": "" + }, + "require-dev": { + "phpspec/phpspec": "2.0.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "http://phpspec.org", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2013-08-10 11:11:45" + }, + { + "name": "phpspec/prophecy-phpunit", + "version": "v1.0.0", + "target-dir": "Prophecy/PhpUnit", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy-phpunit.git", + "reference": "ebc983be95b026fcea18afb7870e7b9041dc9d11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/ebc983be95b026fcea18afb7870e7b9041dc9d11", + "reference": "ebc983be95b026fcea18afb7870e7b9041dc9d11", + "shasum": "" + }, + "require": { + "phpspec/prophecy": "~1.0" + }, + "suggest": { + "phpunit/phpunit": "if it is not installed globally" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\PhpUnit\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christophe Coevoet", + "email": "stof@notk.org" + } + ], + "description": "PhpUnit test case integrating the Prophecy mocking library", + "homepage": "http://phpspec.org", + "keywords": [ + "phpunit", + "prophecy" + ], + "time": "2013-07-04 21:27:53" + }, { "name": "pimple/pimple", "version": "v1.1.0", @@ -239,16 +344,16 @@ }, { "name": "swiftmailer/swiftmailer", - "version": "v5.0.2", + "version": "v5.0.3", "source": { "type": "git", "url": "https://github.com/swiftmailer/swiftmailer.git", - "reference": "f3917ecef35a4e4d98b303eb9fee463bc983f379" + "reference": "32edc3b0de0fdc1b10f5c4912e8677b3f411a230" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/f3917ecef35a4e4d98b303eb9fee463bc983f379", - "reference": "f3917ecef35a4e4d98b303eb9fee463bc983f379", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/32edc3b0de0fdc1b10f5c4912e8677b3f411a230", + "reference": "32edc3b0de0fdc1b10f5c4912e8677b3f411a230", "shasum": "" }, "require": { @@ -284,21 +389,21 @@ "mail", "mailer" ], - "time": "2013-08-30 12:35:21" + "time": "2013-12-03 13:33:24" }, { "name": "symfony/console", - "version": "v2.3.7", + "version": "v2.4.0", "target-dir": "Symfony/Component/Console", "source": { "type": "git", "url": "https://github.com/symfony/Console.git", - "reference": "00848d3e13cf512e77c7498c2b3b0192f61f4b18" + "reference": "3c1496ae96d24ccc6c340fcc25f71d7a1ab4c12c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/00848d3e13cf512e77c7498c2b3b0192f61f4b18", - "reference": "00848d3e13cf512e77c7498c2b3b0192f61f4b18", + "url": "https://api.github.com/repos/symfony/Console/zipball/3c1496ae96d24ccc6c340fcc25f71d7a1ab4c12c", + "reference": "3c1496ae96d24ccc6c340fcc25f71d7a1ab4c12c", "shasum": "" }, "require": { @@ -313,7 +418,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-master": "2.4-dev" } }, "autoload": { @@ -337,21 +442,21 @@ ], "description": "Symfony Console Component", "homepage": "http://symfony.com", - "time": "2013-11-13 21:27:40" + "time": "2013-11-27 09:10:40" }, { "name": "symfony/yaml", - "version": "v2.3.7", + "version": "v2.4.0", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "c1bda5b459d792cb253de12c65beba3040163b2b" + "reference": "1ae235a1b9d3ad3d9f3860ff20acc072df95b7f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/c1bda5b459d792cb253de12c65beba3040163b2b", - "reference": "c1bda5b459d792cb253de12c65beba3040163b2b", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/1ae235a1b9d3ad3d9f3860ff20acc072df95b7f5", + "reference": "1ae235a1b9d3ad3d9f3860ff20acc072df95b7f5", "shasum": "" }, "require": { @@ -360,7 +465,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-master": "2.4-dev" } }, "autoload": { @@ -384,7 +489,7 @@ ], "description": "Symfony Yaml Component", "homepage": "http://symfony.com", - "time": "2013-10-17 11:48:01" + "time": "2013-11-26 16:40:27" } ], "packages-dev": [ From bad0737df19c90ab846202e2b7400aa404f89135 Mon Sep 17 00:00:00 2001 From: "steve.brazier" Date: Fri, 6 Dec 2013 12:52:47 +0000 Subject: [PATCH 25/39] add tests for Plugin Executor --- Tests/PHPCI/Plugin/Util/ExecutorTest.php | 90 ++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 Tests/PHPCI/Plugin/Util/ExecutorTest.php diff --git a/Tests/PHPCI/Plugin/Util/ExecutorTest.php b/Tests/PHPCI/Plugin/Util/ExecutorTest.php new file mode 100644 index 00000000..bf717265 --- /dev/null +++ b/Tests/PHPCI/Plugin/Util/ExecutorTest.php @@ -0,0 +1,90 @@ +mockBuildLogger = $this->prophesize('\PHPCI\BuildLogger'); + $this->mockFactory = $this->prophesize('\PHPCI\Plugin\Util\Factory'); + $this->testedExecutor = new Executor($this->mockFactory->reveal(), $this->mockBuildLogger->reveal()); + } + + public function testExecutePlugin_AssumesPHPCINamespaceIfNoneGiven() + { + $options = array(); + $pluginName = 'PhpUnit'; + $pluginNamespace = 'PHPCI\\Plugin\\'; + + $this->mockFactory->buildPlugin($pluginNamespace . $pluginName, $options) + ->shouldBeCalledTimes(1) + ->willReturn($this->prophesize('PHPCI\Plugin')->reveal()); + + $this->testedExecutor->executePlugin($pluginName, $options); + } + + public function testExecutePlugin_KeepsCalledNameSpace() + { + $options = array(); + $pluginName = 'ExamplePluginFull'; + $pluginNamespace = '\\PHPCI\\Plugin\\Tests\\Util\\'; + + $this->mockFactory->buildPlugin($pluginNamespace . $pluginName, $options) + ->shouldBeCalledTimes(1) + ->willReturn($this->prophesize('PHPCI\Plugin')->reveal()); + + $this->testedExecutor->executePlugin($pluginNamespace . $pluginName, $options); + } + + public function testExecutePlugin_CallsExecuteOnFactoryBuildPlugin() + { + $options = array(); + $pluginName = 'PhpUnit'; + $pluginNamespace = 'PHPCI\\Plugin\\'; + + $mockPlugin = $this->prophesize('PHPCI\Plugin'); + $mockPlugin->execute()->shouldBeCalledTimes(1); + + $this->mockFactory->buildPlugin($pluginNamespace . $pluginName, $options) + ->shouldBeCalledTimes(1) + ->willReturn($mockPlugin->reveal()); + + $this->testedExecutor->executePlugin($pluginName, $options); + } + + public function testExecutePlugin_ReturnsPluginSuccess() + { + $options = array(); + $pluginName = 'PhpUnit'; + $pluginNamespace = 'PHPCI\\Plugin\\'; + + $expectedReturnValue = true; + + $mockPlugin = $this->prophesize('PHPCI\Plugin'); + $mockPlugin->execute()->willReturn($expectedReturnValue); + + $this->mockFactory->buildPlugin($pluginNamespace . $pluginName, $options)->willReturn($mockPlugin->reveal()); + + $returnValue = $this->testedExecutor->executePlugin($pluginName, $options); + + $this->assertEquals($expectedReturnValue, $returnValue); + } + +} + \ No newline at end of file From 23d6238aa2989858537136b4cf8282bb46f20a57 Mon Sep 17 00:00:00 2001 From: "steve.brazier" Date: Fri, 6 Dec 2013 13:04:27 +0000 Subject: [PATCH 26/39] add tests for plugin executor logging --- Tests/PHPCI/Plugin/Util/ExecutorTest.php | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Tests/PHPCI/Plugin/Util/ExecutorTest.php b/Tests/PHPCI/Plugin/Util/ExecutorTest.php index bf717265..b551ebf4 100644 --- a/Tests/PHPCI/Plugin/Util/ExecutorTest.php +++ b/Tests/PHPCI/Plugin/Util/ExecutorTest.php @@ -86,5 +86,35 @@ class ExecutorTest extends ProphecyTestCase $this->assertEquals($expectedReturnValue, $returnValue); } + public function testExecutePlugin_LogsFailureForNonExistentClasses() + { + $options = array(); + $pluginName = 'DOESNTEXIST'; + $pluginNamespace = 'PHPCI\\Plugin\\'; + + $this->mockBuildLogger->logFailure('Plugin does not exist: ' . $pluginName)->shouldBeCalledTimes(1); + + $this->testedExecutor->executePlugin($pluginName, $options); + } + + public function testExecutePlugin_LogsFailureWhenExceptionsAreThrownByPlugin() + { + $options = array(); + $pluginName = 'PhpUnit'; + $pluginNamespace = 'PHPCI\\Plugin\\'; + + $expectedException = new \RuntimeException("Generic Error"); + + $mockPlugin = $this->prophesize('PHPCI\Plugin'); + $mockPlugin->execute()->willThrow($expectedException); + + $this->mockFactory->buildPlugin($pluginNamespace . $pluginName, $options)->willReturn($mockPlugin->reveal()); + + $this->mockBuildLogger->logFailure('EXCEPTION: ' . $expectedException->getMessage(), $expectedException) + ->shouldBeCalledTimes(1); + + $this->testedExecutor->executePlugin($pluginName, $options); + } + } \ No newline at end of file From 1ca8b9628ce5b90146bf3258e4ac17fcec1415b7 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Fri, 6 Dec 2013 13:07:48 +0000 Subject: [PATCH 27/39] remove arguments from Executor test assertions that are not required. --- Tests/PHPCI/Plugin/Util/ExecutorTest.php | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/Tests/PHPCI/Plugin/Util/ExecutorTest.php b/Tests/PHPCI/Plugin/Util/ExecutorTest.php index b551ebf4..694cdfa5 100644 --- a/Tests/PHPCI/Plugin/Util/ExecutorTest.php +++ b/Tests/PHPCI/Plugin/Util/ExecutorTest.php @@ -5,6 +5,7 @@ namespace PHPCI\Plugin\Tests\Util; require_once __DIR__ . "/ExamplePlugins.php"; use PHPCI\Plugin\Util\Executor; +use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTestCase; class ExecutorTest extends ProphecyTestCase @@ -56,14 +57,11 @@ class ExecutorTest extends ProphecyTestCase { $options = array(); $pluginName = 'PhpUnit'; - $pluginNamespace = 'PHPCI\\Plugin\\'; $mockPlugin = $this->prophesize('PHPCI\Plugin'); $mockPlugin->execute()->shouldBeCalledTimes(1); - $this->mockFactory->buildPlugin($pluginNamespace . $pluginName, $options) - ->shouldBeCalledTimes(1) - ->willReturn($mockPlugin->reveal()); + $this->mockFactory->buildPlugin(Argument::any(), Argument::any())->willReturn($mockPlugin->reveal()); $this->testedExecutor->executePlugin($pluginName, $options); } @@ -72,14 +70,13 @@ class ExecutorTest extends ProphecyTestCase { $options = array(); $pluginName = 'PhpUnit'; - $pluginNamespace = 'PHPCI\\Plugin\\'; $expectedReturnValue = true; $mockPlugin = $this->prophesize('PHPCI\Plugin'); $mockPlugin->execute()->willReturn($expectedReturnValue); - $this->mockFactory->buildPlugin($pluginNamespace . $pluginName, $options)->willReturn($mockPlugin->reveal()); + $this->mockFactory->buildPlugin(Argument::any(), Argument::any())->willReturn($mockPlugin->reveal()); $returnValue = $this->testedExecutor->executePlugin($pluginName, $options); @@ -90,7 +87,6 @@ class ExecutorTest extends ProphecyTestCase { $options = array(); $pluginName = 'DOESNTEXIST'; - $pluginNamespace = 'PHPCI\\Plugin\\'; $this->mockBuildLogger->logFailure('Plugin does not exist: ' . $pluginName)->shouldBeCalledTimes(1); @@ -101,14 +97,13 @@ class ExecutorTest extends ProphecyTestCase { $options = array(); $pluginName = 'PhpUnit'; - $pluginNamespace = 'PHPCI\\Plugin\\'; $expectedException = new \RuntimeException("Generic Error"); $mockPlugin = $this->prophesize('PHPCI\Plugin'); $mockPlugin->execute()->willThrow($expectedException); - $this->mockFactory->buildPlugin($pluginNamespace . $pluginName, $options)->willReturn($mockPlugin->reveal()); + $this->mockFactory->buildPlugin(Argument::any(), Argument::any())->willReturn($mockPlugin->reveal()); $this->mockBuildLogger->logFailure('EXCEPTION: ' . $expectedException->getMessage(), $expectedException) ->shouldBeCalledTimes(1); From e1654ee4b6feb98a42aa9529b058a921ed4e538e Mon Sep 17 00:00:00 2001 From: "steve.brazier" Date: Fri, 6 Dec 2013 13:14:19 +0000 Subject: [PATCH 28/39] add test for Executor::executePlugins --- Tests/PHPCI/Plugin/Util/ExecutorTest.php | 31 ++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/Tests/PHPCI/Plugin/Util/ExecutorTest.php b/Tests/PHPCI/Plugin/Util/ExecutorTest.php index 694cdfa5..ec640e95 100644 --- a/Tests/PHPCI/Plugin/Util/ExecutorTest.php +++ b/Tests/PHPCI/Plugin/Util/ExecutorTest.php @@ -111,5 +111,36 @@ class ExecutorTest extends ProphecyTestCase $this->testedExecutor->executePlugin($pluginName, $options); } + public function testExecutePlugins_CallsEachPluginForStage() + { + $phpUnitPluginOptions = array(); + $behatPluginOptions = array(); + + $config = array( + 'stageOne' => array( + 'PhpUnit' => $phpUnitPluginOptions, + 'Behat' => $behatPluginOptions, + ) + ); + + $pluginNamespace = 'PHPCI\\Plugin\\'; + + $mockPhpUnitPlugin = $this->prophesize('PHPCI\Plugin'); + $mockPhpUnitPlugin->execute()->shouldBeCalledTimes(1)->willReturn(true); + + $this->mockFactory->buildPlugin($pluginNamespace . 'PhpUnit', $phpUnitPluginOptions) + ->willReturn($mockPhpUnitPlugin->reveal()); + + + $mockBehatPlugin = $this->prophesize('PHPCI\Plugin'); + $mockBehatPlugin->execute()->shouldBeCalledTimes(1)->willReturn(true); + + $this->mockFactory->buildPlugin($pluginNamespace . 'Behat', $behatPluginOptions) + ->willReturn($mockBehatPlugin->reveal()); + + + $this->testedExecutor->executePlugins($config, 'stageOne'); + } + } \ No newline at end of file From 2fb8985ff74ff1674bdb9a31d801a7f4063c314d Mon Sep 17 00:00:00 2001 From: "steve.brazier" Date: Fri, 6 Dec 2013 15:10:58 +0000 Subject: [PATCH 29/39] move prophecy-phpunit to a dev dependency as it's not required other than to execute tests. --- composer.json | 5 +- composer.lock | 213 +++++++++++++++++++++++++------------------------- 2 files changed, 110 insertions(+), 108 deletions(-) diff --git a/composer.json b/composer.json index a52e8fb6..acafd3a5 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,10 @@ "symfony/console" : "2.*", "psr/log": "1.0.0", "monolog/monolog": "1.6.0", - "pimple/pimple": "1.1.*", + "pimple/pimple": "1.1.*" + }, + + "require-dev": { "phpspec/prophecy-phpunit": "1.*" }, diff --git a/composer.lock b/composer.lock index 0a80a55b..ce6ac387 100644 --- a/composer.lock +++ b/composer.lock @@ -3,7 +3,7 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "d0c90323aa9c3dcabd7d2075483de4a3", + "hash": "07f37de4c8bacd8a1a7b6e14269178d1", "packages": [ { "name": "block8/b8framework", @@ -153,111 +153,6 @@ ], "time": "2013-07-28 22:38:30" }, - { - "name": "phpspec/prophecy", - "version": "v1.0.4", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "79d9c8bd94801bffbf9b56964f6438762da6d8cd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/79d9c8bd94801bffbf9b56964f6438762da6d8cd", - "reference": "79d9c8bd94801bffbf9b56964f6438762da6d8cd", - "shasum": "" - }, - "require-dev": { - "phpspec/phpspec": "2.0.*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Prophecy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "http://phpspec.org", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "time": "2013-08-10 11:11:45" - }, - { - "name": "phpspec/prophecy-phpunit", - "version": "v1.0.0", - "target-dir": "Prophecy/PhpUnit", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy-phpunit.git", - "reference": "ebc983be95b026fcea18afb7870e7b9041dc9d11" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/ebc983be95b026fcea18afb7870e7b9041dc9d11", - "reference": "ebc983be95b026fcea18afb7870e7b9041dc9d11", - "shasum": "" - }, - "require": { - "phpspec/prophecy": "~1.0" - }, - "suggest": { - "phpunit/phpunit": "if it is not installed globally" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Prophecy\\PhpUnit\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christophe Coevoet", - "email": "stof@notk.org" - } - ], - "description": "PhpUnit test case integrating the Prophecy mocking library", - "homepage": "http://phpspec.org", - "keywords": [ - "phpunit", - "prophecy" - ], - "time": "2013-07-04 21:27:53" - }, { "name": "pimple/pimple", "version": "v1.1.0", @@ -493,7 +388,111 @@ } ], "packages-dev": [ - + { + "name": "phpspec/prophecy", + "version": "v1.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "79d9c8bd94801bffbf9b56964f6438762da6d8cd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/79d9c8bd94801bffbf9b56964f6438762da6d8cd", + "reference": "79d9c8bd94801bffbf9b56964f6438762da6d8cd", + "shasum": "" + }, + "require-dev": { + "phpspec/phpspec": "2.0.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "http://phpspec.org", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2013-08-10 11:11:45" + }, + { + "name": "phpspec/prophecy-phpunit", + "version": "v1.0.0", + "target-dir": "Prophecy/PhpUnit", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy-phpunit.git", + "reference": "ebc983be95b026fcea18afb7870e7b9041dc9d11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/ebc983be95b026fcea18afb7870e7b9041dc9d11", + "reference": "ebc983be95b026fcea18afb7870e7b9041dc9d11", + "shasum": "" + }, + "require": { + "phpspec/prophecy": "~1.0" + }, + "suggest": { + "phpunit/phpunit": "if it is not installed globally" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\PhpUnit\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christophe Coevoet", + "email": "stof@notk.org" + } + ], + "description": "PhpUnit test case integrating the Prophecy mocking library", + "homepage": "http://phpspec.org", + "keywords": [ + "phpunit", + "prophecy" + ], + "time": "2013-07-04 21:27:53" + } ], "aliases": [ From 52a908009da5f474912d71e88a896fd10bdee6ef Mon Sep 17 00:00:00 2001 From: "steve.brazier" Date: Fri, 6 Dec 2013 15:17:17 +0000 Subject: [PATCH 30/39] fix PhpUnit test caseing. --- Tests/PHPCI/Plugin/PHPUnitTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/PHPCI/Plugin/PHPUnitTest.php b/Tests/PHPCI/Plugin/PHPUnitTest.php index 211d06e2..89b24694 100644 --- a/Tests/PHPCI/Plugin/PHPUnitTest.php +++ b/Tests/PHPCI/Plugin/PHPUnitTest.php @@ -9,7 +9,7 @@ namespace PHPCI\Plugin\Tests; -use PHPCI\Plugin\PHPUnit; +use PHPCI\Plugin\PhpUnit; /** * Unit test for the PHPUnit plugin. @@ -19,7 +19,7 @@ class PHPUnitTest extends \PHPUnit_Framework_TestCase { /** - * @var PHPUnit $testedPhpUnit + * @var PhpUnit $testedPhpUnit */ protected $testedPhpUnit; @@ -57,7 +57,7 @@ class PHPUnitTest extends \PHPUnit_Framework_TestCase protected function loadPhpUnitWithOptions($arrOptions = array()) { - $this->testedPhpUnit = new PHPUnit($this->mockCiBuilder, $this->mockBuild, $arrOptions); + $this->testedPhpUnit = new PhpUnit($this->mockCiBuilder, $this->mockBuild, $arrOptions); } /** From 35ac98056cae895a24c22af2fb04c5e7ec4e93c0 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Sat, 7 Dec 2013 09:34:28 +0000 Subject: [PATCH 31/39] bring bootstrap.php up to date. --- bootstrap.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/bootstrap.php b/bootstrap.php index afb67c31..17aaf608 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -1,5 +1,14 @@ loadYaml(dirname(__FILE__) . '/PHPCI/config.yml'); + +require_once(dirname(__FILE__) . '/vars.php'); From fecfec9fe512e237c78ed3f44229227a8b08c6d9 Mon Sep 17 00:00:00 2001 From: Steve B Date: Sat, 7 Dec 2013 13:49:13 +0000 Subject: [PATCH 32/39] update bootstrap --- bootstrap.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/bootstrap.php b/bootstrap.php index afb67c31..17aaf608 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -1,5 +1,14 @@ loadYaml(dirname(__FILE__) . '/PHPCI/config.yml'); + +require_once(dirname(__FILE__) . '/vars.php'); From ce88f5095806746d45a40b5b7d144fbc7c12eba9 Mon Sep 17 00:00:00 2001 From: Steve B Date: Sat, 7 Dec 2013 13:53:05 +0000 Subject: [PATCH 33/39] fix the plugin executor so that the status is correctly reported. --- PHPCI/Builder.php | 3 ++- PHPCI/Plugin/Util/Executor.php | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index 2df00bd9..440c0d53 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -163,6 +163,7 @@ class Builder implements LoggerAwareInterface, BuildLogger $this->build->setStarted(new \DateTime()); $this->store->save($this->build); $this->build->sendStatusPostback(); + $this->success = true; try { // Set up the build: @@ -170,7 +171,7 @@ class Builder implements LoggerAwareInterface, BuildLogger // Run the core plugin stages: foreach (array('setup', 'test', 'complete') as $stage) { - $this->pluginExecutor->executePlugins($this->config, $stage); + $this->success &= $this->pluginExecutor->executePlugins($this->config, $stage); } // Failed build? Execute failure plugins and then mark the build as failed. diff --git a/PHPCI/Plugin/Util/Executor.php b/PHPCI/Plugin/Util/Executor.php index 7ea194eb..5bec1820 100644 --- a/PHPCI/Plugin/Util/Executor.php +++ b/PHPCI/Plugin/Util/Executor.php @@ -27,12 +27,14 @@ class Executor * Execute a the appropriate set of plugins for a given build stage. * @param array $config PHPCI configuration * @param string $stage + * @return bool */ public function executePlugins(&$config, $stage) { + $success = true; // Ignore any stages for which we don't have plugins set: if (!array_key_exists($stage, $config) || !is_array($config[$stage])) { - return; + return $success; } foreach ($config[$stage] as $plugin => $options) { @@ -54,12 +56,14 @@ class Executor // If we're in the "test" stage and the plugin is not allowed to fail, // then mark the build as failed: if ($stage == 'test' && !$options['allow_failures']) { - $this->success = false; + $success = false; } $this->logger->logFailure('PLUGIN STATUS: FAILED'); } } + + return $success; } /** From 03aeb7e3b1dddeb68a2e8ac1216fba7ca133899f Mon Sep 17 00:00:00 2001 From: Steve B Date: Sat, 7 Dec 2013 14:29:25 +0000 Subject: [PATCH 34/39] remove unreachable if --- PHPCI/Builder.php | 6 +++--- PHPCI/Command/PollCommand.php | 2 +- PHPCI/Controller/BitbucketController.php | 2 +- PHPCI/Controller/BuildController.php | 2 +- PHPCI/Controller/GitController.php | 2 +- PHPCI/Controller/GithubController.php | 2 +- PHPCI/Controller/GitlabController.php | 2 +- PHPCI/Controller/ProjectController.php | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index 440c0d53..63cf2bad 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -159,7 +159,7 @@ class Builder implements LoggerAwareInterface, BuildLogger public function execute() { // Update the build in the database, ping any external services. - $this->build->setStatus(1); + $this->build->setStatus(Build::STATUS_RUNNING); $this->build->setStarted(new \DateTime()); $this->store->save($this->build); $this->build->sendStatusPostback(); @@ -182,14 +182,14 @@ class Builder implements LoggerAwareInterface, BuildLogger // If we got this far, the build was successful! if ($this->success) { - $this->build->setStatus(2); + $this->build->setStatus(Build::STATUS_SUCCESS); $this->pluginExecutor->executePlugins($this->config, 'success'); $this->logSuccess('BUILD SUCCESSFUL!'); } } catch (\Exception $ex) { $this->logFailure($ex->getMessage(), $ex); - $this->build->setStatus(3); + $this->build->setStatus(Build::STATUS_FAILED); } // Clean up: diff --git a/PHPCI/Command/PollCommand.php b/PHPCI/Command/PollCommand.php index af91acec..3918e27d 100644 --- a/PHPCI/Command/PollCommand.php +++ b/PHPCI/Command/PollCommand.php @@ -84,7 +84,7 @@ class PollCommand extends Command $build = new Build(); $build->setProjectId($project->getId()); $build->setCommitId($last_commit); - $build->setStatus(0); + $build->setStatus(Build::STATUS_NEW); $build->setBranch($project->getType() === 'hg' ? 'default' : 'master'); $build->setCreated(new \DateTime()); diff --git a/PHPCI/Controller/BitbucketController.php b/PHPCI/Controller/BitbucketController.php index 9ec4bb39..783421a3 100644 --- a/PHPCI/Controller/BitbucketController.php +++ b/PHPCI/Controller/BitbucketController.php @@ -53,7 +53,7 @@ class BitbucketController extends \PHPCI\Controller $build = new Build(); $build->setProjectId($project); $build->setCommitId($commits[$branch]); - $build->setStatus(0); + $build->setStatus(Build::STATUS_NEW); $build->setLog(''); $build->setCreated(new \DateTime()); $build->setBranch($branch); diff --git a/PHPCI/Controller/BuildController.php b/PHPCI/Controller/BuildController.php index 8c183774..e7e827d8 100644 --- a/PHPCI/Controller/BuildController.php +++ b/PHPCI/Controller/BuildController.php @@ -109,7 +109,7 @@ class BuildController extends \PHPCI\Controller $build = new Build(); $build->setProjectId($copy->getProjectId()); $build->setCommitId($copy->getCommitId()); - $build->setStatus(0); + $build->setStatus(Build::STATUS_NEW); $build->setBranch($copy->getBranch()); $build->setCreated(new \DateTime()); diff --git a/PHPCI/Controller/GitController.php b/PHPCI/Controller/GitController.php index 396ecaa9..b5a6cf87 100644 --- a/PHPCI/Controller/GitController.php +++ b/PHPCI/Controller/GitController.php @@ -47,7 +47,7 @@ class GitController extends \PHPCI\Controller $build->setCommitId($commit); } - $build->setStatus(0); + $build->setStatus(Build::STATUS_NEW); $build->setLog(''); $build->setCreated(new \DateTime()); } catch (\Exception $ex) { diff --git a/PHPCI/Controller/GithubController.php b/PHPCI/Controller/GithubController.php index b616cbb4..4fe99756 100644 --- a/PHPCI/Controller/GithubController.php +++ b/PHPCI/Controller/GithubController.php @@ -48,7 +48,7 @@ class GithubController extends \PHPCI\Controller $build = new Build(); $build->setProjectId($project); $build->setCommitId($payload['after']); - $build->setStatus(0); + $build->setStatus(Build::STATUS_NEW); $build->setLog(''); $build->setCreated(new \DateTime()); $build->setBranch(str_replace('refs/heads/', '', $payload['ref'])); diff --git a/PHPCI/Controller/GitlabController.php b/PHPCI/Controller/GitlabController.php index 020b6346..a466f4dd 100644 --- a/PHPCI/Controller/GitlabController.php +++ b/PHPCI/Controller/GitlabController.php @@ -42,7 +42,7 @@ class GitlabController extends \PHPCI\Controller $build = new Build(); $build->setProjectId($project); $build->setCommitId($payload['after']); - $build->setStatus(0); + $build->setStatus(Build::STATUS_NEW); $build->setLog(''); $build->setCreated(new \DateTime()); $build->setBranch(str_replace('refs/heads/', '', $payload['ref'])); diff --git a/PHPCI/Controller/ProjectController.php b/PHPCI/Controller/ProjectController.php index 1a4fc496..7c0b75e7 100644 --- a/PHPCI/Controller/ProjectController.php +++ b/PHPCI/Controller/ProjectController.php @@ -69,7 +69,7 @@ class ProjectController extends \PHPCI\Controller $build = new Build(); $build->setProjectId($projectId); $build->setCommitId('Manual'); - $build->setStatus(0); + $build->setStatus(Build::STATUS_NEW); $build->setBranch($project->getType() === 'hg' ? 'default' : 'master'); $build->setCreated(new \DateTime()); From 169a92dfebe234fa38b227b67c426e88d69a43be Mon Sep 17 00:00:00 2001 From: meadsteve Date: Sat, 7 Dec 2013 14:45:13 +0000 Subject: [PATCH 35/39] refactor the plugin stage calling code. --- PHPCI/Builder.php | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index 63cf2bad..08fd3bed 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -165,33 +165,35 @@ class Builder implements LoggerAwareInterface, BuildLogger $this->build->sendStatusPostback(); $this->success = true; - try { - // Set up the build: - $this->setupBuild(); + // Set up the build: + $this->setupBuild(); - // Run the core plugin stages: - foreach (array('setup', 'test', 'complete') as $stage) { - $this->success &= $this->pluginExecutor->executePlugins($this->config, $stage); - } + // Run the core plugin stages: + foreach (array('setup', 'test') as $stage) { + $this->success &= $this->pluginExecutor->executePlugins($this->config, $stage); + } - // Failed build? Execute failure plugins and then mark the build as failed. - if (!$this->success) { - $this->pluginExecutor->executePlugins($this->config, 'failure'); - throw new \Exception('BUILD FAILED!'); - } - - // If we got this far, the build was successful! - if ($this->success) { - $this->build->setStatus(Build::STATUS_SUCCESS); - $this->pluginExecutor->executePlugins($this->config, 'success'); - $this->logSuccess('BUILD SUCCESSFUL!'); - } - - } catch (\Exception $ex) { - $this->logFailure($ex->getMessage(), $ex); + // Set the status so this can be used by complete, success and failure + // stages. + if ($this->success) { + $this->build->setStatus(Build::STATUS_SUCCESS); + } + else { $this->build->setStatus(Build::STATUS_FAILED); } + // Complete stage plugins are always run + $this->pluginExecutor->executePlugins($this->config, 'complete'); + + if ($this->success) { + $this->pluginExecutor->executePlugins($this->config, 'success'); + $this->logSuccess('BUILD SUCCESSFUL!'); + } + else { + $this->pluginExecutor->executePlugins($this->config, 'failure'); + $this->logFailure("BUILD FAILURE"); + } + // Clean up: $this->log('Removing build.'); shell_exec(sprintf('rm -Rf "%s"', $this->buildPath)); From 148d30f74e2ab0ab0eefc3ff0adeb06dec56417f Mon Sep 17 00:00:00 2001 From: Pavel Pavlov Date: Sat, 7 Dec 2013 19:35:44 +0400 Subject: [PATCH 36/39] Don't redirect or reload a page when confirmation dialog wasn't confirmed --- PHPCI/View/Project/view.phtml | 2 +- public/assets/js/phpci.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/PHPCI/View/Project/view.phtml b/PHPCI/View/Project/view.phtml index 2fd6cf6d..036f9837 100644 --- a/PHPCI/View/Project/view.phtml +++ b/PHPCI/View/Project/view.phtml @@ -94,7 +94,7 @@ e.preventDefault(); confirmDelete( "project/delete/getId(); ?>", "Project" - ).onClose = function () {window.location = '/'}; + ).onCloseConfirmed = function () {window.location = '/'}; }); }) diff --git a/public/assets/js/phpci.js b/public/assets/js/phpci.js index 179597c3..7cf07458 100644 --- a/public/assets/js/phpci.js +++ b/public/assets/js/phpci.js @@ -82,6 +82,12 @@ var PHPCIConfirmDialogOptions = { }; var PHPCIConfirmDialog = Class.extend({ + /** + * @private + * @var {bool} Determines whether the dialog has been confirmed + */ + confirmed: false, + /** * @param {PHPCIConfirmDialogOptions} options */ @@ -148,13 +154,25 @@ var PHPCIConfirmDialog = Class.extend({ this.$confirmBtn.click(this.onConfirm.bind(this)); this.$confirmBtn.unbind('hidden.bs.modal'); + + /* + Bind the close event of the dialog to the set of onClose* methods + */ this.$dialog.on('hidden.bs.modal', function () {this.onClose()}.bind(this)); + this.$dialog.on('hidden.bs.modal', function () { + if (this.confirmed) { + this.onCloseConfirmed(); + } else { + this.onCloseCanceled(); + } + }.bind(this)); /* Restore state if was changed previously */ this.$cancelBtn.show(); this.$confirmBtn.show(); + this.confirmed = false; }, /** @@ -172,10 +190,24 @@ var PHPCIConfirmDialog = Class.extend({ }, onConfirm: function (e) { + this.confirmed = true; $(this).attr('disabled', 'disabled'); this.confirmBtnClick(e); }, + /** + * Called only when confirmed dialog was closed + */ + onCloseConfirmed: function () {}, + + /** + * Called only when canceled dialog was closed + */ + onCloseCanceled: function () {}, + + /** + * Called always when the dialog was closed + */ onClose: function () {}, showStatusMessage: function (message, closeTimeout) { From 853510a1d333c72e2d3d9603f0ae73fa6b47c2c7 Mon Sep 17 00:00:00 2001 From: Dan Cryer Date: Mon, 9 Dec 2013 16:12:54 +0000 Subject: [PATCH 37/39] Updating shell plugin with suggestions from #118 --- PHPCI/Plugin/Shell.php | 62 ++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/PHPCI/Plugin/Shell.php b/PHPCI/Plugin/Shell.php index d86b6e1b..b9949cd3 100644 --- a/PHPCI/Plugin/Shell.php +++ b/PHPCI/Plugin/Shell.php @@ -1,11 +1,11 @@ -* @package PHPCI -* @subpackage Plugins -*/ + * Shell Plugin - Allows execute shell commands. + * @author Kinn Coelho Julião + * @package PHPCI + * @subpackage Plugins + */ class Shell implements \PHPCI\Plugin { protected $args; protected $phpci; /** - * @var string $command The command to be executed + * @var string[] $commands The commands to be executed */ - protected $command; + protected $commands = array(); public function __construct(Builder $phpci, Build $build, array $options = array()) { $this->phpci = $phpci; if (isset($options['command'])) { - $command = $options['command']; - $command = str_replace("%buildpath%", $this->phpci->buildPath, $command); - $this->command = $command; + // Keeping this for backwards compatibility, new projects should use interpolation vars. + $options['command'] = str_replace("%buildpath%", $this->phpci->buildPath, $options['command']); + $this->commands = array($options['command']); + return; + } + + /* + * Support the new syntax: + * + * shell: + * - "cd /www" + * - "rm -f file.txt" + */ + if (is_array($options)) { + $this->commands = $options; } } /** - * Runs the shell command. - */ + * Runs the shell command. + */ public function execute() { if (!defined('ENABLE_SHELL_PLUGIN') || !ENABLE_SHELL_PLUGIN) { throw new \Exception('The shell plugin is not enabled.'); } - - $success = $this->phpci->executeCommand($this->command); - + + $success = true; + + foreach ($this->commands as $command) { + $command = $this->phpci->interpolate($command); + + if (!$this->phpci->executeCommand($command)) { + $success = false; + } + } + return $success; } } From 123815aec94b93becbcabe7fac7f7818eac36016 Mon Sep 17 00:00:00 2001 From: Dan Cryer Date: Mon, 9 Dec 2013 16:27:39 +0000 Subject: [PATCH 38/39] Fix for #210 --- PHPCI/View/Plugin/index.phtml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PHPCI/View/Plugin/index.phtml b/PHPCI/View/Plugin/index.phtml index f3f10e60..f9170032 100644 --- a/PHPCI/View/Plugin/index.phtml +++ b/PHPCI/View/Plugin/index.phtml @@ -1,7 +1,7 @@

Plugins

-

PHPCI cannot automatically install/remove plugins for you, as the shell_exec() - function is disabled. PHPCI will update composer.json for you, but you will need to run Composer manually to make the changes.

+

PHPCI cannot automatically install/remove plugins for you, as either the shell_exec() + function is disabled or PHPCI could not find Composer. PHPCI will update composer.json for you, but you will need to run Composer manually to make the changes.

From cfe45f54d0e23c53a4ecd78e147a0b7f7fd546af Mon Sep 17 00:00:00 2001 From: indigodp Date: Wed, 11 Dec 2013 09:33:59 +0200 Subject: [PATCH 39/39] Update LocalBuild.php Add fetching needed branch for local build --- PHPCI/Model/Build/LocalBuild.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PHPCI/Model/Build/LocalBuild.php b/PHPCI/Model/Build/LocalBuild.php index 08d997dd..8e6984c6 100644 --- a/PHPCI/Model/Build/LocalBuild.php +++ b/PHPCI/Model/Build/LocalBuild.php @@ -57,7 +57,7 @@ class LocalBuild extends Build // If it is indeed a bare repository, then extract it into our build path: if ($gitConfig['core']['bare']) { - $builder->executeCommand('mkdir %2$s; git --git-dir="%1$s" archive master | tar -x -C "%2$s"', $reference, $buildPath); + $builder->executeCommand('mkdir %2$s; git --git-dir="%1$s" archive %3$s | tar -x -C "%2$s"', $reference, $buildPath, $this->getBranch()); return true; }