From 9891a4be62be2a7472ba0a366d7851a990071371 Mon Sep 17 00:00:00 2001 From: Steve B Date: Thu, 28 Nov 2013 14:05:26 +0000 Subject: [PATCH 01/16] 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 02/16] 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 03/16] 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 a942525f84f1717b60ffe8c44e431bc75b40effa Mon Sep 17 00:00:00 2001 From: "steve.brazier" Date: Fri, 6 Dec 2013 09:59:07 +0000 Subject: [PATCH 04/16] 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 05/16] 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 06/16] 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 07/16] 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 08/16] 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 09/16] 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 10/16] 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 11/16] 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 12/16] 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 13/16] 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 35ac98056cae895a24c22af2fb04c5e7ec4e93c0 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Sat, 7 Dec 2013 09:34:28 +0000 Subject: [PATCH 14/16] 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 15/16] 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 16/16] 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; } /**