Merge pull request #2 from Block8/master

update fork
This commit is contained in:
yourilima 2014-05-05 15:05:49 +02:00
commit c0d1634b45
53 changed files with 1054 additions and 515 deletions

View file

@ -47,11 +47,6 @@ class Builder implements LoggerAwareInterface
*/
protected $directory;
/**
* @var bool
*/
protected $success = true;
/**
* @var bool
*/
@ -192,7 +187,7 @@ class Builder implements LoggerAwareInterface
$this->build->setStarted(new \DateTime());
$this->store->save($this->build);
$this->build->sendStatusPostback();
$this->success = true;
$success = true;
try {
// Set up the build:
@ -200,12 +195,12 @@ class Builder implements LoggerAwareInterface
// Run the core plugin stages:
foreach (array('setup', 'test') as $stage) {
$this->success &= $this->pluginExecutor->executePlugins($this->config, $stage);
$success &= $this->pluginExecutor->executePlugins($this->config, $stage);
}
// Set the status so this can be used by complete, success and failure
// stages.
if ($this->success) {
if ($success) {
$this->build->setStatus(Build::STATUS_SUCCESS);
} else {
$this->build->setStatus(Build::STATUS_FAILED);
@ -214,7 +209,7 @@ class Builder implements LoggerAwareInterface
// Complete stage plugins are always run
$this->pluginExecutor->executePlugins($this->config, 'complete');
if ($this->success) {
if ($success) {
$this->pluginExecutor->executePlugins($this->config, 'success');
$this->buildLogger->logSuccess('BUILD SUCCESSFUL!');
} else {

View file

@ -195,7 +195,7 @@ class InstallCommand extends Command
protected function writeConfigFile(array $config)
{
$dumper = new \Symfony\Component\Yaml\Dumper();
$yaml = $dumper->dump($config);
$yaml = $dumper->dump($config, 2);
file_put_contents(PHPCI_DIR . 'PHPCI/config.yml', $yaml);
}

View file

@ -10,6 +10,8 @@
namespace PHPCI\Controller;
use PHPCI\BuildFactory;
use PHPCI\Helper\Github;
use PHPCI\Helper\SshKey;
use PHPCI\Model\Build;
use PHPCI\Model\Project;
use b8;
@ -145,37 +147,16 @@ class ProjectController extends \PHPCI\Controller
$method = $this->request->getMethod();
if ($method == 'POST') {
$values = $this->getParams();
$pub = null;
} else {
$tempPath = sys_get_temp_dir() . '/';
$pub = null;
$values = $this->getParams();
// FastCGI fix for Windows machines, where temp path is not available to
// PHP, and defaults to the unwritable system directory. If the temp
// path is pointing to the system directory, shift to the 'TEMP'
// sub-folder, which should also exist, but actually be writable.
if ($tempPath == getenv("SystemRoot") . '/') {
$tempPath = getenv("SystemRoot") . '/TEMP/';
}
if ($method != 'POST') {
$sshKey = new SshKey();
$key = $sshKey->generate();
$keyFile = $tempPath . md5(microtime(true));
if (!is_dir($tempPath)) {
mkdir($tempPath);
}
if ($this->canGenerateKeys()) {
shell_exec('ssh-keygen -q -t rsa -b 2048 -f '.$keyFile.' -N "" -C "deploy@phpci"');
$pub = file_get_contents($keyFile . '.pub');
$prv = file_get_contents($keyFile);
$values = array('key' => $prv, 'pubkey' => $pub);
} else {
$pub = null;
$values = array();
}
$values['key'] = $key['private_key'];
$values['pubkey'] = $key['public_key'];
$pub = $key['public_key'];
}
$form = $this->projectForm($values);
@ -351,7 +332,8 @@ class ProjectController extends \PHPCI\Controller
$field = new Form\Element\TextArea('build_config');
$field->setRequired(false);
$field->setLabel('PHPCI build config for this project (if you cannot add a phpci.yml file in the project repository)');
$label = 'PHPCI build config for this project (if you cannot add a phpci.yml file in the project repository)';
$field->setLabel($label);
$field->setClass('form-control');
$field->setContainerClass('form-group');
$field->setRows(6);
@ -380,46 +362,8 @@ class ProjectController extends \PHPCI\Controller
*/
protected function githubRepositories()
{
$token = Config::getInstance()->get('phpci.github.token');
if (!$token) {
die(json_encode(null));
}
$cache = \b8\Cache::getCache(\b8\Cache::TYPE_APC);
$rtn = $cache->get('phpci_github_repos');
if (!$rtn) {
$orgs = $this->doGithubApiRequest('/user/orgs', array('access_token' => $token));
$params = array('type' => 'all', 'access_token' => $token);
$repos = array();
$repos['user'] = $this->doGithubApiRequest('/user/repos', $params);
foreach ($orgs as $org) {
$repos[$org['login']] = $this->doGithubApiRequest('/orgs/'.$org['login'].'/repos', $params);
}
$rtn = array();
foreach ($repos as $repoGroup) {
foreach ($repoGroup as $repo) {
$rtn['repos'][] = $repo['full_name'];
}
}
$cache->set('phpci_github_repos', $rtn);
}
die(json_encode($rtn));
}
protected function doGithubApiRequest($url, $params)
{
$http = new \b8\HttpClient('https://api.github.com');
$res = $http->get($url, $params);
return $res['body'];
$github = new Github();
die(json_encode($github->getRepositories()));
}
protected function getReferenceValidator($values)
@ -459,10 +403,4 @@ class ProjectController extends \PHPCI\Controller
return true;
};
}
protected function canGenerateKeys()
{
$result = @shell_exec('ssh-keygen');
return !empty($result);
}
}

View file

@ -62,7 +62,7 @@ class SettingsController extends Controller
$this->settings['phpci']['github']['secret'] = $this->getParam('githubsecret', '');
$error = $this->storeSettings();
if($error) {
if ($error) {
header('Location: ' . PHPCI_URL . 'settings?saved=2');
} else {
header('Location: ' . PHPCI_URL . 'settings?saved=1');

View file

@ -58,4 +58,4 @@ class BuildInterpolator
$values = array_values($this->interpolation_vars);
return str_replace($keys, $values, $input);
}
}
}

57
PHPCI/Helper/Github.php Normal file
View file

@ -0,0 +1,57 @@
<?php
namespace PHPCI\Helper;
use b8\Cache;
use b8\Config;
use b8\HttpClient;
class Github
{
public function makeRequest($url, $params)
{
$http = new HttpClient('https://api.github.com');
$res = $http->get($url, $params);
return $res['body'];
}
/**
* Get an array of repositories from Github's API.
*/
public function getRepositories()
{
$token = Config::getInstance()->get('phpci.github.token');
if (!$token) {
die(json_encode(null));
}
$cache = Cache::getCache(Cache::TYPE_APC);
$rtn = $cache->get('phpci_github_repos');
if (!$rtn) {
$orgs = $this->makeRequest('/user/orgs', array('access_token' => $token));
$params = array('type' => 'all', 'access_token' => $token);
$repos = array();
$repos['user'] = $this->makeRequest('/user/repos', $params);
foreach ($orgs as $org) {
$repos[$org['login']] = $this->makeRequest('/orgs/'.$org['login'].'/repos', $params);
}
$rtn = array();
foreach ($repos as $repoGroup) {
foreach ($repoGroup as $repo) {
$rtn['repos'][] = $repo['full_name'];
}
}
$cache->set('phpci_github_repos', $rtn);
}
return $rtn;
}
}

View file

@ -3,16 +3,16 @@
namespace PHPCI\Helper;
class MailerFactory {
class MailerFactory
{
/**
* @var array
*/
protected $emailConfig;
public function __construct($phpCiConfig = null)
public function __construct($config = null)
{
$this->emailConfig = isset($phpCiSettings['email_settings']) ?: array();
$this->emailConfig = isset($config['email_settings']) ?: array();
}
/**
@ -33,7 +33,7 @@ class MailerFactory {
return \Swift_Mailer::newInstance($transport);
}
protected function getMailConfig($configName)
protected function getMailConfig($configName)
{
if (isset($this->emailConfig[$configName]) && $this->emailConfig[$configName] != "") {
return $this->emailConfig[$configName];
@ -54,5 +54,4 @@ class MailerFactory {
}
}
}
}
}

46
PHPCI/Helper/SshKey.php Normal file
View file

@ -0,0 +1,46 @@
<?php
namespace PHPCI\Helper;
class SshKey
{
public function generate()
{
$tempPath = sys_get_temp_dir() . '/';
// FastCGI fix for Windows machines, where temp path is not available to
// PHP, and defaults to the unwritable system directory. If the temp
// path is pointing to the system directory, shift to the 'TEMP'
// sub-folder, which should also exist, but actually be writable.
if (IS_WIN && $tempPath == getenv("SystemRoot") . '/') {
$tempPath = getenv("SystemRoot") . '/TEMP/';
}
$keyFile = $tempPath . md5(microtime(true));
if (!is_dir($tempPath)) {
mkdir($tempPath);
}
$return = array();
if ($this->canGenerateKeys()) {
shell_exec('ssh-keygen -q -t rsa -b 2048 -f '.$keyFile.' -N "" -C "deploy@phpci"');
$pub = file_get_contents($keyFile . '.pub');
$prv = file_get_contents($keyFile);
$return = array('private_key' => $prv, 'public_key' => $pub);
}
return $return;
}
public function canGenerateKeys()
{
$keygen = @shell_exec('ssh-keygen');
$canGenerateKeys = !empty($keygen);
return $canGenerateKeys;
}
}

View file

@ -26,12 +26,12 @@ class Handler
*/
protected $logger;
public function __construct(LoggerInterface $logger = NULL)
public function __construct(LoggerInterface $logger = null)
{
$this->logger = $logger;
}
public static function register(LoggerInterface $logger = NULL)
public static function register(LoggerInterface $logger = null)
{
$handler = new static($logger);
@ -57,7 +57,10 @@ class Handler
throw new \ErrorException(
sprintf('%s: %s in %s line %d', $exception_level, $message, $file, $line),
0, $level, $file, $line
0,
$level,
$file,
$line
);
}
}
@ -70,21 +73,37 @@ class Handler
$fatal_error = error_get_last();
try {
if (($e = error_get_last()) !== null) {
$e = new \ErrorException(
sprintf('%s: %s in %s line %d', $fatal_error['type'], $fatal_error['message'], $fatal_error['file'], $fatal_error['line']),
0, $fatal_error['type'], $fatal_error['file'], $fatal_error['line']
if (($error = error_get_last()) !== null) {
$error = new \ErrorException(
sprintf(
'%s: %s in %s line %d',
$fatal_error['type'],
$fatal_error['message'],
$fatal_error['file'],
$fatal_error['line']
),
0,
$fatal_error['type'],
$fatal_error['file'],
$fatal_error['line']
);
$this->log($e);
$this->log($error);
}
}
catch (\Exception $e)
{
$e = new \ErrorException(
sprintf('%s: %s in %s line %d', $fatal_error['type'], $fatal_error['message'], $fatal_error['file'], $fatal_error['line']),
0, $fatal_error['type'], $fatal_error['file'], $fatal_error['line']
} catch (\Exception $e) {
$error = new \ErrorException(
sprintf(
'%s: %s in %s line %d',
$fatal_error['type'],
$fatal_error['message'],
$fatal_error['file'],
$fatal_error['line']
),
0,
$fatal_error['type'],
$fatal_error['file'],
$fatal_error['line']
);
$this->log($e);
$this->log($error);
}
}
@ -101,9 +120,14 @@ class Handler
if (null !== $this->logger) {
$message = sprintf(
'%s: %s (uncaught exception) at %s line %s', get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine()
'%s: %s (uncaught exception) at %s line %s',
get_class($exception),
$exception->getMessage(),
$exception->getFile(),
$exception->getLine()
);
$this->logger->error($message, array('exception' => $exception));
}
}
}
}

View file

@ -28,6 +28,4 @@ class OutputLogHandler extends AbstractProcessingHandler
{
$this->output->writeln((string)$record['formatted']);
}
}

View file

@ -631,31 +631,4 @@ class BuildBase extends Model
{
return Factory::getStore('BuildMeta', 'PHPCI')->getByBuildId($this->getId());
}
public static function getByPrimaryKey($value, $useConnection = 'read')
{
return Factory::getStore('Build', 'PHPCI')->getByPrimaryKey($value, $useConnection);
}
public static function getById($value, $useConnection = 'read')
{
return Factory::getStore('Build', 'PHPCI')->getById($value, $useConnection);
}
public static function getByProjectId($value, $limit = null, $useConnection = 'read')
{
return Factory::getStore('Build', 'PHPCI')->getByProjectId($value, $limit, $useConnection);
}
public static function getByStatus($value, $limit = null, $useConnection = 'read')
{
return Factory::getStore('Build', 'PHPCI')->getByStatus($value, $limit, $useConnection);
}
}

View file

@ -337,26 +337,4 @@ class BuildMetaBase extends Model
{
return $this->setBuildId($value->getId());
}
public static function getByPrimaryKey($value, $useConnection = 'read')
{
return Factory::getStore('BuildMeta', 'PHPCI')->getByPrimaryKey($value, $useConnection);
}
public static function getById($value, $useConnection = 'read')
{
return Factory::getStore('BuildMeta', 'PHPCI')->getById($value, $useConnection);
}
public static function getByBuildId($value, $limit = null, $useConnection = 'read')
{
return Factory::getStore('BuildMeta', 'PHPCI')->getByBuildId($value, $limit, $useConnection);
}
}

View file

@ -516,26 +516,4 @@ class ProjectBase extends Model
{
return Factory::getStore('Build', 'PHPCI')->getByProjectId($this->getId());
}
public static function getByPrimaryKey($value, $useConnection = 'read')
{
return Factory::getStore('Project', 'PHPCI')->getByPrimaryKey($value, $useConnection);
}
public static function getById($value, $useConnection = 'read')
{
return Factory::getStore('Project', 'PHPCI')->getById($value, $useConnection);
}
public static function getByTitle($value, $limit = null, $useConnection = 'read')
{
return Factory::getStore('Project', 'PHPCI')->getByTitle($value, $limit, $useConnection);
}
}

View file

@ -273,26 +273,4 @@ class UserBase extends Model
$this->_setModified('name');
}
public static function getByPrimaryKey($value, $useConnection = 'read')
{
return Factory::getStore('User', 'PHPCI')->getByPrimaryKey($value, $useConnection);
}
public static function getById($value, $useConnection = 'read')
{
return Factory::getStore('User', 'PHPCI')->getById($value, $useConnection);
}
public static function getByEmail($value, $useConnection = 'read')
{
return Factory::getStore('User', 'PHPCI')->getByEmail($value, $useConnection);
}
}

View file

@ -98,7 +98,9 @@ class GithubBuild extends RemoteGitBuild
{
$rtn = $this->data['commit_message'];
$rtn = preg_replace('/\#([0-9]+)/', '<a target="_blank" href="https://github.com/' . $this->getProject()->getReference() . '/issues/$1">#$1</a>', $rtn);
$reference = $this->getProject()->getReference();
$commitLink = '<a target="_blank" href="https://github.com/' . $reference . '/issues/$1">#$1</a>';
$rtn = preg_replace('/\#([0-9]+)/', $commitLink, $rtn);
$rtn = preg_replace('/\@([a-zA-Z0-9_]+)/', '<a target="_blank" href="https://github.com/$1">@$1</a>', $rtn);
return $rtn;

View file

@ -43,10 +43,11 @@ class GitlabBuild extends RemoteGitBuild
*/
public function getFileLinkTemplate()
{
return sprintf('http://%s/%s/blob/%s/{FILE}#L{LINE}',
$this->getProject()->getAccessInformation("domain"),
$this->getProject()->getReference(),
$this->getBranch()
return sprintf(
'http://%s/%s/blob/%s/{FILE}#L{LINE}',
$this->getProject()->getAccessInformation("domain"),
$this->getProject()->getReference(),
$this->getBranch()
);
}

View file

@ -60,7 +60,8 @@ 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 %3$s | tar -x -C "%2$s"', $reference, $buildPath, $this->getBranch());
$cmd = 'mkdir %2$s; git --git-dir="%1$s" archive %3$s | tar -x -C "%2$s"';
$builder->executeCommand($cmd, $reference, $buildPath, $this->getBranch());
return true;
}

View file

@ -54,7 +54,8 @@ class RemoteGitBuild extends Build
*/
protected function cloneByHttp(Builder $builder, $cloneTo)
{
$success = $builder->executeCommand('git clone -b %s %s "%s"', $this->getBranch(), $this->getCloneUrl(), $cloneTo);
$cmd = 'git clone -b %s %s "%s"';
$success = $builder->executeCommand($cmd, $this->getBranch(), $this->getCloneUrl(), $cloneTo);
if (!empty($commit) && $commit != 'Manual') {
$cmd = 'cd "%s" && git checkout %s';
@ -136,10 +137,12 @@ class RemoteGitBuild extends Build
$path = dirname($cloneTo . '/temp');
$wrapperFile = $path . '.sh';
$sshFlags = '-o CheckHostIP=no -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o PasswordAuthentication=no';
// Write out the wrapper script for this build:
$script = <<<OUT
#!/bin/sh
ssh -o CheckHostIP=no -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o IdentityFile={$keyFile} $*
ssh {$sshFlags} -o IdentityFile={$keyFile} $*
OUT;

View file

@ -21,11 +21,13 @@ use PHPCI\Model\Build;
class Behat implements \PHPCI\Plugin
{
protected $phpci;
protected $build;
protected $features;
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->phpci = $phpci;
$this->build = $build;
$this->features = '';
if (isset($options['executable'])) {

View file

@ -23,10 +23,12 @@ class CleanBuild implements \PHPCI\Plugin
{
protected $remove;
protected $phpci;
protected $build;
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->phpci = $phpci;
$this->build = $build;
$this->remove = isset($options['remove']) && is_array($options['remove']) ? $options['remove'] : array();
}

View file

@ -30,6 +30,8 @@ class Codeception implements \PHPCI\Plugin
*/
protected $phpci;
protected $build;
/**
* @var string|string[] $xmlConfigFile The path (or array of paths) of an xml config for PHPUnit
*/
@ -38,6 +40,7 @@ class Codeception implements \PHPCI\Plugin
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->phpci = $phpci;
$this->build = $build;
if (isset($options['config'])) {
$this->xmlConfigFile = $options['config'];
@ -79,7 +82,9 @@ class Codeception implements \PHPCI\Plugin
if (IS_WIN) {
$cmd = 'cd /d "%s" && ' . $codecept . ' run -c "%s" '. $this->args;
}
$success = $this->phpci->executeCommand($cmd, $this->phpci->buildPath, $this->phpci->buildPath . $configPath);
$configPath = $this->phpci->buildPath . $configPath;
$success = $this->phpci->executeCommand($cmd, $this->phpci->buildPath, $configPath);
return $success;
}

View file

@ -25,6 +25,7 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
protected $action;
protected $preferDist;
protected $phpci;
protected $build;
public static function canExecute($stage, Builder $builder, Build $build)
{
@ -41,8 +42,9 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
{
$path = $phpci->buildPath;
$this->phpci = $phpci;
$this->build = $build;
$this->directory = isset($options['directory']) ? $path . '/' . $options['directory'] : $path;
$this->action = isset($options['action']) ? $options['action'] : 'update';
$this->action = isset($options['action']) ? $options['action'] : 'install';
$this->preferDist = isset($options['prefer_dist']) ? $options['prefer_dist'] : true;
}

View file

@ -23,11 +23,13 @@ class CopyBuild implements \PHPCI\Plugin
protected $directory;
protected $ignore;
protected $phpci;
protected $build;
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$path = $phpci->buildPath;
$this->phpci = $phpci;
$this->build = $build;
$this->directory = isset($options['directory']) ? $options['directory'] : $path;
$this->ignore = isset($options['respect_ignore']) ? (bool)$options['respect_ignore'] : false;
}

View file

@ -46,7 +46,6 @@ class Email implements \PHPCI\Plugin
Build $build,
\Swift_Mailer $mailer,
array $options = array()
) {
$this->phpci = $phpci;
$this->build = $build;

View file

@ -21,11 +21,13 @@ use PHPCI\Model\Build;
class Env implements \PHPCI\Plugin
{
protected $phpci;
protected $build;
protected $env_vars;
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->phpci = $phpci;
$this->phpci = $phpci;
$this->build = $build;
$this->env_vars = $options;
}

View file

@ -31,7 +31,6 @@ class Git implements \PHPCI\Plugin
$this->actions = $options;
}
public function execute()
{
$buildPath = $this->phpci->buildPath;
@ -58,68 +57,80 @@ class Git implements \PHPCI\Plugin
return $success;
}
protected function runAction($action, $options = array())
protected function runAction($action, array $options = array())
{
// If options isn't an array, it should be.
if (!is_array($options)) {
$options = array();
switch ($action) {
case 'merge':
return $this->runMergeAction($options);
case 'tag':
return $this->runTagAction($options);
case 'pull':
return $this->runPullAction($options);
case 'push':
return $this->runPushAction($options);
}
// Handle git merges.
if ($action == 'merge' && array_key_exists('branch', $options)) {
$cmd = 'git checkout %s && git merge ' . $this->build->getBranch();
return $this->phpci->executeCommand($cmd, $this->directory, $options['branch']);
}
// Handle tagging:
if ($action == 'tag') {
$tagName = date('Ymd-His');
$message = 'Tag created by PHPCI: ' . date('Y-m-d H:i:s');
if (array_key_exists('name', $options)) {
$tagName = $this->phpci->interpolate($options['name']);
}
if (array_key_exists('message', $options)) {
$message = $this->phpci->interpolate($options['message']);
}
$cmd = 'git tag %s -m "%s"';
return $this->phpci->executeCommand($cmd, $tagName, $message);
}
// Handle pull:
if ($action == 'pull') {
$branch = $this->build->getBranch();
$remote = 'origin';
if (array_key_exists('branch', $options)) {
$branch = $this->phpci->interpolate($options['branch']);
}
if (array_key_exists('remote', $options)) {
$remote = $this->phpci->interpolate($options['remote']);
}
return $this->phpci->executeCommand('git pull %s %s', $remote, $branch);
}
// Handle push:
if ($action == 'push') {
$branch = $this->build->getBranch();
$remote = 'origin';
if (array_key_exists('branch', $options)) {
$branch = $this->phpci->interpolate($options['branch']);
}
if (array_key_exists('remote', $options)) {
$remote = $this->phpci->interpolate($options['remote']);
}
return $this->phpci->executeCommand('git push %s %s', $remote, $branch);
}
return false;
}
protected function runMergeAction($options)
{
if (array_key_exists('branch', $options)) {
$cmd = 'git checkout %s && git merge ' . $this->build->getBranch();
return $this->phpci->executeCommand($cmd, $this->directory, $options['branch']);
}
}
protected function runTagAction($options)
{
$tagName = date('Ymd-His');
$message = 'Tag created by PHPCI: ' . date('Y-m-d H:i:s');
if (array_key_exists('name', $options)) {
$tagName = $this->phpci->interpolate($options['name']);
}
if (array_key_exists('message', $options)) {
$message = $this->phpci->interpolate($options['message']);
}
$cmd = 'git tag %s -m "%s"';
return $this->phpci->executeCommand($cmd, $tagName, $message);
}
protected function runPullAction($options)
{
$branch = $this->build->getBranch();
$remote = 'origin';
if (array_key_exists('branch', $options)) {
$branch = $this->phpci->interpolate($options['branch']);
}
if (array_key_exists('remote', $options)) {
$remote = $this->phpci->interpolate($options['remote']);
}
return $this->phpci->executeCommand('git pull %s %s', $remote, $branch);
}
protected function runPushAction($options)
{
$branch = $this->build->getBranch();
$remote = 'origin';
if (array_key_exists('branch', $options)) {
$branch = $this->phpci->interpolate($options['branch']);
}
if (array_key_exists('remote', $options)) {
$remote = $this->phpci->interpolate($options['remote']);
}
return $this->phpci->executeCommand('git push %s %s', $remote, $branch);
}
}

View file

@ -24,12 +24,14 @@ class Grunt implements \PHPCI\Plugin
protected $task;
protected $preferDist;
protected $phpci;
protected $build;
protected $grunt;
protected $gruntfile;
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$path = $phpci->buildPath;
$this->build = $build;
$this->phpci = $phpci;
$this->directory = $path;
$this->task = null;

View file

@ -13,16 +13,18 @@ use PHPCI\Model\Build;
*/
class Irc implements \PHPCI\Plugin
{
private $phpci;
private $message;
private $server;
private $port;
private $room;
private $nick;
protected $phpci;
protected $build;
protected $message;
protected $server;
protected $port;
protected $room;
protected $nick;
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->phpci = $phpci;
$this->build = $build;
$this->message = $options['message'];
$buildSettings = $phpci->getConfig('build_settings');

View file

@ -25,10 +25,12 @@ class Lint implements PHPCI\Plugin
protected $recursive = true;
protected $ignore;
protected $phpci;
protected $build;
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->phpci = $phpci;
$this->build = $build;
$this->directories = array('');
$this->ignore = $phpci->ignore;

View file

@ -27,6 +27,7 @@ class Mysql implements \PHPCI\Plugin
* @var \PHPCI\Builder
*/
protected $phpci;
protected $build;
protected $queries = array();
protected $host;
@ -42,6 +43,8 @@ class Mysql implements \PHPCI\Plugin
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->phpci = $phpci;
$this->build = $build;
$this->queries = $options;
$config = \b8\Database::getConnection('write')->getDetails();

View file

@ -22,6 +22,7 @@ use PHPCI\Model\Build;
class Pgsql implements \PHPCI\Plugin
{
protected $phpci;
protected $build;
protected $queries = array();
protected $host;
@ -30,13 +31,14 @@ class Pgsql implements \PHPCI\Plugin
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->phpci = $phpci;
$this->queries = $options;
$this->phpci = $phpci;
$this->build = $build;
$this->queries = $options;
$buildSettings = $phpci->getConfig('build_settings');
if (isset($buildSettings['pgsql'])) {
$sql = $buildSettings['pgsql'];
$sql = $buildSettings['pgsql'];
$this->host = $sql['host'];
$this->user = $sql['user'];
$this->pass = $sql['pass'];

View file

@ -29,10 +29,12 @@ class Phing implements \PHPCI\Plugin
private $propertyFile;
protected $phpci;
protected $build;
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->setPhpci($phpci);
$this->build = $build;
/*
* Set working directory

View file

@ -23,6 +23,7 @@ class PhpCpd implements \PHPCI\Plugin
protected $directory;
protected $args;
protected $phpci;
protected $build;
/**
* @var string, based on the assumption the root may not hold the code to be
@ -38,6 +39,8 @@ class PhpCpd implements \PHPCI\Plugin
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->phpci = $phpci;
$this->build = $build;
$this->path = $phpci->buildPath;
$this->standard = 'PSR1';
$this->ignore = $phpci->ignore;

View file

@ -20,8 +20,16 @@ use PHPCI\Model\Build;
*/
class PhpCsFixer implements \PHPCI\Plugin
{
/**
* @var \PHPCI\Builder
*/
protected $phpci;
/**
* @var \PHPCI\Model\Build
*/
protected $build;
protected $workingDir = '';
protected $level = ' --level=all';
protected $verbose = '';
@ -31,6 +39,8 @@ class PhpCsFixer implements \PHPCI\Plugin
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->phpci = $phpci;
$this->build = $build;
$this->workingdir = $this->phpci->buildPath;
$this->buildArgs($options);
}

View file

@ -26,6 +26,11 @@ class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
*/
protected $phpci;
/**
* @var \PHPCI\Model\Build
*/
protected $build;
/**
* @var array
*/
@ -59,10 +64,7 @@ class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
return false;
}
/**
* @param \PHPCI\Builder $phpci
* @param array $options
*/
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->phpci = $phpci;

View file

@ -21,11 +21,26 @@ use PHPCI\Model\Build;
*/
class PhpSpec implements PHPCI\Plugin
{
/**
* @var \PHPCI\Builder
*/
protected $phpci;
/**
* @var \PHPCI\Model\Build
*/
protected $build;
/**
* @var array
*/
protected $options;
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->phpci = $phpci;
$this->phpci = $phpci;
$this->build = $build;
$this->options = $options;
}
/**

View file

@ -12,6 +12,7 @@ namespace PHPCI\Plugin;
use PHPCI;
use PHPCI\Builder;
use PHPCI\Model\Build;
use PHPCI\Plugin\Util\TapParser;
/**
* PHP Unit Plugin - Allows PHP Unit testing.
@ -23,6 +24,7 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
{
protected $args;
protected $phpci;
protected $build;
/**
* @var string|string[] $directory The directory (or array of dirs) to run PHPUnit on
@ -58,20 +60,20 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
public static function findConfigFile($buildPath)
{
if (file_exists($buildPath . '/phpunit.xml')) {
return $buildPath . '/phpunit.xml';
if (file_exists($buildPath . 'phpunit.xml')) {
return 'phpunit.xml';
}
if (file_exists($buildPath . '/tests/phpunit.xml')) {
return $buildPath . '/tests/phpunit.xml';
if (file_exists($buildPath . 'tests/phpunit.xml')) {
return 'tests/phpunit.xml';
}
if (file_exists($buildPath . '/phpunit.xml.dist')) {
return $buildPath . '/phpunit.xml.dist';
if (file_exists($buildPath . 'phpunit.xml.dist')) {
return 'phpunit.xml.dist';
}
if (file_exists($buildPath . '/tests/phpunit.xml.dist')) {
return $buildPath . '/tests/phpunit.xml.dist';
if (file_exists($buildPath . 'tests/phpunit.xml.dist')) {
return 'tests/phpunit.xml.dist';
}
return null;
@ -80,9 +82,9 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->phpci = $phpci;
$this->build = $build;
if (!count($options)) {
$this->runFrom = $phpci->buildPath;
if (empty($options['config']) && empty($options['directory'])) {
$this->xmlConfigFile = self::findConfigFile($phpci->buildPath);
}
@ -118,6 +120,8 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
{
$success = true;
$this->phpci->logExecOutput(false);
// Run any config files first. This can be either a single value or an array.
if ($this->xmlConfigFile !== null) {
$success &= $this->runConfigFile($this->xmlConfigFile);
@ -128,6 +132,16 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
$success &= $this->runDir($this->directory);
}
$output = $this->phpci->getLastOutput();
$tapParser = new TapParser($output);
$output = $tapParser->parse();
$failures = $tapParser->getTotalFailures();
$this->build->storeMeta('phpunit-errors', $failures);
$this->build->storeMeta('phpunit-data', $output);
$this->phpci->logExecOutput(true);
return $success;
}
@ -150,7 +164,7 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
}
$cmd = $phpunit . ' %s -c "%s" ' . $this->coverage . $this->path;
$cmd = $phpunit . ' --tap %s -c "%s" ' . $this->coverage . $this->path;
$success = $this->phpci->executeCommand($cmd, $this->args, $this->phpci->buildPath . $configPath);
if ($this->runFrom) {
@ -176,7 +190,7 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
return false;
}
$cmd = $phpunit . ' %s "%s"';
$cmd = $phpunit . ' --tap %s "%s"';
$success = $this->phpci->executeCommand($cmd, $this->args, $this->phpci->buildPath . $dirPath);
chdir($curdir);
return $success;

View file

@ -20,9 +20,18 @@ use PHPCI\Model\Build;
*/
class Shell implements \PHPCI\Plugin
{
protected $args;
/**
* @var \PHPCI\Builder
*/
protected $phpci;
/**
* @var \PHPCI\Model\Build
*/
protected $build;
protected $args;
/**
* @var string[] $commands The commands to be executed
*/
@ -30,7 +39,8 @@ class Shell implements \PHPCI\Plugin
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$this->phpci = $phpci;
$this->phpci = $phpci;
$this->build = $build;
if (isset($options['command'])) {
// Keeping this for backwards compatibility, new projects should use interpolation vars.

View file

@ -6,7 +6,6 @@ use \PHPCI\Logging\BuildLogger;
class Executor
{
/**
* @var BuildLogger
*/
@ -103,5 +102,4 @@ class Executor
return $rtn;
}
}

View file

@ -44,5 +44,4 @@ class PluginInformationCollection implements InstalledPluginInformation
}
return $arr;
}
}

View file

@ -0,0 +1,100 @@
<?php
namespace PHPCI\Plugin\Util;
class TapParser
{
const TEST_COUNTS_PATTERN = '/([0-9]+)\.\.([0-9]+)/';
const TEST_LINE_PATTERN = '/(ok|not ok)\s+[0-9]+\s+\-\s+([^\n]+)::([^\n]+)/';
const TEST_MESSAGE_PATTERN = '/message\:\s+\'([^\']+)\'/';
/**
* @var string
*/
protected $tapString;
protected $failures = 0;
/**
* Create a new TAP parser for a given string.
* @param string $tapString The TAP format string to be parsed.
*/
public function __construct($tapString)
{
$this->tapString = trim($tapString);
}
/**
* Parse a given TAP format string and return an array of tests and their status.
*/
public function parse()
{
// Split up the TAP string into an array of lines, then
// trim all of the lines so there's no leading or trailing whitespace.
$lines = explode("\n", $this->tapString);
$lines = array_map(function ($line) {
return trim($line);
}, $lines);
// Check TAP version:
$versionLine = array_shift($lines);
if ($versionLine != 'TAP version 13') {
throw new \Exception('TapParser only supports TAP version 13');
}
$matches = array();
$totalTests = 0;
if (preg_match(self::TEST_COUNTS_PATTERN, $lines[0], $matches)) {
array_shift($lines);
$totalTests = (int)$matches[2];
}
if (preg_match(self::TEST_COUNTS_PATTERN, $lines[count($lines) - 1], $matches)) {
array_pop($lines);
$totalTests = (int)$matches[2];
}
$rtn = $this->processTestLines($lines);
if ($totalTests != count($rtn)) {
throw new \Exception('Invalid TAP string, number of tests does not match specified test count.');
}
return $rtn;
}
protected function processTestLines($lines)
{
$rtn = array();
foreach ($lines as $line) {
$matches = array();
if (preg_match(self::TEST_LINE_PATTERN, $line, $matches)) {
$ok = ($matches[1] == 'ok' ? true : false);
if (!$ok) {
$this->failures++;
}
$item = array(
'pass' => $ok,
'suite' => $matches[2],
'test' => $matches[3],
);
$rtn[] = $item;
} elseif (preg_match(self::TEST_MESSAGE_PATTERN, $line, $matches)) {
$rtn[count($rtn) - 1]['message'] = $matches[1];
}
}
return $rtn;
}
public function getTotalFailures()
{
return $this->failures;
}
}

View file

@ -20,13 +20,24 @@ use PHPCI\Model\Build;
*/
class Wipe implements \PHPCI\Plugin
{
protected $directory;
/**
* @var \PHPCI\Builder
*/
protected $phpci;
/**
* @var \PHPCI\Model\Build
*/
protected $build;
protected $directory;
public function __construct(Builder $phpci, Build $build, array $options = array())
{
$path = $phpci->buildPath;
$this->phpci = $phpci;
$this->build = $build;
$this->directory = isset($options['directory']) ? $options['directory'] : $path;
}

View file

@ -1,4 +1,3 @@
<h1><i class="glyphicon glyphicon-th-list"></i> <?php print htmlspecialchars($project->getTitle()); ?></h1>
@ -19,7 +18,7 @@
</div>
</div>
<?php if (in_array($project->getType(), array('github', 'gitlab','bitbucket'))): ?>
<?php if (in_array($project->getType(), array('github', 'gitlab', 'bitbucket'))): ?>
<div class="panel panel-info">
<div class="panel-heading">
<h4 class="panel-title">Webhooks</h4>
@ -27,7 +26,6 @@
<div class="panel-body">
To automatically build this project when new commits are pushed, add the URL below
<?php endif; ?>
<?php
switch($project->getType())
@ -50,6 +48,7 @@
?>
</div>
</div>
<?php endif; ?>
<?php if ($project->getPublicKey()): ?>
<div class="panel panel-default">

View file

@ -7,7 +7,7 @@ _**Please be aware that PHPCI is a beta-release project, so whilst it is very st
**Current Build Status**
![Build Status](http://phpci.block8.net/build-status/image/2)
[![Build Status](http://phpci.block8.net/build-status/image/2)](http://phpci.block8.net/build-status/view/2)
##What it does:
* Clones your project from Github, Bitbucket or a local path

View file

@ -42,7 +42,7 @@ class CommandExecutorTest extends ProphecyTestCase
public function testExecuteCommand_ReturnsFalseForInvalidCommands()
{
$returnValue = $this->testedExecutor->buildAndExecuteCommand(array('eerfdcvcho "%s"', 'Hello World'));
$returnValue = $this->testedExecutor->buildAndExecuteCommand(array('eerfdcvcho "%s" > /dev/null 2>&1', 'Hello World'));
$this->assertFalse($returnValue);
}

View file

@ -1,172 +0,0 @@
<?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\Plugin\Tests;
use PHPCI\Plugin\PhpUnit;
/**
* Unit test for the PHPUnit plugin.
* @author meadsteve
*/
class PHPUnitTest extends \PHPUnit_Framework_TestCase
{
/**
* @var PhpUnit $testedPhpUnit
*/
protected $testedPhpUnit;
/**
* @var \PHPUnit_Framework_MockObject_MockObject $mockCiBuilder
*/
protected $mockCiBuilder;
/**
* @var \PHPUnit_Framework_MockObject_MockObject $mockCiBuilder
*/
protected $mockBuild;
public function setUp()
{
$this->mockCiBuilder = $this->getMock(
'\PHPCI\Builder',
array('findBinary', 'executeCommand'),
array(),
"mockBuilder_phpUnit",
false
);
$this->mockCiBuilder->buildPath = "/";
$this->mockBuild = $this->getMock(
'\PHPCI\Model\Build',
array(),
array(),
"MockBuild",
false
);
$this->loadPhpUnitWithOptions();
}
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)
{
$this->mockCiBuilder->expects($expectation)
->method("findBinary")
->will($this->returnValue("phpunit"));
}
/**
* @param \PHPUnit_Framework_MockObject_Matcher_Invocation $expectation
*/
public function expectExectuteCommandToBeCalled($expectation)
{
$this->mockCiBuilder->expects($expectation)
->method("executeCommand");
}
/**
* @covers PHPUnit::execute
*/
public function testExecute_ReturnsTrueWithoutArgs()
{
$returnValue = $this->testedPhpUnit->execute();
$expectedReturn = true;
$this->assertEquals($expectedReturn, $returnValue);
}
/**
* @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->expectFindBinaryToBeCalled($this->once());
$this->expectExectuteCommandToBeCalled($this->once());
$returnValue = $this->testedPhpUnit->execute();
}
/**
* @covers PHPUnit::execute
* @covers PHPUnit::runDir
*/
public function testExecute_CallsExecuteCommandManyTimesWhenGivenArrayDirectory()
{
chdir('/');
$this->loadPhpUnitWithOptions(
array(
'directory' => array("dir1", "dir2")
)
);
$this->expectFindBinaryToBeCalled($this->exactly(2));
$this->expectExectuteCommandToBeCalled($this->exactly(2));
$returnValue = $this->testedPhpUnit->execute();
}
/**
* @covers PHPUnit::execute
* @covers PHPUnit::runConfigFile
*/
public function testExecute_CallsExecuteCommandManyTimesWhenGivenArrayConfig()
{
chdir('/');
$this->loadPhpUnitWithOptions(
array(
'config' => array("configfile1.xml", "configfile2.xml")
)
);
$this->expectFindBinaryToBeCalled($this->exactly(2));
$this->expectExectuteCommandToBeCalled($this->exactly(2));
$returnValue = $this->testedPhpUnit->execute();
}
}

View file

@ -53,4 +53,4 @@
"jakub-onderka/php-parallel-lint": "Parallel Linting Tool",
"behat/behat": "Behat BDD Testing"
}
}
}

508
composer.lock generated
View file

@ -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": "0ac85acececb32f472d8aa807ed054e7",
"hash": "d6834b50e3ea80f4c6f0a05707d0e5f1",
"packages": [
{
"name": "block8/b8framework",
@ -93,16 +93,16 @@
},
{
"name": "monolog/monolog",
"version": "1.8.0",
"version": "1.9.1",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "392ef35fd470638e08d0160d6b1cbab63cb23174"
"reference": "65026b610f8c19e61d7242f600530677b0466aac"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/392ef35fd470638e08d0160d6b1cbab63cb23174",
"reference": "392ef35fd470638e08d0160d6b1cbab63cb23174",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/65026b610f8c19e61d7242f600530677b0466aac",
"reference": "65026b610f8c19e61d7242f600530677b0466aac",
"shasum": ""
},
"require": {
@ -130,7 +130,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.8.x-dev"
"dev-master": "1.9.x-dev"
}
},
"autoload": {
@ -157,7 +157,7 @@
"logging",
"psr-3"
],
"time": "2014-03-23 19:50:26"
"time": "2014-04-24 13:29:03"
},
{
"name": "pimple/pimple",
@ -298,17 +298,17 @@
},
{
"name": "symfony/console",
"version": "v2.4.3",
"version": "v2.4.4",
"target-dir": "Symfony/Component/Console",
"source": {
"type": "git",
"url": "https://github.com/symfony/Console.git",
"reference": "ef20f1f58d7f693ee888353962bd2db336e3bbcb"
"reference": "2e452005b1e1d003d23702d227e23614679eb5ca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Console/zipball/ef20f1f58d7f693ee888353962bd2db336e3bbcb",
"reference": "ef20f1f58d7f693ee888353962bd2db336e3bbcb",
"url": "https://api.github.com/repos/symfony/Console/zipball/2e452005b1e1d003d23702d227e23614679eb5ca",
"reference": "2e452005b1e1d003d23702d227e23614679eb5ca",
"shasum": ""
},
"require": {
@ -349,21 +349,21 @@
],
"description": "Symfony Console Component",
"homepage": "http://symfony.com",
"time": "2014-03-01 17:35:04"
"time": "2014-04-27 13:34:57"
},
{
"name": "symfony/yaml",
"version": "v2.4.3",
"version": "v2.4.4",
"target-dir": "Symfony/Component/Yaml",
"source": {
"type": "git",
"url": "https://github.com/symfony/Yaml.git",
"reference": "77a41c2835ab7cfe8bf6d15e25d3af8f3eb3bacd"
"reference": "65539ecde838f9c0d18b006b2101e3deb4b5c9ff"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Yaml/zipball/77a41c2835ab7cfe8bf6d15e25d3af8f3eb3bacd",
"reference": "77a41c2835ab7cfe8bf6d15e25d3af8f3eb3bacd",
"url": "https://api.github.com/repos/symfony/Yaml/zipball/65539ecde838f9c0d18b006b2101e3deb4b5c9ff",
"reference": "65539ecde838f9c0d18b006b2101e3deb4b5c9ff",
"shasum": ""
},
"require": {
@ -398,10 +398,482 @@
],
"description": "Symfony Yaml Component",
"homepage": "http://symfony.com",
"time": "2014-03-12 18:29:58"
"time": "2014-04-18 20:37:09"
}
],
"packages-dev": [
{
"name": "phpspec/prophecy",
"version": "1.1.2",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
"reference": "976a65af02a2a0e17ce6c949f7b43437205628bb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/976a65af02a2a0e17ce6c949f7b43437205628bb",
"reference": "976a65af02a2a0e17ce6c949f7b43437205628bb",
"shasum": ""
},
"require-dev": {
"phpspec/phpspec": "2.0.*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.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": "2014-01-24 11:03:43"
},
{
"name": "phpspec/prophecy-phpunit",
"version": "v1.0.1",
"target-dir": "Prophecy/PhpUnit",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy-phpunit.git",
"reference": "640c8c3bc9e02d7878e5ed22b1f79818d6bb6caf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/640c8c3bc9e02d7878e5ed22b1f79818d6bb6caf",
"reference": "640c8c3bc9e02d7878e5ed22b1f79818d6bb6caf",
"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": "2014-03-03 23:03:12"
},
{
"name": "phpunit/php-code-coverage",
"version": "1.2.17",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "6ef2bf3a1c47eca07ea95f0d8a902a6340390b34"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6ef2bf3a1c47eca07ea95f0d8a902a6340390b34",
"reference": "6ef2bf3a1c47eca07ea95f0d8a902a6340390b34",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"phpunit/php-file-iterator": ">=1.3.0@stable",
"phpunit/php-text-template": ">=1.2.0@stable",
"phpunit/php-token-stream": ">=1.1.3@stable"
},
"require-dev": {
"phpunit/phpunit": "3.7.*@dev"
},
"suggest": {
"ext-dom": "*",
"ext-xdebug": ">=2.0.5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
}
},
"autoload": {
"classmap": [
"PHP/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
"homepage": "https://github.com/sebastianbergmann/php-code-coverage",
"keywords": [
"coverage",
"testing",
"xunit"
],
"time": "2014-03-28 10:53:45"
},
{
"name": "phpunit/php-file-iterator",
"version": "1.3.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
"reference": "acd690379117b042d1c8af1fafd61bde001bf6bb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb",
"reference": "acd690379117b042d1c8af1fafd61bde001bf6bb",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"autoload": {
"classmap": [
"File/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "FilterIterator implementation that filters files based on a list of suffixes.",
"homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
"keywords": [
"filesystem",
"iterator"
],
"time": "2013-10-10 15:34:57"
},
{
"name": "phpunit/php-text-template",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-text-template.git",
"reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
"reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"autoload": {
"classmap": [
"Text/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Simple template engine.",
"homepage": "https://github.com/sebastianbergmann/php-text-template/",
"keywords": [
"template"
],
"time": "2014-01-30 17:20:04"
},
{
"name": "phpunit/php-timer",
"version": "1.0.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-timer.git",
"reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
"reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"autoload": {
"classmap": [
"PHP/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Utility class for timing",
"homepage": "https://github.com/sebastianbergmann/php-timer/",
"keywords": [
"timer"
],
"time": "2013-08-02 07:42:54"
},
{
"name": "phpunit/php-token-stream",
"version": "1.2.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
"reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ad4e1e23ae01b483c16f600ff1bebec184588e32",
"reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2-dev"
}
},
"autoload": {
"classmap": [
"PHP/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Wrapper around PHP's tokenizer extension.",
"homepage": "https://github.com/sebastianbergmann/php-token-stream/",
"keywords": [
"tokenizer"
],
"time": "2014-03-03 05:10:30"
},
{
"name": "phpunit/phpunit",
"version": "3.7.37",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "ae6cefd7cc84586a5ef27e04bae11ee940ec63dc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ae6cefd7cc84586a5ef27e04bae11ee940ec63dc",
"reference": "ae6cefd7cc84586a5ef27e04bae11ee940ec63dc",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-dom": "*",
"ext-json": "*",
"ext-pcre": "*",
"ext-reflection": "*",
"ext-spl": "*",
"php": ">=5.3.3",
"phpunit/php-code-coverage": "~1.2",
"phpunit/php-file-iterator": "~1.3",
"phpunit/php-text-template": "~1.1",
"phpunit/php-timer": "~1.0",
"phpunit/phpunit-mock-objects": "~1.2",
"symfony/yaml": "~2.0"
},
"require-dev": {
"pear-pear.php.net/pear": "1.9.4"
},
"suggest": {
"phpunit/php-invoker": "~1.1"
},
"bin": [
"composer/bin/phpunit"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.7.x-dev"
}
},
"autoload": {
"classmap": [
"PHPUnit/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
"",
"../../symfony/yaml/"
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"description": "The PHP Unit Testing framework.",
"homepage": "http://www.phpunit.de/",
"keywords": [
"phpunit",
"testing",
"xunit"
],
"time": "2014-04-30 12:24:19"
},
{
"name": "phpunit/phpunit-mock-objects",
"version": "1.2.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
"reference": "5794e3c5c5ba0fb037b11d8151add2a07fa82875"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/5794e3c5c5ba0fb037b11d8151add2a07fa82875",
"reference": "5794e3c5c5ba0fb037b11d8151add2a07fa82875",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"phpunit/php-text-template": ">=1.1.1@stable"
},
"suggest": {
"ext-soap": "*"
},
"type": "library",
"autoload": {
"classmap": [
"PHPUnit/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Mock Object library for PHPUnit",
"homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
"keywords": [
"mock",
"xunit"
],
"time": "2013-01-13 10:24:48"
}
],
"packages-dev": null,
"aliases": [
],

View file

@ -6,12 +6,17 @@ build_settings:
- "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)
setup:
composer:
action: "install"
test:
php_mess_detector:
allowed_warnings: 35 # Set max warnings at the current level - Disallow any further errors creeping in.
allowed_warnings: 10 # Set max warnings at the current level - Disallow any further errors creeping in.
php_code_sniffer:
standard: "PSR2"
php_loc:
php_unit:
failure:
email:

View file

@ -0,0 +1,65 @@
var phpunitPlugin = PHPCI.UiPlugin.extend({
id: 'build-phpunit-errors',
css: 'col-lg-12 col-md-12 col-sm-12 col-xs-12',
title: 'PHPUnit',
lastData: null,
displayOnUpdate: false,
box: true,
register: function() {
var self = this;
var query = PHPCI.registerQuery('phpunit-data', -1, {key: 'phpunit-data'})
$(window).on('phpunit-data', function(data) {
self.onUpdate(data);
});
$(window).on('build-updated', function(data) {
if (data.queryData.status > 1) {
self.displayOnUpdate = true;
query();
}
});
},
render: function() {
return $('<table class="table table-striped" id="phpunit-data">' +
'<thead>' +
'<tr>' +
' <th>Test</th>' +
'</tr>' +
'</thead><tbody></tbody></table>');
},
onUpdate: function(e) {
if (this.lastData && this.lastData[0]) {
return;
}
this.lastData = e.queryData;
var tests = this.lastData[0].meta_value;
var tbody = $('#phpunit-data tbody');
tbody.empty();
for (var i in tests) {
var row = $('<tr>' +
'<td><strong>'+tests[i].suite+'' +
'::'+tests[i].test+'</strong><br>' +
''+(tests[i].message || '')+'</td>' +
'</tr>');
if (!tests[i].pass) {
row.addClass('danger');
} else {
row.addClass('success');
}
tbody.append(row);
}
}
});
PHPCI.registerPlugin(new phpunitPlugin());

View file

@ -3,10 +3,11 @@ var warningsPlugin = PHPCI.UiPlugin.extend({
css: 'col-lg-6 col-md-6 col-sm-12 col-xs-12',
title: 'Quality Trend',
keys: {
'phpmd-warnings': 'PHPMD Warnings',
'phpcs-warnings': 'PHPCS Warnings',
'phpcs-errors': 'PHPCS Errors',
'phplint-errors': 'PHPLint Errors'
'phpmd-warnings': 'PHPMD Warnings',
'phpcs-warnings': 'PHPCS Warnings',
'phpcs-errors': 'PHPCS Errors',
'phplint-errors': 'PHPLint Errors',
'phpunit-errors': 'PHPUnit Errors'
},
data: {},
displayOnUpdate: false,
@ -19,7 +20,7 @@ var warningsPlugin = PHPCI.UiPlugin.extend({
queries.push(PHPCI.registerQuery(key, -1, {num_builds: 10, key: key}));
}
$(window).on('phpmd-warnings phpcs-warnings phpcs-errors phplint-errors', function(data) {
$(window).on('phpmd-warnings phpcs-warnings phpcs-errors phplint-errors phpunit-errors', function(data) {
self.onUpdate(data);
});

View file

@ -16,4 +16,3 @@ require_once('../bootstrap.php');
$fc = new PHPCI\Application($config, new b8\Http\Request());
print $fc->handleRequest();

View file

@ -26,7 +26,6 @@ if (!defined('PHPCI_IS_CONSOLE')) {
define('PHPCI_IS_CONSOLE', false);
}
$isWin = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? true : false;
if (!defined('IS_WIN')) {
define('IS_WIN', $isWin);
define('IS_WIN', ((strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? true : false));
}