Refactor the plugin interface, added more interfaces.
This commit is contained in:
parent
9ce80909d2
commit
8a7a921ee1
|
@ -15,5 +15,29 @@ namespace PHPCI;
|
|||
*/
|
||||
interface Plugin
|
||||
{
|
||||
/**
|
||||
* Sets the options for the current build stage.
|
||||
*
|
||||
* @param array $options
|
||||
*
|
||||
* @throws \Exception If the options are invalid.
|
||||
*/
|
||||
public function setOptions(array $options);
|
||||
|
||||
/**
|
||||
* Sets the settings for all stages.
|
||||
*
|
||||
* @param array $settings
|
||||
*
|
||||
* @throws \Exception If the settings are invalid.
|
||||
*/
|
||||
public function setCommonSettings(array $settings);
|
||||
|
||||
/**
|
||||
* Execute the plugin.
|
||||
*
|
||||
* @return bool true if all went nice, false if the plugin ended normally but failed.
|
||||
* @throws \Exception If something prevented the plugin to end normally.
|
||||
*/
|
||||
public function execute();
|
||||
}
|
||||
|
|
|
@ -33,18 +33,14 @@ abstract class AbstractExecutingPlugin extends AbstractPlugin
|
|||
*
|
||||
* @param Builder $builder
|
||||
* @param Build $build
|
||||
* @param BuildLogger $logger
|
||||
* @param CommandExecutor $executor
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(
|
||||
Builder $builder,
|
||||
Build $build,
|
||||
BuildLogger $logger,
|
||||
CommandExecutor $executor,
|
||||
array $options = array()
|
||||
CommandExecutor $executor
|
||||
) {
|
||||
$this->executor = $executor;
|
||||
parent:__construct($builder, $build, $logger, $options);
|
||||
parent:__construct($builder, $build);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,39 +11,25 @@
|
|||
|
||||
namespace PHPCI\Plugin;
|
||||
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Helper\BuildInterpolator;
|
||||
use PHPCI\Helper\CommandExecutor;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\Plugin\Util\InterpolatorAwareInterface;
|
||||
|
||||
/**
|
||||
* Asbtract plugin which uses a BuildInterpolator.
|
||||
*/
|
||||
abstract class AbstractInterpolatingPlugin extends AbstractExecutingPlugin
|
||||
abstract class AbstractInterpolatingPlugin extends AbstractExecutingPlugin implements InterpolatorAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var BuildInterpolator
|
||||
*/
|
||||
protected $interpolator;
|
||||
|
||||
/** Standard constructor.
|
||||
/**
|
||||
*
|
||||
* @param Builder $phpci
|
||||
* @param Build $build
|
||||
* @param BuildLogger $logger
|
||||
* @param CommandExecutor $executor
|
||||
* @param BuildInterpolator $interpolator
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(
|
||||
Builder $phpci,
|
||||
Build $build,
|
||||
BuildLogger $logger,
|
||||
CommandExecutor $executor,
|
||||
BuildInterpolator $interpolator,
|
||||
array $options = array()
|
||||
) {
|
||||
public function setInterpolator(BuildInterpolator $interpolator)
|
||||
{
|
||||
$this->interpolator = $interpolator;
|
||||
parent::__construct($phpci, $build, $logger, $executor, $options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,13 +14,15 @@ use PHPCI\Builder;
|
|||
use PHPCI\Logging\BuildLogger;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\Plugin;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Asbtract plugin.
|
||||
*
|
||||
* Holds helper for the subclasses.
|
||||
*/
|
||||
abstract class AbstractPlugin implements Plugin
|
||||
abstract class AbstractPlugin implements Plugin, LoggerAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var Build
|
||||
|
@ -33,7 +35,7 @@ abstract class AbstractPlugin implements Plugin
|
|||
protected $phpci;
|
||||
|
||||
/**
|
||||
* @var BuildLogger
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
|
@ -43,30 +45,23 @@ abstract class AbstractPlugin implements Plugin
|
|||
* @param Builder $builder
|
||||
* @param Build $build
|
||||
* @param BuildLogger $logger
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(Builder $builder, Build $build, BuildLogger $logger, array $options = array())
|
||||
public function __construct(Builder $builder, Build $build)
|
||||
{
|
||||
$this->phpci = $builder;
|
||||
$this->build = $build;
|
||||
$this->logger = $logger;
|
||||
|
||||
$this->setup($options);
|
||||
$this->setBuildPath($builder->buildPath);
|
||||
$this->setIgnorePath((array) $builder->ignore);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the key used for options in phpci.yml for this plugin.
|
||||
*
|
||||
* @return string
|
||||
* @param LoggerInterface $logger
|
||||
*/
|
||||
public function getPluginKey()
|
||||
public function setLogger(LoggerInterface $logger)
|
||||
{
|
||||
$matches = null;
|
||||
$className = get_class($this);
|
||||
if (!preg_match('/^PHPCI\\Plguin\\(\w+)$/', $className, $matches)) {
|
||||
return $className;
|
||||
}
|
||||
return strtolower(preg_replace('/[[:lower:]][[:upper:]]/g', '$1_$2', $matches[1]));
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,34 +95,4 @@ abstract class AbstractPlugin implements Plugin
|
|||
{
|
||||
// NOOP
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the plugin for a given stage.
|
||||
*
|
||||
* @param array $options
|
||||
*/
|
||||
abstract protected function setOptions(array $options);
|
||||
|
||||
/**
|
||||
* Post-constructor setup.
|
||||
*
|
||||
* TODO: expose setOptions and setCommonSettings in Plugin and get rid of this method.
|
||||
*
|
||||
* @param array $options
|
||||
*/
|
||||
private function setup(array $options)
|
||||
{
|
||||
$this->setBuildPath($this->phpci->buildPath);
|
||||
$this->setIgnorePath((array) $this->phpci->ignore);
|
||||
|
||||
$settings = $this->phpci->getConfig('build_settings');
|
||||
$key = $this->getPluginKey();
|
||||
if ($settings && isset($settings[$key])) {
|
||||
$this->setCommonSettings((array) $settings[$key]);
|
||||
} else {
|
||||
$this->setCommonSettings(array());
|
||||
}
|
||||
|
||||
$this->setOptions($options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,11 +72,11 @@ class Atoum extends AbstractExecutingPlugin
|
|||
|
||||
if (count(preg_grep("/Success \(/", $output)) == 0) {
|
||||
$status = false;
|
||||
$this->logger->log($output);
|
||||
$this->logger->notice($output);
|
||||
}
|
||||
if (count($output) == 0) {
|
||||
$status = false;
|
||||
$this->logger->log(Lang::get('no_tests_performed'));
|
||||
$this->logger->warning(Lang::get('no_tests_performed'));
|
||||
}
|
||||
|
||||
return $status;
|
||||
|
|
|
@ -129,10 +129,7 @@ class Codeception extends AbstractExecutingPlugin implements PHPCI\ZeroConfigPlu
|
|||
$configPath = $this->buildPath . $configPath;
|
||||
$success = $this->executor->executeCommand($cmd, $this->buildPath, $configPath);
|
||||
|
||||
$this->logger->log(
|
||||
'Codeception XML path: '. $this->buildPath . $this->path . '_output/report.xml',
|
||||
Loglevel::DEBUG
|
||||
);
|
||||
$this->logger->debug('Codeception XML path: '. $this->buildPath . $this->path . '_output/report.xml');
|
||||
$xml = file_get_contents($this->buildPath . $this->path . '_output/report.xml', false);
|
||||
|
||||
$parser = new Parser($this->phpci, $xml);
|
||||
|
|
|
@ -85,10 +85,10 @@ class Composer extends AbstractExecutingPlugin implements PHPCI\ZeroConfigPlugin
|
|||
$cmd .= $composerLocation . ' --no-ansi --no-interaction ';
|
||||
|
||||
if ($this->preferDist) {
|
||||
$this->logger->log('Using --prefer-dist flag');
|
||||
$this->logger->notice('Using --prefer-dist flag');
|
||||
$cmd .= '--prefer-dist';
|
||||
} else {
|
||||
$this->logger->log('Using --prefer-source flag');
|
||||
$this->logger->notice('Using --prefer-source flag');
|
||||
$cmd .= '--prefer-source';
|
||||
}
|
||||
|
||||
|
|
|
@ -65,8 +65,10 @@ class Email extends AbstractPlugin
|
|||
);
|
||||
|
||||
// This is a success if we've not failed to send anything.
|
||||
$this->logger->log(sprintf("%d emails sent", (count($addresses) - $sendFailures)));
|
||||
$this->logger->log(sprintf("%d emails failed to send", $sendFailures));
|
||||
$this->logger->notice(sprintf("%d emails sent", (count($addresses) - $sendFailures)));
|
||||
if ($sendFailures > 0) {
|
||||
$this->logger->error(sprintf("%d emails failed to send", $sendFailures));
|
||||
}
|
||||
|
||||
return ($sendFailures === 0);
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ class Lint extends AbstractExecutingPlugin
|
|||
$success = true;
|
||||
|
||||
if (!$this->executor->executeCommand($php . ' -l "%s"', $this->buildPath . $path)) {
|
||||
$this->logger->logFailure($path);
|
||||
$this->logger->error($path);
|
||||
$success = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,24 +75,19 @@ class Mysql extends AbstractInterpolatingPlugin
|
|||
*/
|
||||
public function execute()
|
||||
{
|
||||
try {
|
||||
$opts = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
|
||||
$pdo = new PDO('mysql:host=' . $this->host, $this->user, $this->pass, $opts);
|
||||
$opts = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
|
||||
$pdo = new PDO('mysql:host=' . $this->host, $this->user, $this->pass, $opts);
|
||||
|
||||
foreach ($this->queries as $query) {
|
||||
if (!is_array($query)) {
|
||||
// Simple query
|
||||
$pdo->query($this->interpolator->interpolate($query));
|
||||
} elseif (isset($query['import'])) {
|
||||
// SQL file execution
|
||||
$this->executeFile($query['import']);
|
||||
} else {
|
||||
throw new \Exception(Lang::get('invalid_command'));
|
||||
}
|
||||
foreach ($this->queries as $query) {
|
||||
if (!is_array($query)) {
|
||||
// Simple query
|
||||
$pdo->query($this->interpolator->interpolate($query));
|
||||
} elseif (isset($query['import'])) {
|
||||
// SQL file execution
|
||||
$this->executeFile($query['import']);
|
||||
} else {
|
||||
throw new \Exception(Lang::get('invalid_command'));
|
||||
}
|
||||
} catch (\Exception $ex) {
|
||||
$this->logger->logFailure($ex->getMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ class Pdepend extends AbstractExecutingPlugin
|
|||
$config = $this->phpci->getSystemConfig('phpci');
|
||||
|
||||
if ($success) {
|
||||
$this->logger->logSuccess(
|
||||
$this->logger->notice(
|
||||
sprintf(
|
||||
"Pdepend successful. You can use %s\n, ![Chart](%s \"Pdepend Chart\")\n
|
||||
and ![Pyramid](%s \"Pdepend Pyramid\")\n
|
||||
|
|
|
@ -65,16 +65,11 @@ class Pgsql extends AbstractInterpolatingPlugin
|
|||
*/
|
||||
public function execute()
|
||||
{
|
||||
try {
|
||||
$opts = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
|
||||
$pdo = new PDO('pgsql:host=' . $this->host, $this->user, $this->pass, $opts);
|
||||
$opts = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
|
||||
$pdo = new PDO('pgsql:host=' . $this->host, $this->user, $this->pass, $opts);
|
||||
|
||||
foreach ($this->queries as $query) {
|
||||
$pdo->query($this->interpolator->interpolate($query));
|
||||
}
|
||||
} catch (\Exception $ex) {
|
||||
$this->logger->logFailure($ex->getMessage());
|
||||
return false;
|
||||
foreach ($this->queries as $query) {
|
||||
$pdo->query($this->interpolator->interpolate($query));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -200,23 +200,14 @@ class Phar extends AbstractPlugin
|
|||
*/
|
||||
public function execute()
|
||||
{
|
||||
$success = false;
|
||||
$phar = new PHPPhar($this->getDirectory() . '/' . $this->getFilename(), 0, $this->getFilename());
|
||||
$phar->buildFromDirectory($this->getPHPCI()->buildPath, $this->getRegExp());
|
||||
|
||||
try {
|
||||
$phar = new PHPPhar($this->getDirectory() . '/' . $this->getFilename(), 0, $this->getFilename());
|
||||
$phar->buildFromDirectory($this->getPHPCI()->buildPath, $this->getRegExp());
|
||||
|
||||
$stub = $this->getStubContent();
|
||||
if ($stub) {
|
||||
$phar->setStub($stub);
|
||||
}
|
||||
|
||||
$success = true;
|
||||
} catch (Exception $e) {
|
||||
$this->getPHPCI()->log(Lang::get('phar_internal_error'));
|
||||
$this->getPHPCI()->log($e->getMessage());
|
||||
$stub = $this->getStubContent();
|
||||
if ($stub) {
|
||||
$phar->setStub($stub);
|
||||
}
|
||||
|
||||
return $success;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -197,7 +197,7 @@ class PhpCodeSniffer extends AbstractExecutingPlugin implements PHPCI\ZeroConfig
|
|||
$data = json_decode(trim($output), true);
|
||||
|
||||
if (!is_array($data)) {
|
||||
$this->logger->log($output);
|
||||
$this->logger->error($output);
|
||||
throw new \Exception(PHPCI\Helper\Lang::get('could_not_process_report'));
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ class PhpCpd extends AbstractExecutingPlugin
|
|||
$xml = simplexml_load_string($xmlString);
|
||||
|
||||
if ($xml === false) {
|
||||
$this->logger->log($xmlString);
|
||||
$this->logger->error($xmlString);
|
||||
throw new \Exception(Lang::get('could_not_process_report'));
|
||||
}
|
||||
|
||||
|
|
|
@ -128,7 +128,7 @@ class PhpMessDetector extends AbstractExecutingPlugin implements PHPCI\ZeroConfi
|
|||
$xml = simplexml_load_string($xmlString);
|
||||
|
||||
if ($xml === false) {
|
||||
$this->logger->log($xmlString);
|
||||
$this->logger->error($xmlString);
|
||||
throw new \Exception('Could not process PHPMD report XML.');
|
||||
}
|
||||
|
||||
|
|
|
@ -156,7 +156,6 @@ class PhpUnit extends AbstractInterpolatingPlugin implements PHPCI\ZeroConfigPlu
|
|||
$tapParser = new TapParser($tapString);
|
||||
$output = $tapParser->parse();
|
||||
} catch (\Exception $ex) {
|
||||
$this->logger->logFailure($tapString);
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,16 +53,11 @@ class Sqlite extends AbstractPlugin
|
|||
*/
|
||||
public function execute()
|
||||
{
|
||||
try {
|
||||
$opts = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
|
||||
$pdo = new PDO('sqlite:' . $this->path, $opts);
|
||||
$opts = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
|
||||
$pdo = new PDO('sqlite:' . $this->path, $opts);
|
||||
|
||||
foreach ($this->queries as $query) {
|
||||
$pdo->query($this->interpolator->interpolate($query));
|
||||
}
|
||||
} catch (\Exception $ex) {
|
||||
$this->logger->logFailure($ex->getMessage());
|
||||
return false;
|
||||
foreach ($this->queries as $query) {
|
||||
$pdo->query($this->interpolator->interpolate($query));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ class TechnicalDebt extends AbstractPlugin implements PHPCI\ZeroConfigPlugin
|
|||
|
||||
list($errorCount, $data) = $this->getErrorList();
|
||||
|
||||
$this->logger->log("Found $errorCount instances of " . implode(', ', $this->searches));
|
||||
$this->logger->notice("Found $errorCount instances of " . implode(', ', $this->searches));
|
||||
|
||||
$this->build->storeMeta('technical_debt-warnings', $errorCount);
|
||||
$this->build->storeMeta('technical_debt-data', $data);
|
||||
|
|
|
@ -48,8 +48,10 @@ class Executor
|
|||
foreach ($config[$stage] as $plugin => $options) {
|
||||
$this->logger->log(Lang::get('running_plugin', $plugin));
|
||||
|
||||
$settings = isset($config['build_settings'][$plugin]) ? $config['build_settings'][$plugin] : array();
|
||||
|
||||
// Try and execute it:
|
||||
if ($this->executePlugin($plugin, $options)) {
|
||||
if ($this->executePlugin($plugin, $options, $settings)) {
|
||||
// Execution was successful:
|
||||
$this->logger->logSuccess(Lang::get('plugin_success'));
|
||||
} elseif ($stage == 'setup') {
|
||||
|
@ -72,8 +74,34 @@ class Executor
|
|||
|
||||
/**
|
||||
* Executes a given plugin, with options and returns the result.
|
||||
*
|
||||
* @param string $plugin Plugin name or class.
|
||||
* @param array $options Stage options.
|
||||
* @param array $settings Common options.
|
||||
* @return boolean true if plugin ended successfully, false if something went wrong.
|
||||
*/
|
||||
public function executePlugin($plugin, $options)
|
||||
public function executePlugin($plugin, array $options, array $settings)
|
||||
{
|
||||
try {
|
||||
$obj = $this->buildPlugin($plugin);
|
||||
$obj->setCommonSettings($settings);
|
||||
$obj->setOptions($options);
|
||||
|
||||
return $obj->execute();
|
||||
} catch (\Exception $ex) {
|
||||
$this->logger->logFailure(Lang::get('exception') . $ex->getMessage(), $ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a plugin instance of the given name.
|
||||
*
|
||||
* @param string $plugin Plugin class or name
|
||||
* @return \PHPCI\Plugin
|
||||
* @throws \Exception If the plugin could not be created.
|
||||
*/
|
||||
protected function buildPlugin($plugin)
|
||||
{
|
||||
// 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.
|
||||
|
@ -87,24 +115,9 @@ class Executor
|
|||
}
|
||||
|
||||
if (!class_exists($class)) {
|
||||
$this->logger->logFailure(Lang::get('plugin_missing', $plugin));
|
||||
return false;
|
||||
throw new \Exception(Lang::get('plugin_missing', $plugin));
|
||||
}
|
||||
|
||||
$rtn = true;
|
||||
|
||||
// Try running it:
|
||||
try {
|
||||
$obj = $this->pluginFactory->buildPlugin($class, $options);
|
||||
|
||||
if (!$obj->execute()) {
|
||||
$rtn = false;
|
||||
}
|
||||
} catch (\Exception $ex) {
|
||||
$this->logger->logFailure(Lang::get('exception') . $ex->getMessage(), $ex);
|
||||
$rtn = false;
|
||||
}
|
||||
|
||||
return $rtn;
|
||||
return $this->pluginFactory->buildPlugin($class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace PHPCI\Plugin\Util;
|
||||
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
/**
|
||||
* Plugin Factory - Loads Plugins and passes required dependencies.
|
||||
* @package PHPCI\Plugin\Util
|
||||
|
@ -104,6 +105,14 @@ class Factory
|
|||
$plugin = $reflectedPlugin->newInstance();
|
||||
}
|
||||
|
||||
if ($plugin instanceof InterpolatorAwareInterface) {
|
||||
$plugin->setInterpolator($this->getResourceFor('PHPCI\Helper\BuildInterpolator'));
|
||||
}
|
||||
|
||||
if ($plugin instanceof LoggerAwareInterface) {
|
||||
$plugin->setLogger($this->getResourceFor('Psr\Log\LoggerInterface'));
|
||||
}
|
||||
|
||||
return $plugin;
|
||||
}
|
||||
|
||||
|
|
27
PHPCI/Plugin/Util/InterpolatorAwareInterface.php
Normal file
27
PHPCI/Plugin/Util/InterpolatorAwareInterface.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2014, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link https://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\Plugin\Util;
|
||||
|
||||
use PHPCI\Helper\BuildInterpolator;
|
||||
|
||||
/**
|
||||
* An object that accepts a build interpolator.
|
||||
*
|
||||
* @author Adirelle <adirelle@gmail.com>
|
||||
*/
|
||||
interface InterpolatorAwareInterface
|
||||
{
|
||||
/**
|
||||
* Sets the BuildInterpolator.
|
||||
*
|
||||
* @param BuildInterpolator $interpolator
|
||||
*/
|
||||
public function setInterpolator(BuildInterpolator $interpolator);
|
||||
}
|
Loading…
Reference in a new issue