This commit is contained in:
OxGroup 2016-11-23 21:36:40 +00:00 committed by GitHub
commit fa66a20a9c
23 changed files with 452 additions and 2914 deletions

3
.gitignore vendored
View file

@ -1,5 +1,7 @@
/composer.lock
.idea .idea
vendor/ vendor/
.gitignore
composer.phar composer.phar
config.php config.php
.DS_Store .DS_Store
@ -9,7 +11,6 @@ config.php
.htaccess .htaccess
PHPCI/config.yml PHPCI/config.yml
cache cache
/loggerconfig.php
/pluginconfig.php /pluginconfig.php
PHPCI/Model/Migration.php PHPCI/Model/Migration.php
PHPCI/Model/Base/MigrationBase.php PHPCI/Model/Base/MigrationBase.php

View file

@ -104,7 +104,7 @@ class Application extends b8\Application
$this->response->setContent($view->render()); $this->response->setContent($view->render());
} }
if ($this->response->hasLayout() && $this->controller->layout) { if (!empty($this->response->hasLayout()) && isset($this->controller->layout)) {
$this->setLayoutVariables($this->controller->layout); $this->setLayoutVariables($this->controller->layout);
$this->controller->layout->content = $this->response->getContent(); $this->controller->layout->content = $this->response->getContent();

View file

@ -246,7 +246,7 @@ class Builder implements LoggerAwareInterface
// Clean up: // Clean up:
$this->buildLogger->log(Lang::get('removing_build')); $this->buildLogger->log(Lang::get('removing_build'));
$this->build->removeBuildDirectory(); //$this->build->removeBuildDirectory();
$this->store->save($this->build); $this->store->save($this->build);
} }

View file

@ -74,14 +74,7 @@ class RunCommand extends Command
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output)
{ {
$this->output = $output; $this->output = $output;
$this->logger->pushHandler(new OutputLogHandler($output));
// For verbose mode we want to output all informational and above
// messages to the symphony output interface.
if ($input->hasOption('verbose') && $input->getOption('verbose')) {
$this->logger->pushHandler(
new OutputLogHandler($this->output, Logger::INFO)
);
}
$running = $this->validateRunningBuilds(); $running = $this->validateRunningBuilds();

View file

@ -12,7 +12,6 @@ namespace PHPCI\Controller;
use b8; use b8;
use b8\Store; use b8\Store;
use Exception; use Exception;
use PHPCI\BuildFactory;
use PHPCI\Model\Project; use PHPCI\Model\Project;
use PHPCI\Service\BuildService; use PHPCI\Service\BuildService;
use PHPCI\Store\BuildStore; use PHPCI\Store\BuildStore;
@ -78,6 +77,7 @@ class WebhookController extends \b8\Controller
$response->setResponseCode(500); $response->setResponseCode(500);
$response->setContent(array('status' => 'failed', 'error' => $ex->getMessage())); $response->setContent(array('status' => 'failed', 'error' => $ex->getMessage()));
} }
return $response; return $response;
} }
@ -256,6 +256,7 @@ class WebhookController extends \b8\Controller
$results[$commit['id']] = array('status' => 'failed', 'error' => $ex->getMessage()); $results[$commit['id']] = array('status' => 'failed', 'error' => $ex->getMessage());
} }
} }
return array('status' => $status, 'commits' => $results); return array('status' => $status, 'commits' => $results);
} }
@ -264,6 +265,7 @@ class WebhookController extends \b8\Controller
$branch = str_replace('refs/tags/', 'Tag: ', $payload['ref']); $branch = str_replace('refs/tags/', 'Tag: ', $payload['ref']);
$committer = $payload['pusher']['email']; $committer = $payload['pusher']['email'];
$message = $payload['head_commit']['message']; $message = $payload['head_commit']['message'];
return $this->createBuild($project, $payload['after'], $branch, $committer, $message); return $this->createBuild($project, $payload['after'], $branch, $committer, $message);
} }
@ -293,7 +295,14 @@ class WebhookController extends \b8\Controller
$url = $payload['pull_request']['commits_url']; $url = $payload['pull_request']['commits_url'];
$http = new \b8\HttpClient(); $http = new \b8\HttpClient();
$http->setHeaders($headers); $http->setHeaders($headers);
$response = $http->get($url); //for large pull requests, allow grabbing more then the default number of commits
$custom_per_page = \b8\Config::getInstance()->get('phpci.github.per_page');
$params = [];
if ($custom_per_page) {
$params["per_page"] = $custom_per_page;
}
$response = $http->get($url, $params);
// Check we got a success response: // Check we got a success response:
if (!$response['success']) { if (!$response['success']) {
@ -379,6 +388,7 @@ class WebhookController extends \b8\Controller
$results[$commit['id']] = array('status' => 'failed', 'error' => $ex->getMessage()); $results[$commit['id']] = array('status' => 'failed', 'error' => $ex->getMessage());
} }
} }
return array('status' => $status, 'commits' => $results); return array('status' => $status, 'commits' => $results);
} }
@ -406,7 +416,8 @@ class WebhookController extends \b8\Controller
$committer, $committer,
$commitMessage, $commitMessage,
array $extra = null array $extra = null
) { )
{
// Check if a build already exists for this commit ID: // Check if a build already exists for this commit ID:
$builds = $this->buildStore->getByProjectAndCommit($project->getId(), $commitId); $builds = $this->buildStore->getByProjectAndCommit($project->getId(), $commitId);

View file

@ -37,7 +37,7 @@ class Lang
return call_user_func_array('sprintf', $vars); return call_user_func_array('sprintf', $vars);
} }
return '%%MISSING STRING: ' . $string . '%%'; return $string;
} }
/** /**

View file

@ -438,7 +438,6 @@ PHPCI',
'php_unit' => 'PHP Unit', 'php_unit' => 'PHP Unit',
'php_cpd' => 'PHP Copy/Paste Detector', 'php_cpd' => 'PHP Copy/Paste Detector',
'php_docblock_checker' => 'PHP Docblock Checker', 'php_docblock_checker' => 'PHP Docblock Checker',
'behat' => 'Behat', 'php_lint' => 'PHP Lint',
'technical_debt' => 'Technical Debt',
); );

View file

@ -148,11 +148,12 @@ PHPCI',
Services</a> вашего Bitbucket репозитория.', Services</a> вашего Bitbucket репозитория.',
// View Build // View Build
'errors' => 'Ошибки',
'information' => 'Информация',
'build_x_not_found' => 'Сборки с ID %d не существует.', 'build_x_not_found' => 'Сборки с ID %d не существует.',
'build_n' => 'Сборка %d', 'build_n' => 'Сборка %d',
'rebuild_now' => 'Пересобрать сейчас', 'rebuild_now' => 'Пересобрать сейчас',
'committed_by_x' => 'Отправил %s', 'committed_by_x' => 'Отправил %s',
'commit_id_x' => 'Коммит: %s', 'commit_id_x' => 'Коммит: %s',
@ -164,6 +165,7 @@ PHPCI',
'noncomment_lines' => 'Строк некомментариев', 'noncomment_lines' => 'Строк некомментариев',
'logical_lines' => 'Строк логики', 'logical_lines' => 'Строк логики',
'lines_of_code' => 'Строк кода', 'lines_of_code' => 'Строк кода',
'structure' => 'Структура',
'build_log' => 'Лог сборки', 'build_log' => 'Лог сборки',
'quality_trend' => 'Тенденция качества', 'quality_trend' => 'Тенденция качества',
'codeception_errors' => 'Ошибки Codeception', 'codeception_errors' => 'Ошибки Codeception',
@ -205,8 +207,8 @@ PHPCI',
'build_created' => 'Сборка создана', 'build_created' => 'Сборка создана',
'build_started' => 'Сборка запущена', 'build_started' => 'Сборка запущена',
'build_finished' => 'Сборка окончена', 'build_finished' => 'Сборка окончена',
'test_message' => 'Message', 'test_message' => 'Сообщение',
'test_no_message' => 'No message', 'test_no_message' => 'Нет сообщений',
'test_success' => 'Успешно: %d', 'test_success' => 'Успешно: %d',
'test_fail' => 'Провалено: %d', 'test_fail' => 'Провалено: %d',
'test_skipped' => 'Пропущено: %d', 'test_skipped' => 'Пропущено: %d',
@ -268,8 +270,8 @@ PHPCI',
'5_mins' => '5 минут', '5_mins' => '5 минут',
'15_mins' => '15 минут', '15_mins' => '15 минут',
'30_mins' => '30 минут', '30_mins' => '30 минут',
'1_hour' => '1 часа', '1_hour' => '1 час',
'3_hours' => '3 часов', '3_hours' => '3 часа',
// Plugins // Plugins
'cannot_update_composer' => 'PHPCI не может обновить composer.json, если он недоступен на запись.', 'cannot_update_composer' => 'PHPCI не может обновить composer.json, если он недоступен на запись.',
@ -293,10 +295,10 @@ PHPCI',
'duration' => 'Продолжительность', 'duration' => 'Продолжительность',
'plugin' => 'Плагин', 'plugin' => 'Плагин',
'stage_setup' => 'Установка', 'stage_setup' => 'Установка',
'stage_test' => 'тестирование', 'stage_test' => 'Тестирование',
'stage_complete' => 'Завершение', 'stage_complete' => 'Завершено',
'stage_success' => 'Успешное завершение', 'stage_success' => 'Успешно',
'stage_failure' => 'Провал', 'stage_failure' => 'Провалено',
'stage_broken' => 'Поломка', 'stage_broken' => 'Поломка',
'stage_fixed' => 'Исправление', 'stage_fixed' => 'Исправление',
@ -408,5 +410,19 @@ PHPCI',
'build_file_missing' => 'Указанного файла сборки не существует.', 'build_file_missing' => 'Указанного файла сборки не существует.',
'property_file_missing' => 'Указанного файла сборки не существует.', 'property_file_missing' => 'Указанного файла сборки не существует.',
'could_not_process_report' => 'Невозможно обработать отчет этой утилиты.', 'could_not_process_report' => 'Невозможно обработать отчет этой утилиты.',
'shell_not_enabled' => 'Плагин shell не включен. Пожалуйста, включите его в файле config.yml.' 'shell_not_enabled' => 'Плагин shell не включен. Пожалуйста, включите его в файле config.yml.',
// Error Levels:
'critical' => 'Критическая',
'high' => 'Высокий',
'normal' => 'Обычный',
'low' => 'Низкий',
// Plugins that generate errors:
'php_mess_detector' => 'PHP Mess Detector',
'php_code_sniffer' => 'PHP Code Sniffer',
'php_unit' => 'PHP Unit',
'php_cpd' => 'PHP Copy/Paste Detector',
'php_docblock_checker' => 'PHP Docblock Checker',
'php_lint' => 'PHP Lint'
); );

View file

@ -10,40 +10,82 @@
namespace PHPCI\Logging; namespace PHPCI\Logging;
use Monolog\Handler\AbstractProcessingHandler; use Monolog\Handler\AbstractProcessingHandler;
use Psr\Log\LogLevel; use Monolog\Logger;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
/** /**
* Class OutputLogHandler outputs the build log to the terminal. * Class OutputLogHandler outputs the build log to the terminal.
*
* @package PHPCI\Logging * @package PHPCI\Logging
*/ */
class OutputLogHandler extends AbstractProcessingHandler class OutputLogHandler extends AbstractProcessingHandler
{ {
/**
* @var array
*/
protected static $levels = array(
OutputInterface::VERBOSITY_QUIET => Logger::ERROR,
OutputInterface::VERBOSITY_NORMAL => Logger::WARNING,
OutputInterface::VERBOSITY_VERBOSE => Logger::NOTICE,
OutputInterface::VERBOSITY_VERY_VERBOSE => Logger::INFO,
OutputInterface::VERBOSITY_DEBUG => Logger::DEBUG,
);
/**
* @var array
*/
protected static $colors = array(
Logger::ERROR => 'red',
Logger::WARNING => 'yellow',
Logger::NOTICE => 'green',
Logger::INFO => 'white'
);
/** /**
* @var OutputInterface * @var OutputInterface
*/ */
protected $output; protected $output;
/** /**
* OutputLogHandler constructor.
*
* @param OutputInterface $output * @param OutputInterface $output
* @param bool|string $level
* @param bool $bubble
*/ */
public function __construct( public function __construct(OutputInterface $output)
OutputInterface $output, {
$level = LogLevel::INFO, parent::__construct(static::$levels[$output->getVerbosity()]);
$bubble = true
) {
parent::__construct($level, $bubble);
$this->output = $output; $this->output = $output;
$this->pushProcessor(array($this, 'addConsoleColor'));
}
public function addConsoleColor($record)
{
foreach (static::$colors as $level => $color) {
if ($record['level'] >= $level) {
break;
}
}
$record['message'] = sprintf('<fg=%s>%s</fg=%s>', $color, rtrim($record['message']), $color);
return $record;
} }
/** /**
* Write a log entry to the terminal. * Write a log entry to the terminal.
*
* @param array $record * @param array $record
*/ */
protected function write(array $record) protected function write(array $record)
{ {
$this->output->writeln((string)$record['formatted']);
if ($record['level'] >= Logger::ERROR && $this->output instanceof ConsoleOutputInterface) {
$output = $this->output->getErrorOutput();
} else {
$output = $this->output;
}
$output->write($record['formatted']);
} }
} }

View file

@ -15,6 +15,7 @@ use PHPCI\Model\Build;
/** /**
* PHP Loc - Allows PHP Copy / Lines of Code testing. * PHP Loc - Allows PHP Copy / Lines of Code testing.
*
* @author Johan van der Heide <info@japaveh.nl> * @author Johan van der Heide <info@japaveh.nl>
* @package PHPCI * @package PHPCI
* @subpackage Plugins * @subpackage Plugins
@ -30,11 +31,18 @@ class PhpLoc implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
*/ */
protected $phpci; protected $phpci;
/**
* @var Build
*/
protected $build;
/** /**
* Check if this plugin can be executed. * Check if this plugin can be executed.
*
* @param $stage * @param $stage
* @param Builder $builder * @param Builder $builder
* @param Build $build * @param Build $build
*
* @return bool * @return bool
*/ */
public static function canExecute($stage, Builder $builder, Build $build) public static function canExecute($stage, Builder $builder, Build $build)
@ -48,6 +56,7 @@ class PhpLoc implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
/** /**
* Set up the plugin, configure options, etc. * Set up the plugin, configure options, etc.
*
* @param Builder $phpci * @param Builder $phpci
* @param Build $build * @param Build $build
* @param array $options * @param array $options
@ -84,15 +93,28 @@ class PhpLoc implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
$success = $this->phpci->executeCommand($phploc . ' %s "%s"', $ignore, $this->directory); $success = $this->phpci->executeCommand($phploc . ' %s "%s"', $ignore, $this->directory);
$output = $this->phpci->getLastOutput(); $output = $this->phpci->getLastOutput();
if (preg_match_all('/\((LOC|CLOC|NCLOC|LLOC)\)\s+([0-9]+)/', $output, $matches)) { if (preg_match_all('/\((LOC|CLOC|NCLOC|LLOC)\)\s+([0-9]+)/', $output, $matches2)) {
$data = array(); $data = array();
foreach ($matches[1] as $k => $v) { foreach ($matches2[1] as $k => $v) {
$data[$v] = (int)$matches[2][$k]; $data[$v] = (int) $matches2[2][$k];
} }
$this->build->storeMeta('phploc', $data); $this->build->storeMeta('phploc', $data);
} }
if (preg_match_all('/(Namespaces|Interfaces|Classes|Methods)\s+([0-9]+)/', $output, $matches)) {
$key = $matches[1];
$val = $matches[2];
$data = array(
$key[1] => (int) $val[1],
$key[2] => (int) $val[2],
$key[3] => (int) $val[3],
$key[6] => (int) $val[6],
);
$this->build->storeMeta('phploc-structure', $data);
}
return $success; return $success;
} }
} }

View file

@ -2,8 +2,11 @@
namespace PHPCI\Plugin\Util; namespace PHPCI\Plugin\Util;
use Pimple\Container;
/** /**
* Plugin Factory - Loads Plugins and passes required dependencies. * Plugin Factory - Loads Plugins and passes required dependencies.
*
* @package PHPCI\Plugin\Util * @package PHPCI\Plugin\Util
*/ */
class Factory class Factory
@ -15,19 +18,21 @@ class Factory
private $currentPluginOptions; private $currentPluginOptions;
/** /**
* @var \Pimple * @var Container
*/ */
private $container; private $container;
/** /**
* @param \Pimple $container * Factory constructor.
*
* @param Container|null $container
*/ */
public function __construct(\Pimple $container = null) public function __construct(Container $container = null)
{ {
if ($container) { if ($container) {
$this->container = $container; $this->container = $container;
} else { } else {
$this->container = new \Pimple(); $this->container = new Container();
} }
$self = $this; $self = $this;
@ -46,6 +51,7 @@ class Factory
* This enables the config file to call any public methods. * This enables the config file to call any public methods.
* *
* @param $configPath * @param $configPath
*
* @return bool - true if the function exists else false. * @return bool - true if the function exists else false.
*/ */
public function addConfigFromFile($configPath) public function addConfigFromFile($configPath)
@ -56,14 +62,17 @@ class Factory
$configFunction = require($configPath); $configFunction = require($configPath);
if (is_callable($configFunction)) { if (is_callable($configFunction)) {
$configFunction($this); $configFunction($this);
return true; return true;
} }
} }
return false; return false;
} }
/** /**
* Get most recently used factory options. * Get most recently used factory options.
*
* @return mixed * @return mixed
*/ */
public function getLastOptions() public function getLastOptions()
@ -77,6 +86,7 @@ class Factory
* *
* @param $className * @param $className
* @param array|null $options * @param array|null $options
*
* @throws \InvalidArgumentException if $className doesn't represent a valid plugin * @throws \InvalidArgumentException if $className doesn't represent a valid plugin
* @return \PHPCI\Plugin * @return \PHPCI\Plugin
*/ */
@ -111,6 +121,7 @@ class Factory
* @param callable $loader * @param callable $loader
* @param string|null $name * @param string|null $name
* @param string|null $type * @param string|null $type
*
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* @internal param mixed $resource * @internal param mixed $resource
*/ */
@ -118,7 +129,8 @@ class Factory
$loader, $loader,
$name = null, $name = null,
$type = null $type = null
) { )
{
if ($name === null && $type === null) { if ($name === null && $type === null) {
throw new \InvalidArgumentException( throw new \InvalidArgumentException(
"Type or Name must be specified" "Type or Name must be specified"
@ -138,20 +150,24 @@ class Factory
/** /**
* Get an internal resource ID. * Get an internal resource ID.
*
* @param null $type * @param null $type
* @param null $name * @param null $name
*
* @return string * @return string
*/ */
private function getInternalID($type = null, $name = null) private function getInternalID($type = null, $name = null)
{ {
$type = $type ?: ""; $type = $type ?: "";
$name = $name ?: ""; $name = $name ?: "";
return $type . "-" . $name; return $type . "-" . $name;
} }
/** /**
* @param string $type * @param string $type
* @param string $name * @param string $name
*
* @return mixed * @return mixed
*/ */
public function getResourceFor($type = null, $name = null) public function getResourceFor($type = null, $name = null)
@ -176,6 +192,7 @@ class Factory
/** /**
* @param \ReflectionParameter $param * @param \ReflectionParameter $param
*
* @return null|string * @return null|string
*/ */
private function getParamType(\ReflectionParameter $param) private function getParamType(\ReflectionParameter $param)
@ -195,6 +212,7 @@ class Factory
/** /**
* @param $existingArgs * @param $existingArgs
* @param \ReflectionParameter $param * @param \ReflectionParameter $param
*
* @return array * @return array
* @throws \DomainException * @throws \DomainException
*/ */

View file

@ -9,7 +9,7 @@
<?php Lang::out('edit_project'); ?> <?php Lang::out('edit_project'); ?>
</a> </a>
<a class="btn btn-danger" href="javascript:confirmDelete('<?php print PHPCI_URL . 'project/delete/' . $project->getId(); ?>', '<?php print Lang::out('project'); ?>', true)"> <a class="btn btn-danger" href="javascript:;" onclick="confirmDelete('<?php print PHPCI_URL . 'project/delete/' . $project->getId(); ?>', '<?php print Lang::out('project'); ?>', true)">
<?php Lang::out('delete_project'); ?> <?php Lang::out('delete_project'); ?>
</a> </a>

View file

@ -31,6 +31,7 @@
</script> </script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
<script src="<?php print PHPCI_URL; ?>assets/js/class.js"></script> <script src="<?php print PHPCI_URL; ?>assets/js/class.js"></script>
<script src="<?php print PHPCI_URL; ?>assets/js/sprintf.js"></script> <script src="<?php print PHPCI_URL; ?>assets/js/sprintf.js"></script>
<script src="<?php print PHPCI_URL; ?>assets/js/moment.min.js"></script> <script src="<?php print PHPCI_URL; ?>assets/js/moment.min.js"></script>

View file

@ -1,79 +0,0 @@
{
"name" : "block8/phpci",
"description" : "Simple continuous integration for PHP projects.",
"minimum-stability": "stable",
"type" : "library",
"keywords" : ["php", "phpci", "ci", "continuous", "integration", "testing", "phpunit", "continuous integration", "jenkins", "travis"],
"homepage" : "http://www.phptesting.org/",
"license" : "BSD-2-Clause",
"authors": [
{
"name" : "Dan Cryer",
"email" : "dan.cryer@block8.co.uk",
"homepage": "http://www.block8.co.uk",
"role" : "Developer"
}
],
"support": {
"email" : "hello+phpci@block8.co.uk",
"issues": "https://github.com/Block8/PHPCI/issues",
"source": "https://github.com/Block8/PHPCI"
},
"autoload": {
"psr-4": {
"PHPCI\\": "PHPCI"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\PHPCI\\": "Tests/PHPCI/"
}
},
"require": {
"php": ">=5.3.8",
"ext-pdo": "*",
"ext-pdo_mysql": "*",
"block8/b8framework": "~1.0",
"ircmaxell/password-compat": "~1.0",
"swiftmailer/swiftmailer": "~5.0",
"symfony/yaml": "~2.1",
"symfony/console": "~2.1",
"psr/log": "~1.0",
"monolog/monolog": "~1.6",
"pimple/pimple": "~1.1",
"robmorgan/phinx": "~0.4",
"sensiolabs/ansi-to-html": "~1.1",
"pda/pheanstalk": "~3.1",
"maknz/slack": "~1.7",
"hipchat/hipchat-php": "~1.4",
"mremi/flowdock": "~1.0"
},
"require-dev": {
"phpunit/phpunit": "~4.5",
"phpmd/phpmd": "~2.0",
"squizlabs/php_codesniffer": "~2.3",
"block8/php-docblock-checker": "~1.0",
"phploc/phploc": "~2.0",
"jakub-onderka/php-parallel-lint": "0.8.*"
},
"suggest": {
"block8/php-docblock-checker": "PHP Docblock Checker",
"phpmd/phpmd": "PHP Mess Detector",
"sebastian/phpcpd": "PHP Copy/Paste Detector",
"squizlabs/php_codesniffer": "PHP Code Sniffer",
"phpspec/phpspec": "PHP Spec",
"fabpot/php-cs-fixer": "PHP Coding Standards Fixer",
"phploc/phploc": "PHP Lines of Code",
"atoum/atoum": "Atoum",
"jakub-onderka/php-parallel-lint": "Parallel Linting Tool",
"behat/behat": "Behat BDD Testing",
"phptal/phptal": "PHPTAL templating engine"
}
}

2740
composer.lock generated

File diff suppressed because it is too large Load diff

0
errors.log Normal file
View file

View file

@ -0,0 +1,72 @@
var composerSecurityCheck = ActiveBuild.UiPlugin.extend({
id: 'build-composer-security-check-errors',
css: 'col-lg-6 col-md-6 col-sm-6 col-xs-6',
title: Lang.get('Composer Security'),
lastData: null,
displayOnUpdate: false,
box: true,
rendered: false,
register: function() {
var self = this;
var query = ActiveBuild.registerQuery('composer-security-check-errors', -1, {key: 'composer-security-check-errors'})
$(window).on('composer-security-check-errors', function(data) {
self.onUpdate(data);
});
$(window).on('build-updated', function() {
if (!self.rendered) {
self.displayOnUpdate = true;
query();
}
});
},
render: function() {
return $('<div class="table-responsive"><table class="table" id="composer-security-check-data">' +
'<thead>' +
'<tr>' +
' <th>'+Lang.get('Resultats')+'</th>' +
'</tr>' +
'</thead><tbody></tbody></table></div>');
},
onUpdate: function(e) {
if (!e.queryData) {
$('#build-composer-security-check-errors').hide();
return;
}
this.rendered = true;
this.lastData = e.queryData;
var results = this.lastData[0].meta_value;
var tbody = $('#composer-security-check-data tbody');
tbody.empty();
if (results.length == 0) {
$('#build-composer-security-check-errors').hide();
return;
}
console.log(results);
for (var i in results) {
var lib = results[i];
var head = '<tr><th>'+i + ' ' + lib.version+'</th></tr>'
tbody.append(head);
console.log(lib);
for (var j in lib.advisories) {
var advise = lib.advisories[j]
console.log(advise);
var row = '<tr><td><a href="'+advise.link+'" target="_blank">'+advise.title+'</a></TD></tr>'
tbody.append(row);
}
}
$('#build-composer-security-check-errors').show();
}
});
ActiveBuild.registerPlugin(new composerSecurityCheck());

View file

@ -1,6 +1,6 @@
var locPlugin = ActiveBuild.UiPlugin.extend({ var locPlugin = ActiveBuild.UiPlugin.extend({
id: 'build-lines-chart', id: 'build-lines-chart',
css: 'col-xs-12', css: 'col-xs-6',
title: Lang.get('lines_of_code'), title: Lang.get('lines_of_code'),
lastData: null, lastData: null,
displayOnUpdate: false, displayOnUpdate: false,

View file

@ -0,0 +1,106 @@
var locPlugin2 = ActiveBuild.UiPlugin.extend({
id: 'build-lines-chart-structure',
css: 'col-xs-6',
title: Lang.get('structure'),
lastData: null,
displayOnUpdate: false,
rendered: false,
chartData: null,
register: function() {
var self = this;
var query = ActiveBuild.registerQuery('phploc-structure', -1, {num_builds: 10, key: 'phploc-structure'})
$(window).on('phploc-structure', function(data) {
self.onUpdate(data);
});
$(window).on('build-updated', function(data) {
if (data.queryData.status > 1 && !self.rendered) {
query();
}
});
},
render: function() {
var self = this;
var container = $('<div id="phploc-structure" style="width: 100%; height: 300px"></div>');
container.append('<canvas id="phploc-structure-chart" style="width: 100%; height: 300px"></canvas>');
$(document).on('shown.bs.tab', function () {
$('#build-lines-chart-structure').hide();
self.drawChart();
});
return container;
},
onUpdate: function(e) {
this.lastData = e.queryData;
this.displayChart();
},
displayChart: function() {
var self = this;
var builds = this.lastData;
self.rendered = true;
self.chartData = {
labels: [],
datasets: [
{
label: "Namespaces",
strokeColor: "rgba(60,141,188,1)",
pointColor: "rgba(60,141,188,1)",
data: []
},
{
label: "Interfaces",
strokeColor: "rgba(245,105,84,1)",
pointColor: "rgba(245,105,84,1)",
data: []
},
{
label: "Classes",
strokeColor: "rgba(0,166,90,1)",
pointColor: "rgba(0,166,90,1)",
data: []
},
{
label: "Methods",
strokeColor: "rgba(0,192,239,1)",
pointColor: "rgba(0,192,239,1)",
data: []
}
]
};
for (var i in builds) {
self.chartData.labels.push('Build ' + builds[i].build_id);
self.chartData.datasets[0].data.push(builds[i].meta_value.Namespaces);
self.chartData.datasets[1].data.push(builds[i].meta_value.Interfaces);
self.chartData.datasets[2].data.push(builds[i].meta_value.Classes);
self.chartData.datasets[3].data.push(builds[i].meta_value.Methods);
}
self.drawChart();
},
drawChart: function () {
var self = this;
if ($('#information').hasClass('active') && self.chartData && self.lastData) {
$('#build-lines-chart-structure').show();
var ctx = $("#phploc-structure-chart").get(0).getContext("2d");
var phpLocChart = new Chart(ctx);
phpLocChart.Line(self.chartData, {
datasetFill: false,
multiTooltipTemplate: "<%=datasetLabel%>: <%= value %>"
});
}
}
});
ActiveBuild.registerPlugin(new locPlugin2());

View file

@ -1,6 +1,6 @@
var SummaryPlugin = ActiveBuild.UiPlugin.extend({ var SummaryPlugin = ActiveBuild.UiPlugin.extend({
id: 'build-summary', id: 'build-summary',
css: 'col-xs-12', css: 'col-xs-6',
title: Lang.get('build-summary'), title: Lang.get('build-summary'),
box: true, box: true,
statusIcons: [ 'fa-clock-o', 'fa-cogs', 'fa-check', 'fa-remove' ], statusIcons: [ 'fa-clock-o', 'fa-cogs', 'fa-check', 'fa-remove' ],

View file

@ -1,6 +1,6 @@
var warningsPlugin = ActiveBuild.UiPlugin.extend({ var warningsPlugin = ActiveBuild.UiPlugin.extend({
id: 'build-warnings-chart', id: 'build-warnings-chart',
css: 'col-xs-12', css: 'col-xs-6',
title: Lang.get('quality_trend'), title: Lang.get('quality_trend'),
keys: { keys: {
'codeception-errors': Lang.get('codeception_errors'), 'codeception-errors': Lang.get('codeception_errors'),

View file

@ -169,23 +169,99 @@ var Build = Class.extend({
if (plugin.title) { if (plugin.title) {
content.prepend('<div class="box-header"><h3 class="box-title">' + plugin.title + '</h3></div>'); content.prepend('<div class="box-header"><h3 class="box-title">' + plugin.title + '</h3></div>');
} }
this.toggleWidget(content);
container.append(content); container.append(content);
$('#plugins').append(container); $('#plugins').append(container);
}, },
toggleWidget: function ($box) {
var self = this;
var id = $box.attr('id');
var $header = $box.find('.box-header');
var $content = $header.next();
// Add widget toggler
var $toggle = $('<i class="box-tools fa pull-right fa-angle-down"></i>');
if (self.isWidgetHidden(id)) {
$content.addClass('hidden');
$toggle.toggleClass('fa-angle-down fa-angle-left');
}
$toggle.appendTo($header).click(function () {
$content.toggleClass('hidden');
if ($content.hasClass('hidden')) {
self.hideWidget(id);
} else {
self.showWidget(id);
}
$(this).toggleClass('fa-angle-down fa-angle-left');
});
},
isWidgetHidden: function (id) {
var settings = this._getSettings('hidden_widgets');
return (settings.indexOf(id) != -1);
},
hideWidget: function (id) {
var settings = this._getSettings('hidden_widgets');
var index = settings.indexOf(id);
if (index == -1) {
settings.push(id);
this._storeSettings('hidden_widgets', settings);
}
},
showWidget: function (id) {
var settings = this._getSettings('hidden_widgets');
var index = settings.indexOf(id);
if (index != -1) {
settings.splice(index, 1);
this._storeSettings('hidden_widgets', settings);
}
},
_getSettings: function (setting) {
var settingsArray = [];
var settingsString = $.cookie(setting);
if (settingsString) {
settingsArray = settingsString.split(',');
}
return settingsArray;
},
_storeSettings: function (setting, value) {
$.cookie(setting, value.toString());
},
UiPlugin: Class.extend({ UiPlugin: Class.extend({
id: null, id: null,
css: 'col-lg-4 col-md-6 col-sm-12 col-xs-12', css: 'col-lg-4 col-md-6 col-sm-12 col-xs-12',
box: false, box: false,
init: function () { init: function () {
}, },
register: function () { register: function () {
var self = this; var self = this;
$(window).on('build-updated', function (data) { $(window).on('build-updated', function (data) {
self.onUpdate(data); self.onUpdate(data);
}); });