rector/packages/ChangesReporting/Output/ConsoleOutputFormatter.php

155 lines
6.6 KiB
PHP
Raw Normal View History

2019-10-13 05:59:52 +00:00
<?php
declare (strict_types=1);
2020-03-19 00:07:07 +00:00
namespace Rector\ChangesReporting\Output;
2017-10-22 14:31:29 +00:00
use RectorPrefix20210510\Nette\Utils\Strings;
use Rector\ChangesReporting\Annotation\RectorsChangelogResolver;
2020-03-19 00:07:07 +00:00
use Rector\ChangesReporting\Contract\Output\OutputFormatterInterface;
use Rector\Core\Configuration\Configuration;
use Rector\Core\Configuration\Option;
use Rector\Core\Contract\Console\OutputStyleInterface;
2020-05-03 19:17:42 +00:00
use Rector\Core\ValueObject\Application\RectorError;
use Rector\Core\ValueObject\ProcessResult;
use Rector\Core\ValueObject\Reporting\FileDiff;
final class ConsoleOutputFormatter implements \Rector\ChangesReporting\Contract\Output\OutputFormatterInterface
2017-10-22 14:31:29 +00:00
{
/**
* @var string
*/
public const NAME = 'console';
/**
* @var string
* @see https://regex101.com/r/q8I66g/1
*/
private const ON_LINE_REGEX = '# on line #';
2017-10-22 14:31:29 +00:00
/**
* @var OutputStyleInterface
2017-10-22 14:31:29 +00:00
*/
private $outputStyle;
2019-08-10 07:28:27 +00:00
/**
* @var Configuration
2019-08-10 07:28:27 +00:00
*/
private $configuration;
/**
* @var RectorsChangelogResolver
*/
private $rectorsChangelogResolver;
public function __construct(\Rector\Core\Configuration\Configuration $configuration, \Rector\Core\Contract\Console\OutputStyleInterface $outputStyle, \Rector\ChangesReporting\Annotation\RectorsChangelogResolver $rectorsChangelogResolver)
{
$this->outputStyle = $outputStyle;
$this->configuration = $configuration;
$this->rectorsChangelogResolver = $rectorsChangelogResolver;
2017-10-22 14:31:29 +00:00
}
public function report(\Rector\Core\ValueObject\ProcessResult $processResult) : void
{
2020-01-17 13:54:37 +00:00
if ($this->configuration->getOutputFile()) {
$message = \sprintf('Option "--%s" can be used only with "--%s %s"', \Rector\Core\Configuration\Option::OPTION_OUTPUT_FILE, \Rector\Core\Configuration\Option::OPTION_OUTPUT_FORMAT, 'json');
$this->outputStyle->error($message);
2020-01-17 09:02:46 +00:00
}
if ($this->configuration->shouldShowDiffs()) {
$this->reportFileDiffs($processResult->getFileDiffs());
}
$this->reportErrors($processResult->getErrors());
$this->reportRemovedFilesAndNodes($processResult);
if ($processResult->getErrors() !== []) {
return;
}
$message = $this->createSuccessMessage($processResult);
$this->outputStyle->success($message);
}
public function getName() : string
{
return self::NAME;
}
/**
2018-02-08 15:51:16 +00:00
* @param FileDiff[] $fileDiffs
*/
private function reportFileDiffs(array $fileDiffs) : void
{
if (\count($fileDiffs) <= 0) {
return;
}
// normalize
\ksort($fileDiffs);
$message = \sprintf('%d file%s with changes', \count($fileDiffs), \count($fileDiffs) === 1 ? '' : 's');
$this->outputStyle->title($message);
$i = 0;
2018-02-08 15:51:16 +00:00
foreach ($fileDiffs as $fileDiff) {
2019-05-28 20:38:21 +00:00
$relativeFilePath = $fileDiff->getRelativeFilePath();
$message = \sprintf('<options=bold>%d) %s</>', ++$i, $relativeFilePath);
$this->outputStyle->writeln($message);
$this->outputStyle->newLine();
$this->outputStyle->writeln($fileDiff->getDiffConsoleFormatted());
$rectorsChangelogsLines = $this->createRectorChangelogLines($fileDiff);
2020-03-19 00:07:07 +00:00
if ($fileDiff->getRectorChanges() !== []) {
$this->outputStyle->writeln('<options=underscore>Applied rules:</>');
$this->outputStyle->listing($rectorsChangelogsLines);
$this->outputStyle->newLine();
2018-11-05 01:27:48 +00:00
}
}
}
2018-09-17 10:38:11 +00:00
/**
2020-05-03 19:17:42 +00:00
* @param RectorError[] $errors
2018-09-17 10:38:11 +00:00
*/
private function reportErrors(array $errors) : void
2018-09-17 10:38:11 +00:00
{
foreach ($errors as $error) {
$errorMessage = $error->getMessage();
$errorMessage = $this->normalizePathsToRelativeWithLine($errorMessage);
$message = \sprintf('Could not process "%s" file%s, due to: %s"%s".', $error->getRelativeFilePath(), $error->getRectorClass() ? ' by "' . $error->getRectorClass() . '"' : '', \PHP_EOL, $errorMessage);
2018-09-17 10:38:11 +00:00
if ($error->getLine()) {
$message .= ' On line: ' . $error->getLine();
}
$this->outputStyle->error($message);
2018-09-17 10:38:11 +00:00
}
}
private function reportRemovedFilesAndNodes(\Rector\Core\ValueObject\ProcessResult $processResult) : void
2019-08-06 07:37:31 +00:00
{
if ($processResult->getAddedFilesCount() !== 0) {
$message = \sprintf('%d files were added', $processResult->getAddedFilesCount());
$this->outputStyle->note($message);
}
if ($processResult->getRemovedFilesCount() !== 0) {
$message = \sprintf('%d files were removed', $processResult->getRemovedFilesCount());
$this->outputStyle->note($message);
2019-08-06 07:37:31 +00:00
}
$this->reportRemovedNodes($processResult);
2019-08-10 07:28:27 +00:00
}
private function normalizePathsToRelativeWithLine(string $errorMessage) : string
{
$regex = '#' . \preg_quote(\getcwd(), '#') . '/#';
$errorMessage = \RectorPrefix20210510\Nette\Utils\Strings::replace($errorMessage, $regex, '');
return \RectorPrefix20210510\Nette\Utils\Strings::replace($errorMessage, self::ON_LINE_REGEX, ':');
}
private function reportRemovedNodes(\Rector\Core\ValueObject\ProcessResult $processResult) : void
2019-08-10 07:28:27 +00:00
{
if ($processResult->getRemovedNodeCount() === 0) {
2019-08-10 07:28:27 +00:00
return;
}
$message = \sprintf('%d nodes were removed', $processResult->getRemovedNodeCount());
$this->outputStyle->warning($message);
2019-08-10 07:28:27 +00:00
}
private function createSuccessMessage(\Rector\Core\ValueObject\ProcessResult $processResult) : string
{
$changeCount = \count($processResult->getFileDiffs()) + $processResult->getRemovedAndAddedFilesCount();
if ($changeCount === 0) {
return 'Rector is done!';
}
return \sprintf('%d file%s %s by Rector', $changeCount, $changeCount > 1 ? 's' : '', $this->configuration->isDryRun() ? 'would have changed (dry-run)' : ($changeCount === 1 ? 'has' : 'have') . ' been changed');
}
/**
* @return string[]
*/
private function createRectorChangelogLines(\Rector\Core\ValueObject\Reporting\FileDiff $fileDiff) : array
{
$rectorsChangelogs = $this->rectorsChangelogResolver->resolveIncludingMissing($fileDiff->getRectorClasses());
$rectorsChangelogsLines = [];
foreach ($rectorsChangelogs as $rectorClass => $changelog) {
$rectorShortClass = (string) \RectorPrefix20210510\Nette\Utils\Strings::after($rectorClass, '\\', -1);
2021-04-12 19:16:36 +00:00
$rectorsChangelogsLines[] = $changelog === null ? $rectorShortClass : $rectorShortClass . ' (' . $changelog . ')';
}
return $rectorsChangelogsLines;
}
2017-10-22 14:31:29 +00:00
}