diff --git a/src/Tools/Analyzer/Phpcpd.php b/src/Tools/Analyzer/Phpcpd.php index 53e3ee2..e788803 100644 --- a/src/Tools/Analyzer/Phpcpd.php +++ b/src/Tools/Analyzer/Phpcpd.php @@ -2,8 +2,6 @@ namespace Edge\QA\Tools\Analyzer; -use Edge\QA\Tools\GetVersions; - class Phpcpd extends \Edge\QA\Tools\Tool { public static $SETTINGS = array( diff --git a/src/Tools/Analyzer/Phpstan.php b/src/Tools/Analyzer/Phpstan.php index 9e36c23..b17f6c6 100644 --- a/src/Tools/Analyzer/Phpstan.php +++ b/src/Tools/Analyzer/Phpstan.php @@ -3,7 +3,6 @@ namespace Edge\QA\Tools\Analyzer; use Edge\QA\OutputMode; -use Edge\QA\Tools\GetVersions; class Phpstan extends \Edge\QA\Tools\Tool { diff --git a/src/Tools/GetVersions.php b/src/Tools/GetVersions.php index 31089bf..894d2d7 100644 --- a/src/Tools/GetVersions.php +++ b/src/Tools/GetVersions.php @@ -6,10 +6,11 @@ class GetVersions { - public function getToolVersion(array $toolSettings) + public function hasToolVersion(array $toolSettings, $operator, $version) { - $versions = $this->__invoke(['tool' => $toolSettings + ['customBinary' => null]]); - return $versions['tool']['version_normalized']; + $versions = $this->__invoke(['tool' => $toolSettings]); + $toolVersion = $versions['tool']['version_normalized']; + return self::compareVersions($toolVersion, $operator, $version); } public function __invoke(array $tools) @@ -114,7 +115,7 @@ private function normalizeVersion(array $composerInfo) if ($composerInfo['version_normalized'] == '9999999-dev') { return $composerInfo['version']; } - return preg_replace('/\.0$/s', '', $composerInfo['version_normalized']); + return self::normalizeSemver($composerInfo['version_normalized']); } private function groupAuthors(array $composerAuthors) @@ -134,8 +135,12 @@ private function loadVersionFromConsoleCommand($command) { $process = $this->createSymfonyProcess($command); $process->run(); - $firstLine = $this->getFirstLine($process->getOutput()); - return $this->extractVersion($firstLine); + if ($process->getOutput()) { + return self::extractVersionFromConsole($process->getOutput()); + } elseif ($process->getErrorOutput()) { + return trim($process->getErrorOutput()); + } + return "{$process->getExitCode()} {$process->getExitCodeText()}"; } private function createSymfonyProcess($command) @@ -147,20 +152,29 @@ private function createSymfonyProcess($command) } } - private function getFirstLine($string) + public static function extractVersionFromConsole($text) { - return strtok($string, "\n"); + $regexes = [ + 'semver' => '(\d+\.\d+(\.\d+)?)', + 'dev version' => '(\d+\.x)', + ]; + foreach ($regexes as $regex) { + $match = []; + preg_match($regex, $text, $match); + if ($match) { + return self::normalizeSemver($match[0]); + } + } + return $text; } - private function extractVersion($text) + public static function normalizeSemver($semver) { - return str_replace( - array( - ' by Sebastian Bergmann and contributors.', - 'PHPUnit ' - ), - '', - $text - ); + return preg_replace('/\.0$/s', '', $semver); + } + + public static function compareVersions($toolVersion, $operator, $version) + { + return $toolVersion && version_compare(str_replace(".x", "", $toolVersion), $version, $operator); } } diff --git a/src/Tools/Tool.php b/src/Tools/Tool.php index df9b0ab..a3c07fc 100644 --- a/src/Tools/Tool.php +++ b/src/Tools/Tool.php @@ -38,8 +38,10 @@ protected function saveDynamicConfig($config, $fileExtension) protected function toolVersionIs($operator, $version) { $versions = new GetVersions(); - $composerVersion = $versions->getToolVersion(static::$SETTINGS); - return $composerVersion && version_compare($composerVersion, $version, $operator); + $settings = static::$SETTINGS + [ + 'customBinary' => $this->config->getCustomBinary((string) $this->tool), + ]; + return $versions->hasToolVersion($settings, $operator, $version); } protected function writeln($text) diff --git a/tests/GetVersionsTest.php b/tests/GetVersionsTest.php new file mode 100644 index 0000000..4b73b1a --- /dev/null +++ b/tests/GetVersionsTest.php @@ -0,0 +1,59 @@ + ['2.7.4', '2.7.4'], + 'minor release' => ['2.7.0', '2.7'], + 'major release' => ['2.0.0', '2.0'], + ]; + } + + /** @dataProvider provideCliVersion */ + public function testCliVersion($cliOutput, $expectedVersion) + { + assertThat(GetVersions::extractVersionFromConsole($cliOutput), is($expectedVersion)); + } + + public function provideCliVersion() + { + return [ + 'semver at the end' => ['irrelevant 0.12.86', '0.12.86'], + 'semver at the start' => ['0.12.86 irrelevant', '0.12.86'], + 'semver at 2nd line' => ["first\nirrele 4.8.36 vant\nsecond", '4.8.36'], + 'custom format' => ['irrelevant v1.10', '1.10'], + 'no space' => ['v1.13.7irrelevant', '1.13.7'], + 'dev version' => ['irrelevant 4.x-dev@', '4.x'], + 'prefer semver (semver + dev)' => ['v1.13.7 4.x-dev@', '1.13.7'], + 'prefer semver (dev + semver)' => ['4.x-dev@ v1.13.7', '1.13.7'], + 'no version' => ['irrelevant text', 'irrelevant text'], + ]; + } + + /** @dataProvider provideComparedVersions */ + public function testCompareVersions($toolVersion, $operator, $version, $expectedResult) + { + assertThat(GetVersions::compareVersions($toolVersion, $operator, $version), is($expectedResult)); + } + + public function provideComparedVersions() + { + return [ + 'no version' => ['', '>', '1', false], + 'is lower?' => ['7', '<', '6', false], + 'is greater than dev version' => ['4', '>=', '4.x', true], + 'semver is greater than' => ['4.1', '>=', '4', true], + 'dev version is greater than' => ['4.x', '>=', '4', true], + ]; + } +}