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();
|
||||
}
|
||||
|
||||
public function logExecOutput($enableLog = true)
|
||||
{
|
||||
$this->commandExecutor->logExecOutput = $enableLog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a binary required by a plugin.
|
||||
* @param $binary
|
||||
|
|
|
@ -25,6 +25,9 @@ class CommandExecutor
|
|||
|
||||
protected $lastOutput;
|
||||
|
||||
public $logExecOutput = true;
|
||||
|
||||
|
||||
/**
|
||||
* The path which findBinary will look in.
|
||||
* @var string
|
||||
|
@ -80,7 +83,7 @@ class CommandExecutor
|
|||
$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);
|
||||
}
|
||||
|
||||
|
|
|
@ -157,4 +157,9 @@ class Build extends BuildBase
|
|||
|
||||
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';
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
$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(
|
||||
$cmd,
|
||||
$path,
|
||||
|
@ -133,9 +138,14 @@ class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
|
|||
$suffixes
|
||||
);
|
||||
|
||||
// Re-enable exec output logging:
|
||||
$this->phpci->logExecOutput(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-data', $data);
|
||||
|
||||
if ($this->allowed_warnings != -1 && $errors > $this->allowed_warnings) {
|
||||
$success = false;
|
||||
|
@ -150,4 +160,38 @@ class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
|
|||
$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
|
||||
{
|
||||
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
|
||||
{
|
||||
font-size: 2em;
|
||||
|
@ -69,6 +74,23 @@ td .label {
|
|||
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 {
|
||||
color: #246;
|
||||
font-size: 1.8em;
|
||||
|
@ -135,8 +157,13 @@ td .label {
|
|||
|
||||
.ui-sortable-placeholder * { visibility: hidden; }
|
||||
|
||||
.ui-plugin { padding-top: 15px; }
|
||||
.ui-plugin .panel-title {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.panel-body table {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#loading {
|
||||
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({
|
||||
handle: '.title',
|
||||
handle: '.panel-title',
|
||||
connectWith: '#plugins',
|
||||
update: self.storePluginOrder
|
||||
});
|
||||
|
@ -391,16 +391,13 @@ var PHPCIObject = Class.extend({
|
|||
},
|
||||
|
||||
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 content = $('<div></div>').attr('id', plugin.id).append(output);
|
||||
|
||||
if (plugin.box) {
|
||||
content.addClass('box');
|
||||
}
|
||||
content.addClass('panel');
|
||||
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue