prepare(); $this->lint(); $this->phploc(TRUE); $this->phpcs(TRUE); $this->dependencyReport(); $this->phpcpdReport(); } /** * Run all tests, generate coverage, generate docs, generate code statistics */ public function build() { $this->analyze(); $this->coverage(); $this->docs(); } /** * Cleanup temporary files */ public function clean() { $cleanFiles = [ 'build/humbug.json', 'build/humbug-log.txt', ]; array_map(function ($file) { @unlink($file); }, $cleanFiles); // So the task doesn't complain, // make any 'missing' dirs to cleanup array_map(function ($dir) { if ( ! is_dir($dir)) { `mkdir -p {$dir}`; } }, $this->cleanDirs); $this->_cleanDir($this->cleanDirs); $this->_deleteDir($this->cleanDirs); } /** * Run unit tests and generate coverage reports */ public function coverage() { $this->_run(['phpdbg -qrr -- vendor/bin/phpunit -c build']); } /** * Generate documentation with phpdox */ public function docs() { $cmd_parts = [ 'vendor/bin/phpdox', ]; $this->_run($cmd_parts, ' && '); } /** * Verify that source files are valid */ public function lint() { $files = $this->getAllSourceFiles(); $chunks = array_chunk($files, 12); foreach($chunks as $chunk) { $this->parallelLint($chunk); } } /** * Run the phpcs tool * * @param bool $report - if true, generates reports instead of direct output */ public function phpcs($report = FALSE) { $report_cmd_parts = [ 'vendor/bin/phpcs', '--standard=./build/phpcs.xml', '--report-checkstyle=./build/logs/phpcs.xml', ]; $normal_cmd_parts = [ 'vendor/bin/phpcs', '--standard=./build/phpcs.xml', ]; $cmd_parts = ($report) ? $report_cmd_parts : $normal_cmd_parts; $this->_run($cmd_parts); } /** * Run the phploc tool * * @param bool $report - if true, generates reports instead of direct output */ public function phploc($report = FALSE) { // Command for generating reports $report_cmd_parts = [ 'vendor/bin/phploc', '--count-tests', '--log-csv=build/logs/phploc.csv', '--log-xml=build/logs/phploc.xml', 'src', 'tests' ]; // Command for generating direct output $normal_cmd_parts = [ 'vendor/bin/phploc', '--count-tests', 'src', 'tests' ]; $cmd_parts = ($report) ? $report_cmd_parts : $normal_cmd_parts; $this->_run($cmd_parts); } /** * Create temporary directories */ public function prepare() { array_map([$this, '_mkdir'], $this->taskDirs); } /** * Lint php files and run unit tests */ public function test() { $this->lint(); $this->_run(['phpunit']); } /** * Watches for file updates, and automatically runs appropriate actions */ public function watch() { $this->taskWatch() ->monitor('composer.json', function() { $this->taskComposerUpdate()->run(); }) ->monitor('src', function () { $this->taskExec('test')->run(); }) ->monitor('tests', function () { $this->taskExec('test')->run(); }) ->run(); } /** * Create pdepend reports */ protected function dependencyReport() { $cmd_parts = [ 'vendor/bin/pdepend', '--jdepend-xml=build/logs/jdepend.xml', '--jdepend-chart=build/pdepend/dependencies.svg', '--overview-pyramid=build/pdepend/overview-pyramid.svg', 'src' ]; $this->_run($cmd_parts); } /** * Get the total list of source files, including tests * * @return array */ protected function getAllSourceFiles() { $files = array_merge( glob_recursive('build/*.php'), glob_recursive('src/*.php'), glob_recursive('src/**/*.php'), glob_recursive('tests/*.php'), glob_recursive('tests/**/*.php'), glob('*.php') ); sort($files); return $files; } /** * Run php's linter in one parallel task for the passed chunk * * @param array $chunk */ protected function parallelLint(array $chunk) { $task = $this->taskParallelExec() ->timeout(5) ->printed(FALSE); foreach($chunk as $file) { $task = $task->process("php -l {$file}"); } $task->run(); } /** * Generate copy paste detector report */ protected function phpcpdReport() { $cmd_parts = [ 'vendor/bin/phpcpd', '--log-pmd build/logs/pmd-cpd.xml', 'src' ]; $this->_run($cmd_parts); } /** * Shortcut for joining an array of command arguments * and then running it * * @param array $cmd_parts - command arguments * @param string $join_on - what to join the command arguments with */ protected function _run(array $cmd_parts, $join_on = ' ') { $this->taskExec(implode($join_on, $cmd_parts))->run(); } }