prepare(); $this->lint(); $this->phploc(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); $this->_cleanDir($this->taskDirs); $this->_deleteDir($this->taskDirs); } /** * Run unit tests and generate coverage reports */ public function coverage() { $this->taskPhpUnit() ->configFile('build/phpunit.xml') ->printed(true) ->run(); } /** * Generate documentation with phpdox */ public function docs() { $cmd_parts = [ 'cd build', '../vendor/bin/phpdox', 'cd ..' ]; $this->_run($cmd_parts, ' && '); } /** * Verify that source files are valid */ public function lint() { $files = $this->getAllSourceFiles(); $chunks = array_chunk($files, 6); $collection = $this->collection(); foreach($chunks as $chunk) { $this->parallelLint($collection, $chunk); } $collection->run(); } /** * Run mutation tests with humbug * * @param bool $stats - if true, generates stats rather than running mutation tests */ public function mutate($stats = FALSE) { $test_parts = [ 'vendor/bin/humbug' ]; $stat_parts = [ 'vendor/bin/humbug', '--skip-killed=yes', '-v', './build/humbug.json' ]; $cmd_parts = ($stats) ? $stat_parts : $test_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', '--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() { $this->clean(); array_map([$this, '_mkdir'], $this->taskDirs); } /** * Lint php files and run unit tests */ public function test() { $this->lint(); $this->taskPHPUnit() ->configFile('phpunit.xml') ->printed(true) ->run(); } /** * 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(); })->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('tests/*.php'), glob('*.php') ); sort($files); return $files; } /** * Run php's linter in one parallel task for the passed chunk * * @param Collection $collection * @param array $chunk */ protected function parallelLint($collection, array $chunk) { $task = $this->taskParallelExec(); foreach($chunk as $file) { $task = $task->process("php -l {$file}"); } $task->addToCollection($collection); } /** * 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); } /** * Short cut 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->_exec(implode($join_on, $cmd_parts)); } }