Adding the ability to run projects with no build configuration. Runs what plugins it can automatically. Closes #235

This commit is contained in:
Dan Cryer 2014-04-25 10:17:39 +01:00
parent 70b47152cb
commit 4363cb1966
9 changed files with 224 additions and 28 deletions

View file

@ -88,20 +88,73 @@ class Build extends BuildBase
*/
protected function handleConfig(Builder $builder, $buildPath)
{
$build_config = null;
// Try phpci.yml first:
if (is_file($buildPath . '/phpci.yml')) {
$build_config = file_get_contents($buildPath . '/phpci.yml');
}
if (!is_file($buildPath . '/phpci.yml') || !$build_config) {
// Try getting the project build config from the database:
if (empty($build_config)) {
$build_config = $this->getProject()->getBuildConfig();
if (!$build_config) {
$builder->logFailure('Project does not contain a phpci.yml file.');
return false;
}
// Fall back to zero config plugins:
if (empty($build_config)) {
$build_config = $this->getZeroConfigPlugins($builder);
}
if (is_string($build_config)) {
$yamlParser = new YamlParser();
$build_config = $yamlParser->parse($build_config);
}
$builder->setConfigArray($build_config);
return true;
}
protected function getZeroConfigPlugins(Builder $builder)
{
$pluginDir = PHPCI_DIR . 'PHPCI/Plugin/';
$dir = new \DirectoryIterator($pluginDir);
$config = array(
'build_settings' => array(
'ignore' => array(
'vendor/',
)
)
);
foreach ($dir as $item) {
if ($item->isDot()) {
continue;
}
if (!$item->isFile()) {
continue;
}
if ($item->getExtension() != 'php') {
continue;
}
$className = '\PHPCI\Plugin\\'.$item->getBasename('.php');
$reflectedPlugin = new \ReflectionClass($className);
if (!$reflectedPlugin->implementsInterface('\PHPCI\ZeroConfigPlugin')) {
continue;
}
foreach (array('setup', 'test', 'complete', 'success', 'failure') as $stage) {
if ($className::canExecute($stage, $builder, $this)) {
$config[$stage][$className] = array();
}
}
}
$yamlParser = new YamlParser();
$builder->setConfigArray($yamlParser->parse($build_config));
return $builder->getConfig('build_settings');
return $config;
}
}

View file

@ -9,6 +9,7 @@
namespace PHPCI\Plugin;
use PHPCI;
use PHPCI\Builder;
use PHPCI\Model\Build;
@ -18,13 +19,24 @@ use PHPCI\Model\Build;
* @package PHPCI
* @subpackage Plugins
*/
class Composer implements \PHPCI\Plugin
class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
{
protected $directory;
protected $action;
protected $preferDist;
protected $phpci;
public static function canExecute($stage, Builder $builder, Build $build)
{
$path = $builder->buildPath . '/composer.json';
if (file_exists($path) && $stage == 'setup') {
return true;
}
return false;
}
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$path = $phpci->buildPath;

View file

@ -9,6 +9,7 @@
namespace PHPCI\Plugin;
use PHPCI;
use PHPCI\Builder;
use PHPCI\Model\Build;
@ -18,7 +19,7 @@ use PHPCI\Model\Build;
* @package PHPCI
* @subpackage Plugins
*/
class Lint implements \PHPCI\Plugin
class Lint implements PHPCI\Plugin
{
protected $directories;
protected $recursive = true;

View file

@ -9,6 +9,7 @@
namespace PHPCI\Plugin;
use PHPCI;
use PHPCI\Builder;
use PHPCI\Model\Build;
@ -18,7 +19,7 @@ use PHPCI\Model\Build;
* @package PHPCI
* @subpackage Plugins
*/
class PhpCodeSniffer implements \PHPCI\Plugin
class PhpCodeSniffer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
{
/**
* @var \PHPCI\Builder
@ -50,6 +51,16 @@ class PhpCodeSniffer implements \PHPCI\Plugin
*/
protected $encoding;
/**
* @var int
*/
protected $allowed_errors;
/**
* @var int
*/
protected $allowed_warnings;
/**
* @var string, based on the assumption the root may not hold the code to be
* tested, exteds the base path
@ -61,21 +72,33 @@ class PhpCodeSniffer implements \PHPCI\Plugin
*/
protected $ignore;
public static function canExecute($stage, Builder $builder, Build $build)
{
if ($stage == 'test') {
return true;
}
return false;
}
/**
* @param \PHPCI\Builder $phpci
* @param \PHPCI\Model\Build $build
* @param array $options
*/
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->phpci = $phpci;
$this->build = $build;
$this->suffixes = array('php');
$this->directory = $phpci->buildPath;
$this->standard = 'PSR2';
$this->tab_width = '';
$this->encoding = '';
$this->path = '';
$this->ignore = $this->phpci->ignore;
$this->phpci = $phpci;
$this->build = $build;
$this->suffixes = array('php');
$this->directory = $phpci->buildPath;
$this->standard = 'PSR2';
$this->tab_width = '';
$this->encoding = '';
$this->path = '';
$this->ignore = $this->phpci->ignore;
$this->allowed_warnings = -1;
$this->allowed_errors = -1;
if (isset($options['suffixes'])) {
$this->suffixes = (array)$options['suffixes'];
@ -104,6 +127,14 @@ class PhpCodeSniffer implements \PHPCI\Plugin
if (isset($options['ignore'])) {
$this->ignore = $options['ignore'];
}
if (isset($options['allowed_warnings'])) {
$this->allowed_warnings = (int)$options['allowed_warnings'];
}
if (isset($options['allowed_errors'])) {
$this->allowed_errors = (int)$options['allowed_errors'];
}
}
/**
@ -121,7 +152,7 @@ class PhpCodeSniffer implements \PHPCI\Plugin
}
$cmd = $phpcs . ' --report=emacs %s %s %s %s %s "%s"';
$success = $this->phpci->executeCommand(
$this->phpci->executeCommand(
$cmd,
$standard,
$suffixes,
@ -133,14 +164,25 @@ class PhpCodeSniffer implements \PHPCI\Plugin
$output = $this->phpci->getLastOutput();
$success = true;
$matches = array();
if (preg_match_all('/\: warning \-/', $output, $matches)) {
$this->build->storeMeta('phpcs-warnings', count($matches[0]));
$warnings = count($matches[0]);
$this->build->storeMeta('phpcs-warnings', $warnings);
if ($this->allowed_warnings != -1 && $warnings > $this->allowed_warnings) {
$success = false;
}
}
$matches = array();
if (preg_match_all('/\: error \-/', $output, $matches)) {
$this->build->storeMeta('phpcs-errors', count($matches[0]));
$errors = count($matches[0]);
$this->build->storeMeta('phpcs-errors', $errors);
if ($this->allowed_errors != -1 && $errors > $this->allowed_errors) {
$success = false;
}
}
return $success;

View file

@ -9,6 +9,7 @@
namespace PHPCI\Plugin;
use PHPCI;
use PHPCI\Builder;
use PHPCI\Model\Build;
@ -18,7 +19,7 @@ use PHPCI\Model\Build;
* @package PHPCI
* @subpackage Plugins
*/
class PhpLoc implements \PHPCI\Plugin
class PhpLoc implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
{
/**
* @var string
@ -29,6 +30,15 @@ class PhpLoc implements \PHPCI\Plugin
*/
protected $phpci;
public static function canExecute($stage, Builder $builder, Build $build)
{
if ($stage == 'test') {
return true;
}
return false;
}
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->phpci = $phpci;

View file

@ -9,6 +9,7 @@
namespace PHPCI\Plugin;
use PHPCI;
use PHPCI\Builder;
use PHPCI\Model\Build;
@ -18,7 +19,7 @@ use PHPCI\Model\Build;
* @package PHPCI
* @subpackage Plugins
*/
class PhpMessDetector implements \PHPCI\Plugin
class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
{
/**
* @var \PHPCI\Builder
@ -49,6 +50,15 @@ class PhpMessDetector implements \PHPCI\Plugin
*/
protected $rules;
public static function canExecute($stage, Builder $builder, Build $build)
{
if ($stage == 'test') {
return true;
}
return false;
}
/**
* @param \PHPCI\Builder $phpci
* @param array $options
@ -61,11 +71,16 @@ class PhpMessDetector implements \PHPCI\Plugin
$this->ignore = $phpci->ignore;
$this->path = '';
$this->rules = array('codesize', 'unusedcode', 'naming');
$this->allowed_warnings = -1;
if (!empty($options['path'])) {
$this->path = $options['path'];
}
if (array_key_exists('allowed_warnings', $options)) {
$this->allowed_warnings = (int)$options['allowed_warnings'];
}
foreach (array('rules', 'ignore', 'suffixes') as $key) {
$this->overrideSetting($options, $key);
}
@ -110,7 +125,7 @@ class PhpMessDetector implements \PHPCI\Plugin
}
$cmd = $phpmd . ' "%s" text %s %s %s';
$success = $this->phpci->executeCommand(
$this->phpci->executeCommand(
$cmd,
$path,
implode(',', $this->rules),
@ -118,9 +133,14 @@ class PhpMessDetector implements \PHPCI\Plugin
$suffixes
);
$success = true;
$errors = count(array_filter(explode(PHP_EOL, trim($this->phpci->getLastOutput()))));
$this->build->storeMeta('phpmd-warnings', $errors);
if ($this->allowed_warnings != -1 && $errors > $this->allowed_warnings) {
$success = false;
}
return $success;
}

View file

@ -9,6 +9,7 @@
namespace PHPCI\Plugin;
use PHPCI;
use PHPCI\Builder;
use PHPCI\Model\Build;
@ -18,7 +19,7 @@ use PHPCI\Model\Build;
* @package PHPCI
* @subpackage Plugins
*/
class PhpSpec implements \PHPCI\Plugin
class PhpSpec implements PHPCI\Plugin
{
protected $phpci;

View file

@ -9,6 +9,7 @@
namespace PHPCI\Plugin;
use PHPCI;
use PHPCI\Builder;
use PHPCI\Model\Build;
@ -18,7 +19,7 @@ use PHPCI\Model\Build;
* @package PHPCI
* @subpackage Plugins
*/
class PhpUnit implements \PHPCI\Plugin
class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
{
protected $args;
protected $phpci;
@ -46,9 +47,44 @@ class PhpUnit implements \PHPCI\Plugin
*/
protected $xmlConfigFile;
public static function canExecute($stage, Builder $builder, Build $build)
{
if ($stage == 'test' && !is_null(self::findConfigFile($builder->buildPath))) {
return true;
}
return false;
}
public static function findConfigFile($buildPath)
{
if (file_exists($buildPath . '/phpunit.xml')) {
return $buildPath . '/phpunit.xml';
}
if (file_exists($buildPath . '/tests/phpunit.xml')) {
return $buildPath . '/tests/phpunit.xml';
}
if (file_exists($buildPath . '/phpunit.xml.dist')) {
return $buildPath . '/phpunit.xml.dist';
}
if (file_exists($buildPath . '/tests/phpunit.xml.dist')) {
return $buildPath . '/tests/phpunit.xml.dist';
}
return null;
}
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->phpci = $phpci;
$this->phpci = $phpci;
if (!count($options)) {
$this->runFrom = $phpci->buildPath;
$this->xmlConfigFile = self::findConfigFile($phpci->buildPath);
}
if (isset($options['directory'])) {
$this->directory = $options['directory'];

View file

@ -0,0 +1,21 @@
<?php
/**
* PHPCI - Continuous Integration for PHP
*
* @copyright Copyright 2013, Block 8 Limited.
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
* @link http://www.phptesting.org/
*/
namespace PHPCI;
use PHPCI\Model\Build;
/**
* PHPCI Plugin Interface - Used by all build plugins.
* @author Dan Cryer <dan@block8.co.uk>
*/
interface ZeroConfigPlugin
{
public static function canExecute($stage, Builder $builder, Build $build);
}