Skip to content

Commit

Permalink
[Console] Move color differ here (#2887)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed Sep 1, 2022
1 parent 5a28970 commit 88b75c6
Show file tree
Hide file tree
Showing 14 changed files with 222 additions and 9 deletions.
3 changes: 1 addition & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,8 @@
"symfony/dependency-injection": "^6.1",
"symfony/finder": "^6.0",
"symfony/string": "^6.0",
"symplify/autowire-array-parameter": "^11.1",
"symplify/autowire-array-parameter": "^11.1.8",
"symplify/easy-parallel": "^11.1",
"symplify/symplify-kernel": "^11.1.7",
"symplify/rule-doc-generator-contracts": "^11.1",
"webmozart/assert": "^1.11"
},
Expand Down
4 changes: 4 additions & 0 deletions config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
use Rector\PSR4\Composer\PSR4NamespaceMatcher;
use Rector\PSR4\Contract\PSR4AutoloadNamespaceMatcherInterface;
use Rector\Utils\Command\MissingInSetCommand;
use SebastianBergmann\Diff\Differ;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Style\SymfonyStyle;
use function Symfony\Component\DependencyInjection\Loader\Configurator\service;
Expand Down Expand Up @@ -224,4 +225,7 @@
$services->set(\PHPStan\PhpDocParser\Lexer\Lexer::class);
$services->set(TypeParser::class);
$services->set(ConstExprParser::class);

// console color diff
$services->set(Differ::class);
};
7 changes: 4 additions & 3 deletions e2e/e2eTestRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
// runs a rector e2e test.
// checks whether we expect a certain output, or alternatively that rector just processed everything without errors

use Rector\Core\Console\Formatter\ColorConsoleDiffFormatter;
use Rector\Core\Console\Formatter\ConsoleDiffer;
use Rector\Core\Console\Style\SymfonyStyleFactory;
use Rector\Core\Util\Reflection\PrivatesAccessor;
use SebastianBergmann\Diff\Differ;
use Symfony\Component\Console\Command\Command;
use Symplify\PackageBuilder\Console\Formatter\ColorConsoleDiffFormatter;
use Symplify\PackageBuilder\Console\Output\ConsoleDiffer;

$projectRoot = __DIR__ .'/..';
$rectorBin = $projectRoot . '/bin/rector';
Expand Down Expand Up @@ -40,7 +41,7 @@
exit($exitCode);
}

$symfonyStyleFactory = new SymfonyStyleFactory(new \Rector\Core\Util\Reflection\PrivatesAccessor());
$symfonyStyleFactory = new SymfonyStyleFactory(new PrivatesAccessor());
$symfonyStyle = $symfonyStyleFactory->create();

$matchedExpectedOutput = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

namespace Rector\ChangesReporting\ValueObjectFactory;

use Rector\Core\Console\Formatter\ConsoleDiffer;
use Rector\Core\Differ\DefaultDiffer;
use Rector\Core\FileSystem\FilePathHelper;
use Rector\Core\ValueObject\Application\File;
use Rector\Core\ValueObject\Reporting\FileDiff;
use Symplify\PackageBuilder\Console\Output\ConsoleDiffer;

final class FileDiffFactory
{
Expand Down
104 changes: 104 additions & 0 deletions src/Console/Formatter/ColorConsoleDiffFormatter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php

declare(strict_types=1);

namespace Rector\Core\Console\Formatter;

use Nette\Utils\Strings;
use Symfony\Component\Console\Formatter\OutputFormatter;

/**
* Inspired by @see https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/master/src/Differ/DiffConsoleFormatter.php to be
* used as standalone class, without need to require whole package by Dariusz Rumiński <dariusz.ruminski@gmail.com>
*
* @see \Rector\Core\Tests\Console\Formatter\ColorConsoleDiffFormatterTest
*/
final class ColorConsoleDiffFormatter
{
/**
* @var string
* @see https://regex101.com/r/ovLMDF/1
*/
private const PLUS_START_REGEX = '#^(\+.*)#';

/**
* @var string
* @see https://regex101.com/r/xwywpa/1
*/
private const MINUT_START_REGEX = '#^(\-.*)#';

/**
* @var string
* @see https://regex101.com/r/CMlwa8/1
*/
private const AT_START_REGEX = '#^(@.*)#';

/**
* @var string
* @see https://regex101.com/r/qduj2O/1
*/
private const NEWLINES_REGEX = "#\n\r|\n#";

private readonly string $template;

public function __construct()
{
$this->template = sprintf(
'<comment> ---------- begin diff ----------</comment>%s%%s%s<comment> ----------- end diff -----------</comment>' . PHP_EOL,
PHP_EOL,
PHP_EOL
);
}

public function format(string $diff): string
{
return $this->formatWithTemplate($diff, $this->template);
}

private function formatWithTemplate(string $diff, string $template): string
{
$escapedDiff = OutputFormatter::escape(rtrim($diff));

$escapedDiffLines = Strings::split($escapedDiff, self::NEWLINES_REGEX);

// remove description of added + remove; obvious on diffs
foreach ($escapedDiffLines as $key => $escapedDiffLine) {
if ($escapedDiffLine === '--- Original') {
unset($escapedDiffLines[$key]);
}

if ($escapedDiffLine === '+++ New') {
unset($escapedDiffLines[$key]);
}
}

$coloredLines = array_map(function (string $string): string {
$string = $this->makePlusLinesGreen($string);
$string = $this->makeMinusLinesRed($string);
$string = $this->makeAtNoteCyan($string);

if ($string === ' ') {
return '';
}

return $string;
}, $escapedDiffLines);

return sprintf($template, implode(PHP_EOL, $coloredLines));
}

private function makePlusLinesGreen(string $string): string
{
return Strings::replace($string, self::PLUS_START_REGEX, '<fg=green>$1</fg=green>');
}

private function makeMinusLinesRed(string $string): string
{
return Strings::replace($string, self::MINUT_START_REGEX, '<fg=red>$1</fg=red>');
}

private function makeAtNoteCyan(string $string): string
{
return Strings::replace($string, self::AT_START_REGEX, '<fg=cyan>$1</fg=cyan>');
}
}
30 changes: 30 additions & 0 deletions src/Console/Formatter/CompleteUnifiedDiffOutputBuilderFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Rector\Core\Console\Formatter;

use Rector\Core\Util\Reflection\PrivatesAccessor;
use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;

/**
* @api
* Creates @see UnifiedDiffOutputBuilder with "$contextLines = 1000;"
*/
final class CompleteUnifiedDiffOutputBuilderFactory
{
public function __construct(
private readonly PrivatesAccessor $privatesAccessor
) {
}

/**
* @api
*/
public function create(): UnifiedDiffOutputBuilder
{
$unifiedDiffOutputBuilder = new UnifiedDiffOutputBuilder('');
$this->privatesAccessor->setPrivateProperty($unifiedDiffOutputBuilder, 'contextLines', 10000);
return $unifiedDiffOutputBuilder;
}
}
22 changes: 22 additions & 0 deletions src/Console/Formatter/ConsoleDiffer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Rector\Core\Console\Formatter;

use SebastianBergmann\Diff\Differ;

final class ConsoleDiffer
{
public function __construct(
private readonly Differ $differ,
private readonly ColorConsoleDiffFormatter $colorConsoleDiffFormatter
) {
}

public function diff(string $old, string $new): string
{
$diff = $this->differ->diff($old, $new);
return $this->colorConsoleDiffFormatter->format($diff);
}
}
3 changes: 1 addition & 2 deletions src/Kernel/RectorKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symplify\AutowireArrayParameter\DependencyInjection\CompilerPass\AutowireArrayParameterCompilerPass;
use Symplify\PackageBuilder\ValueObject\ConsoleColorDiffConfig;

final class RectorKernel
{
Expand Down Expand Up @@ -94,6 +93,6 @@ private function createCompilerPasses(): array
*/
private function createDefaultConfigFiles(): array
{
return [__DIR__ . '/../../config/config.php', ConsoleColorDiffConfig::FILE_PATH];
return [__DIR__ . '/../../config/config.php'];
}
}
41 changes: 41 additions & 0 deletions tests/Console/Formatter/ColorConsoleDiffFormatterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace Rector\Core\Tests\Console\Formatter;

use Iterator;
use Nette\Utils\FileSystem;
use PHPUnit\Framework\TestCase;
use Rector\Core\Console\Formatter\ColorConsoleDiffFormatter;

final class ColorConsoleDiffFormatterTest extends TestCase
{
private ColorConsoleDiffFormatter $colorConsoleDiffFormatter;

protected function setUp(): void
{
$this->colorConsoleDiffFormatter = new ColorConsoleDiffFormatter();
}

/**
* @dataProvider provideData()
*/
public function test(string $content, string $expectedFormatedFileContent): void
{
$formattedContent = $this->colorConsoleDiffFormatter->format($content);

$this->assertStringEqualsFile($expectedFormatedFileContent, $formattedContent);
}

public function provideData(): Iterator
{
yield ['...', __DIR__ . '/Source/expected/expected.txt'];
yield ["-old\n+new", __DIR__ . '/Source/expected/expected_old_new.txt'];

yield [
FileSystem::read(__DIR__ . '/Fixture/with_full_diff_by_phpunit.diff'),
__DIR__ . '/Fixture/expected_with_full_diff_by_phpunit.diff',
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<comment> ---------- begin diff ----------</comment>
...
<comment> ----------- end diff -----------</comment>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--- Original
+++ New
...
3 changes: 3 additions & 0 deletions tests/Console/Formatter/Source/expected/expected.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<comment> ---------- begin diff ----------</comment>
...
<comment> ----------- end diff -----------</comment>
4 changes: 4 additions & 0 deletions tests/Console/Formatter/Source/expected/expected_old_new.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<comment> ---------- begin diff ----------</comment>
<fg=red>-old</fg=red>
<fg=green>+new</fg=green>
<comment> ----------- end diff -----------</comment>
2 changes: 1 addition & 1 deletion tests/Util/Reflection/PrivatesAccessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

final class PrivatesAccessorTest extends TestCase
{
private PrivatesAccessor $privatesAccessor;
private readonly PrivatesAccessor $privatesAccessor;

protected function setUp(): void
{
Expand Down

0 comments on commit 88b75c6

Please sign in to comment.