Migrating PHPMD to use XML report format and add a UI plugin to display warning information. See #305
This commit is contained in:
parent
71d86bd346
commit
66bfcea8ed
|
@ -258,6 +258,11 @@ class Builder implements LoggerAwareInterface
|
||||||
return $this->commandExecutor->getLastOutput();
|
return $this->commandExecutor->getLastOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function logExecOutput($enableLog = true)
|
||||||
|
{
|
||||||
|
$this->commandExecutor->logExecOutput = $enableLog;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a binary required by a plugin.
|
* Find a binary required by a plugin.
|
||||||
* @param $binary
|
* @param $binary
|
||||||
|
|
|
@ -25,6 +25,9 @@ class CommandExecutor
|
||||||
|
|
||||||
protected $lastOutput;
|
protected $lastOutput;
|
||||||
|
|
||||||
|
public $logExecOutput = true;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The path which findBinary will look in.
|
* The path which findBinary will look in.
|
||||||
* @var string
|
* @var string
|
||||||
|
@ -80,7 +83,7 @@ class CommandExecutor
|
||||||
$lastOutput = trim($lastOutput, '"');
|
$lastOutput = trim($lastOutput, '"');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($this->lastOutput) && ($this->verbose|| $status != 0)) {
|
if ($this->logExecOutput && !empty($this->lastOutput) && ($this->verbose|| $status != 0)) {
|
||||||
$this->logger->log($this->lastOutput);
|
$this->logger->log($this->lastOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,4 +157,9 @@ class Build extends BuildBase
|
||||||
|
|
||||||
return $config;
|
return $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getFileLink($file, $line = null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,4 +93,24 @@ class GithubBuild extends RemoteGitBuild
|
||||||
return 'https://github.com/' . $this->getProject()->getReference() . '.git';
|
return 'https://github.com/' . $this->getProject()->getReference() . '.git';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCommitMessage()
|
||||||
|
{
|
||||||
|
$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);
|
||||||
|
$rtn = preg_replace('/\@([a-zA-Z0-9_]+)/', '<a target="_blank" href="https://github.com/$1">@$1</a>', $rtn);
|
||||||
|
|
||||||
|
return $rtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFileLinkTemplate()
|
||||||
|
{
|
||||||
|
$link = 'https://github.com/' . $this->getProject()->getReference() . '/';
|
||||||
|
$link .= 'blob/' . $this->getBranch() . '/';
|
||||||
|
$link .= '{FILE}';
|
||||||
|
$link .= '#L{LINE}';
|
||||||
|
|
||||||
|
return $link;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,7 +124,12 @@ class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
|
||||||
$path = $this->path;
|
$path = $this->path;
|
||||||
}
|
}
|
||||||
|
|
||||||
$cmd = $phpmd . ' "%s" text %s %s %s';
|
$cmd = $phpmd . ' "%s" xml %s %s %s';
|
||||||
|
|
||||||
|
// Disable exec output logging, as we don't want the XML report in the log:
|
||||||
|
$this->phpci->logExecOutput(false);
|
||||||
|
|
||||||
|
// Run PHPMD:
|
||||||
$this->phpci->executeCommand(
|
$this->phpci->executeCommand(
|
||||||
$cmd,
|
$cmd,
|
||||||
$path,
|
$path,
|
||||||
|
@ -133,9 +138,14 @@ class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
|
||||||
$suffixes
|
$suffixes
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Re-enable exec output logging:
|
||||||
|
$this->phpci->logExecOutput(true);
|
||||||
|
|
||||||
$success = true;
|
$success = true;
|
||||||
$errors = count(array_filter(explode(PHP_EOL, trim($this->phpci->getLastOutput()))));
|
|
||||||
|
list($errors, $data) = $this->processReport(trim($this->phpci->getLastOutput()));
|
||||||
$this->build->storeMeta('phpmd-warnings', $errors);
|
$this->build->storeMeta('phpmd-warnings', $errors);
|
||||||
|
$this->build->storeMeta('phpmd-data', $data);
|
||||||
|
|
||||||
if ($this->allowed_warnings != -1 && $errors > $this->allowed_warnings) {
|
if ($this->allowed_warnings != -1 && $errors > $this->allowed_warnings) {
|
||||||
$success = false;
|
$success = false;
|
||||||
|
@ -150,4 +160,38 @@ class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
|
||||||
$this->{$key} = $options[$key];
|
$this->{$key} = $options[$key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function processReport($xml)
|
||||||
|
{
|
||||||
|
$xml = simplexml_load_string($xml);
|
||||||
|
|
||||||
|
if ($xml === false) {
|
||||||
|
throw new \Exception('Could not process PHPMD report XML.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$warnings = 0;
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
foreach ($xml->file as $file) {
|
||||||
|
$fileName = (string)$file['name'];
|
||||||
|
$fileName = str_replace($this->phpci->buildPath, '', $fileName);
|
||||||
|
|
||||||
|
foreach ($file->violation as $violation) {
|
||||||
|
$warnings++;
|
||||||
|
$warning = array(
|
||||||
|
'file' => $fileName,
|
||||||
|
'line_start' => (int)$violation['beginline'],
|
||||||
|
'line_end' => (int)$violation['endline'],
|
||||||
|
'rule' => (string)$violation['rule'],
|
||||||
|
'ruleset' => (string)$violation['ruleset'],
|
||||||
|
'priority' => (int)$violation['priority'],
|
||||||
|
'message' => (string)$violation,
|
||||||
|
);
|
||||||
|
|
||||||
|
$data[] = $warning;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array($warnings, $data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,11 +57,16 @@ td .label {
|
||||||
|
|
||||||
#title
|
#title
|
||||||
{
|
{
|
||||||
border-bottom: 1px solid #ccc;
|
|
||||||
margin: -10px -10px 15px -10px;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#title img {
|
||||||
|
border: 1px solid #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: 2px 2px 2px rgba(0,0,0,0.1);
|
||||||
|
margin-bottom: 15px;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
#title h1
|
#title h1
|
||||||
{
|
{
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
|
@ -69,6 +74,23 @@ td .label {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#title h1 span {
|
||||||
|
font-weight: lighter;
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#title h1 label {
|
||||||
|
margin-top: -6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#build-info {
|
||||||
|
margin-left: 100px;
|
||||||
|
}
|
||||||
|
.commit-message {
|
||||||
|
font-size: 1.2em;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
color: #246;
|
color: #246;
|
||||||
font-size: 1.8em;
|
font-size: 1.8em;
|
||||||
|
@ -135,8 +157,13 @@ td .label {
|
||||||
|
|
||||||
.ui-sortable-placeholder * { visibility: hidden; }
|
.ui-sortable-placeholder * { visibility: hidden; }
|
||||||
|
|
||||||
.ui-plugin { padding-top: 15px; }
|
.ui-plugin .panel-title {
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-body table {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
#loading {
|
#loading {
|
||||||
font-family: Roboto, Arial, Sans-Serif;
|
font-family: Roboto, Arial, Sans-Serif;
|
||||||
|
|
69
public/assets/js/build-plugins/phpmd.js
Normal file
69
public/assets/js/build-plugins/phpmd.js
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
var phpmdPlugin = PHPCI.UiPlugin.extend({
|
||||||
|
id: 'build-phpmd-warnings',
|
||||||
|
css: 'col-lg-12 col-md-12 col-sm-12 col-xs-12',
|
||||||
|
title: 'PHP Mess Detector',
|
||||||
|
lastData: null,
|
||||||
|
displayOnUpdate: false,
|
||||||
|
|
||||||
|
register: function() {
|
||||||
|
var self = this;
|
||||||
|
var query = PHPCI.registerQuery('phpmd-data', -1, {key: 'phpmd-data'})
|
||||||
|
|
||||||
|
$(window).on('phpmd-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="phpmd-data">' +
|
||||||
|
'<thead>' +
|
||||||
|
'<tr>' +
|
||||||
|
' <th>File</th>' +
|
||||||
|
' <th>Start</th>' +
|
||||||
|
' <th>End</th>' +
|
||||||
|
' <th>Message</th>' +
|
||||||
|
'</tr>' +
|
||||||
|
'</thead><tbody></tbody></table>');
|
||||||
|
},
|
||||||
|
|
||||||
|
onUpdate: function(e) {
|
||||||
|
if (this.lastData && this.lastData[0]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lastData = e.queryData;
|
||||||
|
|
||||||
|
var errors = this.lastData[0].meta_value;
|
||||||
|
var tbody = $('#phpmd-data tbody');
|
||||||
|
tbody.empty();
|
||||||
|
|
||||||
|
for (var i in errors) {
|
||||||
|
var file = errors[i].file;
|
||||||
|
|
||||||
|
if (PHPCI.fileLinkTemplate) {
|
||||||
|
var fileLink = PHPCI.fileLinkTemplate.replace('{FILE}', file);
|
||||||
|
fileLink = fileLink.replace('{LINE}', errors[i].line_start);
|
||||||
|
|
||||||
|
file = '<a target="_blank" href="'+fileLink+'">' + file + '</a>';
|
||||||
|
}
|
||||||
|
|
||||||
|
var row = $('<tr>' +
|
||||||
|
'<td>'+file+'</td>' +
|
||||||
|
'<td>'+errors[i].line_start+'</td>' +
|
||||||
|
'<td>'+errors[i].line_end+'</td>' +
|
||||||
|
'<td>'+errors[i].message+'</td></tr>');
|
||||||
|
|
||||||
|
tbody.append(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
PHPCI.registerPlugin(new phpmdPlugin());
|
|
@ -382,7 +382,7 @@ var PHPCIObject = Class.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#plugins').sortable({
|
$('#plugins').sortable({
|
||||||
handle: '.title',
|
handle: '.panel-title',
|
||||||
connectWith: '#plugins',
|
connectWith: '#plugins',
|
||||||
update: self.storePluginOrder
|
update: self.storePluginOrder
|
||||||
});
|
});
|
||||||
|
@ -391,16 +391,13 @@ var PHPCIObject = Class.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
renderPlugin: function(plugin) {
|
renderPlugin: function(plugin) {
|
||||||
var output = $('<div></div>').addClass('box-content').append(plugin.render());
|
var output = $('<div></div>').addClass('panel-body').append(plugin.render());
|
||||||
var container = $('<div></div>').addClass('ui-plugin ' + plugin.css);
|
var container = $('<div></div>').addClass('ui-plugin ' + plugin.css);
|
||||||
var content = $('<div></div>').attr('id', plugin.id).append(output);
|
var content = $('<div></div>').attr('id', plugin.id).append(output);
|
||||||
|
content.addClass('panel');
|
||||||
if (plugin.box) {
|
|
||||||
content.addClass('box');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.title) {
|
if (plugin.title) {
|
||||||
content.prepend('<h3 class="title">'+plugin.title+'</h3>');
|
content.prepend('<div class="panel-heading"><h3 class="panel-title">'+plugin.title+'</h3></div>');
|
||||||
}
|
}
|
||||||
|
|
||||||
content.append(output);
|
content.append(output);
|
||||||
|
|
Loading…
Reference in a new issue