2017-02-17 08:25:19 -05:00
|
|
|
<?php declare(strict_types=1);
|
2019-12-05 16:59:24 -05:00
|
|
|
|
2017-02-17 08:25:19 -05:00
|
|
|
use Robo\Tasks;
|
|
|
|
|
2016-08-09 11:08:45 -04:00
|
|
|
if ( ! function_exists('glob_recursive'))
|
|
|
|
{
|
|
|
|
// Does not support flag GLOB_BRACE
|
|
|
|
function glob_recursive($pattern, $flags = 0)
|
|
|
|
{
|
|
|
|
$files = glob($pattern, $flags);
|
|
|
|
|
|
|
|
foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir)
|
|
|
|
{
|
|
|
|
$files = array_merge($files, glob_recursive($dir.'/'.basename($pattern), $flags));
|
|
|
|
}
|
|
|
|
|
|
|
|
return $files;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This is project's console commands configuration for Robo task runner.
|
|
|
|
*
|
|
|
|
* @see http://robo.li/
|
|
|
|
*/
|
2017-02-17 08:25:19 -05:00
|
|
|
class RoboFile extends Tasks {
|
2016-08-29 15:50:59 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Directories used by analysis tools
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
2016-08-09 11:08:45 -04:00
|
|
|
protected $taskDirs = [
|
|
|
|
'build/logs',
|
|
|
|
'build/pdepend',
|
|
|
|
'build/phpdox',
|
|
|
|
];
|
|
|
|
|
2016-08-29 15:50:59 -04:00
|
|
|
/**
|
|
|
|
* Directories to remove with the clean task
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
protected $cleanDirs = [
|
|
|
|
'coverage',
|
|
|
|
'docs',
|
|
|
|
'phpdoc',
|
|
|
|
'build/logs',
|
|
|
|
'build/phpdox',
|
|
|
|
'build/pdepend'
|
|
|
|
];
|
|
|
|
|
2016-08-09 11:08:45 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Do static analysis tasks
|
|
|
|
*/
|
2019-12-06 10:05:09 -05:00
|
|
|
public function analyze(): void
|
2016-08-09 11:08:45 -04:00
|
|
|
{
|
|
|
|
$this->prepare();
|
|
|
|
$this->lint();
|
|
|
|
$this->phploc(TRUE);
|
2016-08-29 15:50:59 -04:00
|
|
|
$this->phpcs(TRUE);
|
2020-03-13 09:53:31 -04:00
|
|
|
$this->phpmd(TRUE);
|
2016-08-09 11:08:45 -04:00
|
|
|
$this->dependencyReport();
|
|
|
|
$this->phpcpdReport();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run all tests, generate coverage, generate docs, generate code statistics
|
|
|
|
*/
|
2019-12-06 10:05:09 -05:00
|
|
|
public function build(): void
|
2016-08-09 11:08:45 -04:00
|
|
|
{
|
|
|
|
$this->analyze();
|
|
|
|
$this->coverage();
|
|
|
|
$this->docs();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Cleanup temporary files
|
|
|
|
*/
|
2019-12-06 10:05:09 -05:00
|
|
|
public function clean(): void
|
2016-08-09 11:08:45 -04:00
|
|
|
{
|
|
|
|
$cleanFiles = [
|
|
|
|
'build/humbug.json',
|
|
|
|
'build/humbug-log.txt',
|
|
|
|
];
|
2019-12-06 10:05:09 -05:00
|
|
|
array_map(static function ($file) {
|
2016-08-09 11:08:45 -04:00
|
|
|
@unlink($file);
|
|
|
|
}, $cleanFiles);
|
|
|
|
|
2016-08-29 15:50:59 -04:00
|
|
|
// So the task doesn't complain,
|
|
|
|
// make any 'missing' dirs to cleanup
|
2019-12-06 10:05:09 -05:00
|
|
|
array_map(static function ($dir) {
|
2016-08-29 15:50:59 -04:00
|
|
|
if ( ! is_dir($dir))
|
|
|
|
{
|
|
|
|
`mkdir -p {$dir}`;
|
|
|
|
}
|
|
|
|
}, $this->cleanDirs);
|
|
|
|
|
|
|
|
$this->_cleanDir($this->cleanDirs);
|
|
|
|
$this->_deleteDir($this->cleanDirs);
|
2016-08-09 11:08:45 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run unit tests and generate coverage reports
|
|
|
|
*/
|
2019-12-06 10:05:09 -05:00
|
|
|
public function coverage(): void
|
2016-08-09 11:08:45 -04:00
|
|
|
{
|
2017-03-27 10:09:45 -04:00
|
|
|
$this->_run(['phpdbg -qrr -- vendor/bin/phpunit -c build']);
|
2016-08-09 11:08:45 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generate documentation with phpdox
|
|
|
|
*/
|
2019-12-06 10:05:09 -05:00
|
|
|
public function docs(): void
|
2016-08-09 11:08:45 -04:00
|
|
|
{
|
|
|
|
$cmd_parts = [
|
2017-03-27 10:09:45 -04:00
|
|
|
'vendor/bin/phpdox',
|
2016-08-09 11:08:45 -04:00
|
|
|
];
|
|
|
|
$this->_run($cmd_parts, ' && ');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Verify that source files are valid
|
|
|
|
*/
|
2019-12-06 10:05:09 -05:00
|
|
|
public function lint(): void
|
2016-08-09 11:08:45 -04:00
|
|
|
{
|
|
|
|
$files = $this->getAllSourceFiles();
|
|
|
|
|
2020-04-07 21:53:53 -04:00
|
|
|
$chunks = array_chunk($files, (int)shell_exec('getconf _NPROCESSORS_ONLN'));
|
2016-08-09 11:08:45 -04:00
|
|
|
|
|
|
|
foreach($chunks as $chunk)
|
|
|
|
{
|
2016-08-30 11:45:17 -04:00
|
|
|
$this->parallelLint($chunk);
|
2016-08-09 11:08:45 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-29 15:50:59 -04:00
|
|
|
/**
|
|
|
|
* Run the phpcs tool
|
|
|
|
*
|
|
|
|
* @param bool $report - if true, generates reports instead of direct output
|
|
|
|
*/
|
2019-12-06 10:05:09 -05:00
|
|
|
public function phpcs($report = FALSE): void
|
2016-08-29 15:50:59 -04:00
|
|
|
{
|
|
|
|
$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);
|
|
|
|
}
|
|
|
|
|
2020-03-13 09:53:31 -04:00
|
|
|
public function phpmd($report = FALSE): void
|
|
|
|
{
|
|
|
|
$report_cmd_parts = [
|
|
|
|
'vendor/bin/phpmd',
|
|
|
|
'./src',
|
|
|
|
'xml',
|
|
|
|
'cleancode,codesize,controversial,design,naming,unusedcode',
|
|
|
|
'--exclude ParallelAPIRequest',
|
|
|
|
'--reportfile ./build/logs/phpmd.xml'
|
|
|
|
];
|
|
|
|
|
|
|
|
$normal_cmd_parts = [
|
|
|
|
'vendor/bin/phpmd',
|
|
|
|
'./src',
|
|
|
|
'ansi',
|
|
|
|
'cleancode,codesize,controversial,design,naming,unusedcode',
|
|
|
|
'--exclude ParallelAPIRequest'
|
|
|
|
];
|
|
|
|
|
|
|
|
$cmd_parts = ($report) ? $report_cmd_parts : $normal_cmd_parts;
|
|
|
|
|
|
|
|
$this->_run($cmd_parts);
|
|
|
|
}
|
|
|
|
|
2016-08-09 11:08:45 -04:00
|
|
|
/**
|
|
|
|
* Run the phploc tool
|
|
|
|
*
|
|
|
|
* @param bool $report - if true, generates reports instead of direct output
|
|
|
|
*/
|
2019-12-06 10:05:09 -05:00
|
|
|
public function phploc($report = FALSE): void
|
2016-08-09 11:08:45 -04:00
|
|
|
{
|
|
|
|
// Command for generating reports
|
|
|
|
$report_cmd_parts = [
|
|
|
|
'vendor/bin/phploc',
|
2016-08-29 15:50:59 -04:00
|
|
|
'--count-tests',
|
2016-08-09 11:08:45 -04:00
|
|
|
'--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
|
|
|
|
*/
|
2019-12-06 10:05:09 -05:00
|
|
|
public function prepare(): void
|
2016-08-09 11:08:45 -04:00
|
|
|
{
|
|
|
|
array_map([$this, '_mkdir'], $this->taskDirs);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Lint php files and run unit tests
|
|
|
|
*/
|
2019-12-06 10:05:09 -05:00
|
|
|
public function test(): void
|
2016-08-09 11:08:45 -04:00
|
|
|
{
|
|
|
|
$this->lint();
|
|
|
|
|
2019-12-05 16:59:24 -05:00
|
|
|
$this->_run(['phpunit']);
|
2016-08-09 11:08:45 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create pdepend reports
|
|
|
|
*/
|
2019-12-06 10:05:09 -05:00
|
|
|
protected function dependencyReport(): void
|
2016-08-09 11:08:45 -04:00
|
|
|
{
|
|
|
|
$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
|
|
|
|
*/
|
2019-12-06 10:05:09 -05:00
|
|
|
protected function getAllSourceFiles(): array
|
2016-08-09 11:08:45 -04:00
|
|
|
{
|
|
|
|
$files = array_merge(
|
|
|
|
glob_recursive('build/*.php'),
|
|
|
|
glob_recursive('src/*.php'),
|
2017-02-17 08:25:19 -05:00
|
|
|
glob_recursive('src/**/*.php'),
|
2016-08-09 11:08:45 -04:00
|
|
|
glob_recursive('tests/*.php'),
|
2017-02-17 08:25:19 -05:00
|
|
|
glob_recursive('tests/**/*.php'),
|
2016-08-09 11:08:45 -04:00
|
|
|
glob('*.php')
|
|
|
|
);
|
|
|
|
|
2020-03-13 09:53:31 -04:00
|
|
|
$files = array_filter($files, static function(string $value) {
|
|
|
|
return strpos($value, '__snapshots__') === FALSE;
|
|
|
|
});
|
|
|
|
|
2016-08-09 11:08:45 -04:00
|
|
|
sort($files);
|
|
|
|
|
|
|
|
return $files;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run php's linter in one parallel task for the passed chunk
|
|
|
|
*
|
|
|
|
* @param array $chunk
|
|
|
|
*/
|
2019-12-06 10:05:09 -05:00
|
|
|
protected function parallelLint(array $chunk): void
|
2016-08-09 11:08:45 -04:00
|
|
|
{
|
2016-08-30 11:45:17 -04:00
|
|
|
$task = $this->taskParallelExec()
|
|
|
|
->timeout(5)
|
|
|
|
->printed(FALSE);
|
2016-08-09 11:08:45 -04:00
|
|
|
|
|
|
|
foreach($chunk as $file)
|
|
|
|
{
|
|
|
|
$task = $task->process("php -l {$file}");
|
|
|
|
}
|
|
|
|
|
2016-08-30 11:45:17 -04:00
|
|
|
$task->run();
|
2016-08-09 11:08:45 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generate copy paste detector report
|
|
|
|
*/
|
2019-12-06 10:05:09 -05:00
|
|
|
protected function phpcpdReport(): void
|
2016-08-09 11:08:45 -04:00
|
|
|
{
|
|
|
|
$cmd_parts = [
|
|
|
|
'vendor/bin/phpcpd',
|
|
|
|
'--log-pmd build/logs/pmd-cpd.xml',
|
|
|
|
'src'
|
|
|
|
];
|
|
|
|
$this->_run($cmd_parts);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2016-08-29 15:50:59 -04:00
|
|
|
* Shortcut for joining an array of command arguments
|
2016-08-09 11:08:45 -04:00
|
|
|
* and then running it
|
|
|
|
*
|
|
|
|
* @param array $cmd_parts - command arguments
|
|
|
|
* @param string $join_on - what to join the command arguments with
|
|
|
|
*/
|
2019-12-06 10:05:09 -05:00
|
|
|
protected function _run(array $cmd_parts, $join_on = ' '): void
|
2016-08-09 11:08:45 -04:00
|
|
|
{
|
2016-08-30 11:45:17 -04:00
|
|
|
$this->taskExec(implode($join_on, $cmd_parts))->run();
|
2016-08-09 11:08:45 -04:00
|
|
|
}
|
|
|
|
}
|