diff --git a/src/ChangesReporting/Output/Factory/JsonOutputFactory.php b/src/ChangesReporting/Output/Factory/JsonOutputFactory.php new file mode 100644 index 00000000000..aa75152d3ab --- /dev/null +++ b/src/ChangesReporting/Output/Factory/JsonOutputFactory.php @@ -0,0 +1,85 @@ + [ + 'changed_files' => $processResult->getTotalChanged(), + ], + ]; + + // We need onlyWithChanges: false to include all file diffs + $fileDiffs = $processResult->getFileDiffs(onlyWithChanges: false); + ksort($fileDiffs); + foreach ($fileDiffs as $fileDiff) { + $filePath = $configuration->isReportingWithRealPath() + ? ($fileDiff->getAbsoluteFilePath() ?? '') + : $fileDiff->getRelativeFilePath() + ; + + if ($configuration->shouldShowDiffs() && $fileDiff->getDiff() !== '') { + $errorsJson[Bridge::FILE_DIFFS][] = [ + 'file' => $filePath, + 'diff' => $fileDiff->getDiff(), + 'applied_rectors' => $fileDiff->getRectorClasses(), + ]; + } + + // for Rector CI + $errorsJson['changed_files'][] = $filePath; + } + + $systemErrors = $processResult->getSystemErrors(); + $errorsJson['totals']['errors'] = count($systemErrors); + + $errorsData = self::createErrorsData($systemErrors, $configuration->isReportingWithRealPath()); + if ($errorsData !== []) { + $errorsJson['errors'] = $errorsData; + } + + return Json::encode($errorsJson, pretty: true); + } + + /** + * @param SystemError[] $errors + * @return mixed[] + */ + private static function createErrorsData(array $errors, bool $absoluteFilePath): array + { + $errorsData = []; + + foreach ($errors as $error) { + $errorDataJson = [ + 'message' => $error->getMessage(), + 'file' => $absoluteFilePath ? $error->getAbsoluteFilePath() : $error->getRelativeFilePath(), + ]; + + if ($error->getRectorClass() !== null) { + $errorDataJson['caused_by'] = $error->getRectorClass(); + } + + if ($error->getLine() !== null) { + $errorDataJson['line'] = $error->getLine(); + } + + $errorsData[] = $errorDataJson; + } + + return $errorsData; + } +} diff --git a/src/ChangesReporting/Output/JsonOutputFormatter.php b/src/ChangesReporting/Output/JsonOutputFormatter.php index 65062a4bb8e..7064487d25c 100644 --- a/src/ChangesReporting/Output/JsonOutputFormatter.php +++ b/src/ChangesReporting/Output/JsonOutputFormatter.php @@ -4,11 +4,9 @@ namespace Rector\ChangesReporting\Output; -use Nette\Utils\Json; use Rector\ChangesReporting\Contract\Output\OutputFormatterInterface; -use Rector\Parallel\ValueObject\Bridge; +use Rector\ChangesReporting\Output\Factory\JsonOutputFactory; use Rector\ValueObject\Configuration; -use Rector\ValueObject\Error\SystemError; use Rector\ValueObject\ProcessResult; final readonly class JsonOutputFormatter implements OutputFormatterInterface @@ -25,67 +23,6 @@ public function getName(): string public function report(ProcessResult $processResult, Configuration $configuration): void { - $errorsJson = [ - 'totals' => [ - 'changed_files' => $processResult->getTotalChanged(), - ], - ]; - - $fileDiffs = $processResult->getFileDiffs(); - ksort($fileDiffs); - foreach ($fileDiffs as $fileDiff) { - $filePath = $configuration->isReportingWithRealPath() - ? ($fileDiff->getAbsoluteFilePath() ?? '') - : $fileDiff->getRelativeFilePath() - ; - - $errorsJson[Bridge::FILE_DIFFS][] = [ - 'file' => $filePath, - 'diff' => $fileDiff->getDiff(), - 'applied_rectors' => $fileDiff->getRectorClasses(), - ]; - - // for Rector CI - $errorsJson['changed_files'][] = $filePath; - } - - $systemErrors = $processResult->getSystemErrors(); - $errorsJson['totals']['errors'] = count($systemErrors); - - $errorsData = $this->createErrorsData($systemErrors, $configuration->isReportingWithRealPath()); - if ($errorsData !== []) { - $errorsJson['errors'] = $errorsData; - } - - $json = Json::encode($errorsJson, pretty: true); - echo $json . PHP_EOL; - } - - /** - * @param SystemError[] $errors - * @return mixed[] - */ - private function createErrorsData(array $errors, bool $absoluteFilePath): array - { - $errorsData = []; - - foreach ($errors as $error) { - $errorDataJson = [ - 'message' => $error->getMessage(), - 'file' => $absoluteFilePath ? $error->getAbsoluteFilePath() : $error->getRelativeFilePath(), - ]; - - if ($error->getRectorClass() !== null) { - $errorDataJson['caused_by'] = $error->getRectorClass(); - } - - if ($error->getLine() !== null) { - $errorDataJson['line'] = $error->getLine(); - } - - $errorsData[] = $errorDataJson; - } - - return $errorsData; + echo JsonOutputFactory::create($processResult, $configuration) . PHP_EOL; } } diff --git a/tests/ChangesReporting/Output/Factory/JsonOutputFactoryTest.php b/tests/ChangesReporting/Output/Factory/JsonOutputFactoryTest.php new file mode 100644 index 00000000000..5f7a467b910 --- /dev/null +++ b/tests/ChangesReporting/Output/Factory/JsonOutputFactoryTest.php @@ -0,0 +1,47 @@ +assertSame($expectedOutput, $actualOutput); + } +} diff --git a/tests/ChangesReporting/Output/Fixtures/without_diffs.json b/tests/ChangesReporting/Output/Fixtures/without_diffs.json new file mode 100644 index 00000000000..d15f37f36de --- /dev/null +++ b/tests/ChangesReporting/Output/Fixtures/without_diffs.json @@ -0,0 +1,17 @@ +{ + "totals": { + "changed_files": 2, + "errors": 1 + }, + "changed_files": [ + "some/file.php", + "some/file_foo.php" + ], + "errors": [ + { + "message": "Some error message", + "file": "some/file.php", + "line": 1 + } + ] +} \ No newline at end of file