From 9ecd3bfa111e79242f960b867b283097ee246fb1 Mon Sep 17 00:00:00 2001 From: Dan Cryer Date: Thu, 8 May 2014 16:02:24 +0000 Subject: [PATCH] Adding PHP Docblock Checker plugin --- PHPCI/Plugin/PhpDocblockChecker.php | 138 ++++++++++++++++++ phpci.yml | 2 + public/assets/js/build-plugins/phpdoccheck.js | 78 ++++++++++ public/assets/js/build-plugins/warnings.js | 5 +- 4 files changed, 221 insertions(+), 2 deletions(-) create mode 100755 PHPCI/Plugin/PhpDocblockChecker.php create mode 100644 public/assets/js/build-plugins/phpdoccheck.js diff --git a/PHPCI/Plugin/PhpDocblockChecker.php b/PHPCI/Plugin/PhpDocblockChecker.php new file mode 100755 index 00000000..b41b8434 --- /dev/null +++ b/PHPCI/Plugin/PhpDocblockChecker.php @@ -0,0 +1,138 @@ + +* @package PHPCI +* @subpackage Plugins +*/ +class PhpDocblockChecker implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin +{ + /** + * @var \PHPCI\Builder + */ + protected $phpci; + + /** + * @var \PHPCI\Model\Build + */ + protected $build; + + /** + * @var string Based on the assumption the root may not hold the code to be + * tested, extends the build path. + */ + protected $path; + + /** + * @var array - paths to ignore + */ + protected $ignore; + + protected $skipClasses = false; + protected $skipMethods = false; + + public static function canExecute($stage, Builder $builder, Build $build) + { + if ($stage == 'test') { + return true; + } + + return false; + } + + + public function __construct(Builder $phpci, Build $build, array $options = array()) + { + $this->phpci = $phpci; + $this->build = $build; + $this->ignore = $phpci->ignore; + $this->path = ''; + $this->allowed_warnings = 0; + + if (isset($options['zero_config']) && $options['zero_config']) { + $this->allowed_warnings = -1; + } + + if (array_key_exists('skip_classes', $options)) { + $this->skipClasses = true; + } + + if (array_key_exists('skip_methods', $options)) { + $this->skipMethods = true; + } + + if (!empty($options['path'])) { + $this->path = $options['path']; + } + + if (array_key_exists('allowed_warnings', $options)) { + $this->allowed_warnings = (int)$options['allowed_warnings']; + } + } + + /** + * Runs PHP Mess Detector in a specified directory. + */ + public function execute() + { + $ignore = ''; + if (count($this->ignore)) { + $ignore = ' --exclude="' . implode(',', $this->ignore) . '"'; + } + + var_dump($ignore); + + $checker = $this->phpci->findBinary('phpdoccheck'); + + if (!$checker) { + $this->phpci->logFailure('Could not find phpdoccheck.'); + return false; + } + + $path = $this->phpci->buildPath . $this->path; + + $cmd = $checker . ' --json --directory="%s"%s%s%s'; + + // Disable exec output logging, as we don't want the XML report in the log: + $this->phpci->logExecOutput(false); + + // Run checker: + $this->phpci->executeCommand( + $cmd, + $path, + $ignore, + ($this->skipClasses ? ' --skip-classes' : ''), + ($this->skipMethods ? ' --skip-methods' : '') + ); + + // Re-enable exec output logging: + $this->phpci->logExecOutput(true); + + $output = json_decode($this->phpci->getLastOutput()); + $errors = count($output); + $success = true; + + $this->build->storeMeta('phpdoccheck-warnings', $errors); + $this->build->storeMeta('phpdoccheck-data', $output); + + if ($this->allowed_warnings != -1 && $errors > $this->allowed_warnings) { + $success = false; + } + + return $success; + } +} diff --git a/phpci.yml b/phpci.yml index 9dda1fa4..24121476 100644 --- a/phpci.yml +++ b/phpci.yml @@ -17,6 +17,8 @@ test: standard: "PSR2" php_loc: php_unit: + php_docblock_checker: + allowed_warnings: -1 # Allow unlimited warnings for now. failure: email: diff --git a/public/assets/js/build-plugins/phpdoccheck.js b/public/assets/js/build-plugins/phpdoccheck.js new file mode 100644 index 00000000..89d8b449 --- /dev/null +++ b/public/assets/js/build-plugins/phpdoccheck.js @@ -0,0 +1,78 @@ +var phpdoccheckPlugin = PHPCI.UiPlugin.extend({ + id: 'build-phpdoccheck-warnings', + css: 'col-lg-12 col-md-12 col-sm-12 col-xs-12', + title: 'PHP Docblock Checker', + lastData: null, + displayOnUpdate: false, + box: true, + + register: function() { + var self = this; + var query = PHPCI.registerQuery('phpdoccheck-data', -1, {key: 'phpdoccheck-data'}) + + $(window).on('phpdoccheck-data', function(data) { + self.onUpdate(data); + }); + + $(window).on('build-updated', function(data) { + if (data.queryData.status > 1) { + self.displayOnUpdate = true; + query(); + } + }); + }, + + render: function() { + + return $('' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '
TypeFileLineClassMethod
'); + }, + + onUpdate: function(e) { + if (this.lastData && this.lastData[0]) { + return; + } + + this.lastData = e.queryData; + + var errors = this.lastData[0].meta_value; + var tbody = $('#phpdoccheck-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); + + file = '' + file + ''; + } + + var row = $('' + + ''+errors[i].type+'' + + ''+file+'' + + ''+errors[i].line+'' + + ''+errors[i].class+'' + + ''+errors[i].method+''); + + if (errors[i].type == 'method') { + row.addClass('danger'); + } else { + row.addClass('warning'); + } + + tbody.append(row); + } + } +}); + +PHPCI.registerPlugin(new phpdoccheckPlugin()); diff --git a/public/assets/js/build-plugins/warnings.js b/public/assets/js/build-plugins/warnings.js index cc2db78f..70d2b4b2 100644 --- a/public/assets/js/build-plugins/warnings.js +++ b/public/assets/js/build-plugins/warnings.js @@ -7,7 +7,8 @@ var warningsPlugin = PHPCI.UiPlugin.extend({ 'phpcs-warnings': 'PHPCS Warnings', 'phpcs-errors': 'PHPCS Errors', 'phplint-errors': 'PHPLint Errors', - 'phpunit-errors': 'PHPUnit Errors' + 'phpunit-errors': 'PHPUnit Errors', + 'phpdoccheck-warnings': 'PHP Docblock Checker Warnings' }, data: {}, displayOnUpdate: false, @@ -20,7 +21,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 phpunit-errors', function(data) { + $(window).on('phpmd-warnings phpcs-warnings phpcs-errors phplint-errors phpunit-errors phpdoccheck-errors', function(data) { self.onUpdate(data); });