diff --git a/.travis.yml b/.travis.yml index 6b88f2be..22c523c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,7 @@ install: - if [[ ${TRAVIS_PHP_VERSION:0:3} == "7.1" ]]; then composer update && composer require sebastian/phpcpd:dev-master && bin/suggested-tools.sh install; fi script: - vendor/phpunit/phpunit/phpunit + - ./phpqa tools - bin/ci.sh # http://blog.wyrihaximus.net/2015/07/composer-cache-on-travis/ cache: diff --git a/src/CodeAnalysisTasks.php b/src/CodeAnalysisTasks.php index ba36e7c2..01666d82 100644 --- a/src/CodeAnalysisTasks.php +++ b/src/CodeAnalysisTasks.php @@ -8,34 +8,41 @@ trait CodeAnalysisTasks private $tools = array( 'phpmetrics' => array( 'optionSeparator' => ' ', + 'composer' => 'phpmetrics/phpmetrics', ), 'phploc' => array( 'optionSeparator' => ' ', 'xml' => ['phploc.xml'], + 'composer' => 'phploc/phploc', ), 'phpcs' => array( 'optionSeparator' => '=', 'xml' => ['checkstyle.xml'], 'errorsXPath' => '//checkstyle/file/error', + 'composer' => 'squizlabs/php_codesniffer', ), 'phpmd' => array( 'optionSeparator' => ' ', 'xml' => ['phpmd.xml'], 'errorsXPath' => '//pmd/file/violation', + 'composer' => 'phpmd/phpmd', ), 'pdepend' => array( 'optionSeparator' => '=', 'xml' => ['pdepend-jdepend.xml', 'pdepend-summary.xml', 'pdepend-dependencies.xml'], + 'composer' => 'pdepend/pdepend', ), 'phpcpd' => array( 'optionSeparator' => ' ', 'xml' => ['phpcpd.xml'], 'errorsXPath' => '//pmd-cpd/duplication', + 'composer' => 'sebastian/phpcpd', ), 'parallel-lint' => array( 'optionSeparator' => ' ', 'internalClass' => 'JakubOnderka\PhpParallelLint\ParallelLint', 'hasOnlyConsoleOutput' => true, + 'composer' => 'jakub-onderka/php-parallel-lint', ), ); /** @var Options */ @@ -50,17 +57,8 @@ trait CodeAnalysisTasks */ public function tools() { - $this->yell("phpqa v" . PHPQA_VERSION); - foreach (array_keys($this->tools) as $tool) { - if ($tool == 'parallel-lint') { - $task = $this->taskExec(pathToBinary("{$tool}")) - ->printed(false) - ->run(); - $this->getOutput()->writeln(strtok($task->getMessage(), "\n")); - } else { - $this->_exec(pathToBinary("{$tool} --version")); - } - } + $tools = new Task\ToolVersions($this->getOutput()); + $tools($this->tools); } /** diff --git a/src/Task/ToolVersions.php b/src/Task/ToolVersions.php new file mode 100644 index 00000000..1e38f6bb --- /dev/null +++ b/src/Task/ToolVersions.php @@ -0,0 +1,133 @@ +output = $p; + } + + public function __invoke(array $qaTools) + { + $composerPackages = $this->findComposerPackages(); + if ($composerPackages) { + $this->composerInfo($qaTools, $composerPackages); + } else { + $this->consoleInfo(array_keys($qaTools)); + } + } + + private function findComposerPackages() + { + $installedJson = COMPOSER_BINARY_DIR . '/../composer/installed.json'; + if (!is_file($installedJson)) { + return []; + } + + $installedTools = json_decode(file_get_contents($installedJson)); + if (!is_array($installedTools)) { + return []; + } + + $tools = array(); + foreach ($installedTools as $tool) { + $tools[$tool->name] = $tool; + } + + return $tools + [ + 'edgedesign/phpqa' => (object) [ + 'version_normalized' => PHPQA_VERSION, + 'authors' => [(object) ['name' => "Zdeněk Drahoš"]], + ] + ]; + } + + private function composerInfo(array $qaTools, array $composerPackages) + { + $table = new Table($this->output); + $table->setHeaders(['Tool', 'Version', 'Authors']); + $table->addRow($this->toolToTableRow('phpqa', 'edgedesign/phpqa', $composerPackages)); + foreach ($qaTools as $tool => $config) { + $table->addRow($this->toolToTableRow($tool, $config['composer'], $composerPackages)); + } + $table->render(); + } + + private function toolToTableRow($tool, $composerPackage, array $composerPackages) + { + $composerInfo = array_key_exists($composerPackage, $composerPackages) ? + get_object_vars($composerPackages[$composerPackage]) : + [ + 'version' => '', + 'version_normalized' => 'not installed', + 'authors' => [(object) ['name' => "composer require {$composerPackage}"]], + ]; + $composerInfo += [ + 'version_normalized' => '', + 'authors' => [(object) ['name' => '']], + ]; + + return array( + "{$tool}", + $this->normalizeVersion($composerInfo), + $this->groupAuthors($composerInfo['authors']) + ); + } + + private function normalizeVersion(array $composerInfo) + { + if ($composerInfo['version_normalized'] == '9999999-dev') { + return $composerInfo['version']; + } + return preg_replace('/\.0$/s', '', $composerInfo['version_normalized']); + } + + private function groupAuthors(array $composerAuthors) + { + return implode( + ',', + array_map( + function ($author) { + return $author->name; + }, + $composerAuthors + ) + ); + } + + private function consoleInfo(array $tools) + { + $this->output->writeln([ + 'phpqa ' . PHPQA_VERSION . '', + '', + ]); + + foreach ($tools as $tool) { + $versionCommand = $tool == 'parallel-lint' ? $tool : "{$tool} --version"; + $this->loadVersionFromConsoleCommand($versionCommand); + } + } + + private function loadVersionFromConsoleCommand($command) + { + $exec = new Exec(\Edge\QA\pathToBinary($command)); + $result = $exec + ->printed(false) + ->run() + ->getMessage(); + $this->output->writeln($this->getFirstLine($result)); + } + + private function getFirstLine($string) + { + return strtok($string, "\n"); + } +}