From 4ce0b1719051d4738f1f29b809e4fbdcf3c2bccb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= Date: Tue, 10 Oct 2023 09:15:10 +0200 Subject: [PATCH] WIp --- src/Console/Command/Diff.php | 71 ++-------- src/Phar/DiffMode.php | 14 +- src/Phar/PharDiff.php | 28 +--- tests/Console/Command/DiffTest.php | 217 +++++++++++++++-------------- 4 files changed, 138 insertions(+), 192 deletions(-) diff --git a/src/Console/Command/Diff.php b/src/Console/Command/Diff.php index f4c42d009..83bbc3b79 100644 --- a/src/Console/Command/Diff.php +++ b/src/Console/Command/Diff.php @@ -20,8 +20,8 @@ use Fidry\Console\Input\IO; use KevinGH\Box\Console\PharInfoRenderer; use KevinGH\Box\Phar\PharDiff; -use KevinGH\Box\PharInfo\DiffMode; use KevinGH\Box\Phar\PharInfo; +use KevinGH\Box\Phar\DiffMode; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\BufferedOutput; @@ -30,8 +30,8 @@ use function array_map; use function count; // TODO: migrate to Safe API -use function implode; use function explode; +use function implode; use function is_string; use function sprintf; use const PHP_EOL; @@ -120,10 +120,10 @@ public function execute(IO $io): int $diff = new PharDiff(...$paths); - $this->showArchives($diff, $io); + $result1 = $this->compareArchives($diff, $io); $result2 = $this->compareContents($diff, $io); - return $result2; + return $result1 + $result2; } /** @@ -144,8 +144,10 @@ private static function getPaths(IO $io): array ); } - private function showArchives(PharDiff $diff, IO $io): void + private function compareArchives(PharDiff $diff, IO $io): int { + $io->comment('Comparing the two archives... (do not check the signatures)'); + $pharInfoA = $diff->getPharInfoA(); $pharInfoB = $diff->getPharInfoB(); @@ -168,6 +170,8 @@ private function showArchives(PharDiff $diff, IO $io): void $pharInfoB, $io, ); + + return ExitCode::FAILURE; } private static function getDiffMode(IO $io): DiffMode @@ -216,6 +220,8 @@ private static function getDiffMode(IO $io): DiffMode private function compareContents(PharDiff $diff, IO $io): int { + $io->comment('Comparing the two archives contents...'); + $checkSumAlgorithm = $io->getOption(self::CHECK_OPTION)->asNullableNonEmptyString() ?? self::DEFAULT_CHECKSUM_ALGO; if ($io->hasOption('-c') || $io->hasOption('--check')) { @@ -239,61 +245,6 @@ private function compareContents(PharDiff $diff, IO $io): int return ExitCode::FAILURE; } - $io->writeln(sprintf( - '--- Files present in "%s" but not in "%s"', - $diff->getPharA()->getFileName(), - $diff->getPharB()->getFileName(), - )); - $io->writeln(sprintf( - '+++ Files present in "%s" but not in "%s"', - $diff->getPharB()->getFileName(), - $diff->getPharA()->getFileName(), - )); - - $io->newLine(); - - self::renderPaths('-', $diff->getPharA(), $diffResult[0], $io); - self::renderPaths('+', $diff->getPharB(), $diffResult[1], $io); - - $io->error(sprintf( - '%d file(s) difference', - count($diffResult[0]) + count($diffResult[1]), - )); - - return ExitCode::FAILURE; - } - - private function compareContentssS(PharDiff $diff, IO $io): int - { - $io->comment('Comparing the two archives contents...'); - - $checkSumAlgorithm = $io->getOption(self::CHECK_OPTION)->asNullableNonEmptyString() ?? self::DEFAULT_CHECKSUM_ALGO; - - if ($io->hasOption('-c') || $io->hasOption('--check')) { - return $diff->listChecksums($checkSumAlgorithm); - } - - if ($io->getOption(self::GNU_DIFF_OPTION)->asBoolean()) { - $diffResult = $diff->gnuDiff(); - } elseif ($io->getOption(self::GIT_DIFF_OPTION)->asBoolean()) { - $diffResult = $diff->gitDiff(); - } else { - $diffResult = $diff->listDiff(); - } - - if (null === $diffResult || [[], []] === $diffResult) { - $io->success('The contents are identical'); - - return ExitCode::SUCCESS; - } - - if (is_string($diffResult)) { - // Git or GNU diff: we don't have much control on the format - $io->writeln($diffResult); - - return ExitCode::FAILURE; - } - $io->writeln(sprintf( '--- Files present in "%s" but not in "%s"', $diff->getPharInfoA()->getFileName(), diff --git a/src/Phar/DiffMode.php b/src/Phar/DiffMode.php index 0e13fdf3b..bad3736b0 100644 --- a/src/Phar/DiffMode.php +++ b/src/Phar/DiffMode.php @@ -2,10 +2,18 @@ declare(strict_types=1); -namespace KevinGH\Box\PharInfo; +/* + * This file is part of the box project. + * + * (c) Kevin Herrera + * Théo Fidry + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace KevinGH\Box\Phar; -use BackedEnum; -use UnitEnum; use function array_map; enum DiffMode: string diff --git a/src/Phar/PharDiff.php b/src/Phar/PharDiff.php index bf7b3a38c..9c01906b0 100644 --- a/src/Phar/PharDiff.php +++ b/src/Phar/PharDiff.php @@ -16,6 +16,7 @@ use KevinGH\Box\Console\Command\Extract; use KevinGH\Box\Pharaoh\PharDiff as ParagoniePharDiff; +use KevinGH\Box\Phar\DiffMode; use SplFileInfo; use Symfony\Component\Finder\Finder; use Symfony\Component\Process\Process; @@ -26,6 +27,9 @@ use function str_replace; use const DIRECTORY_SEPARATOR; +/** + * @internal + */ final class PharDiff { private readonly ParagoniePharDiff $diff; @@ -68,8 +72,8 @@ public function diff(DiffMode $mode): null|string|array } return self::getDiff( - $this->pharA, - $this->pharB, + $this->pharInfoA, + $this->pharInfoB, self::getModeCommand($mode), ); } @@ -82,24 +86,6 @@ private static function getModeCommand(DiffMode $mode): string }; } - public function gitDiff(): ?string - { - return self::getDiff( - $this->pharInfoA, - $this->pharInfoB, - 'git diff --no-index', - ); - } - - public function gnuDiff(): ?string - { - return self::getDiff( - $this->pharInfoA, - $this->pharInfoB, - 'diff --exclude='.Extract::PHAR_META_PATH, - ); - } - /** * @see ParagoniePharDiff::listChecksums() */ @@ -113,7 +99,7 @@ public function listChecksums(string $algo = 'sha384'): int * which are not in the second and the second array all the files present in the second PHAR but * not the first one. */ - public function listDiff(): array + private function listDiff(): array { $pharAFiles = self::collectFiles($this->pharInfoA); $pharBFiles = self::collectFiles($this->pharInfoB); diff --git a/tests/Console/Command/DiffTest.php b/tests/Console/Command/DiffTest.php index f004bfbf1..650f1c164 100644 --- a/tests/Console/Command/DiffTest.php +++ b/tests/Console/Command/DiffTest.php @@ -17,7 +17,9 @@ use Fidry\Console\Command\Command; use Fidry\Console\DisplayNormalizer; use Fidry\Console\ExitCode; +use Fidry\Console\Test\OutputAssertions; use InvalidArgumentException; +use KevinGH\Box\Phar\DiffMode; use KevinGH\Box\Phar\InvalidPhar; use KevinGH\Box\Platform; use KevinGH\Box\Test\CommandTestCase; @@ -100,13 +102,46 @@ public function test_it_displays_the_list_diff_of_two_phar_files_by_default(): v } /** - * @dataProvider gitDiffPharsProvider + * @dataProvider diffPharsProvider */ - public function test_it_can_display_the_git_diff_of_two_phar_files( - callable $executeCommand, + public function test_it_can_display_the_diff_of_two_phar_files( + string $pharAPath, + string $pharBPath, + ?DiffMode $diffMode, ?string $expectedOutput, int $expectedStatusCode, ): void { + $command = [ + 'command' => 'diff', + 'pharA' => $pharAPath, + 'pharB' => $pharBPath, + '--check' => null, + ]; + + if (null !== $diffMode) { + $command['--diff-mode'] = $diffMode->value; + } + + ob_start(); + $this->commandTester->execute($command); + $actual = DisplayNormalizer::removeTrailingSpaces(ob_get_clean()); + + $expected = <<<'OUTPUT' + No differences encountered. + + OUTPUT; + + $this->assertSame($expected, $actual); + $this->assertSame($expectedStatusCode, $this->commandTester->getStatusCode()); + } + + public static function diffPharsProvider(): iterable + { + yield from self::gitDiffPharsProvider(); + yield from self::GNUDiffPharsProvider(); + } + + public function test_it_can_display_the_git_diff_of_two_phar_files(): void { self::markTestSkipped('TODO'); $actualOutput = $executeCommand($this->commandTester); @@ -117,21 +152,35 @@ public function test_it_can_display_the_git_diff_of_two_phar_files( self::assertSame($expectedStatusCode, $this->commandTester->getStatusCode()); } - /** - * @dataProvider GNUDiffPharsProvider - */ - public function test_it_can_display_the_gnu_diff_of_two_phar_files( - callable $executeCommand, - ?string $expectedOutput, - int $expectedStatusCode, - ): void { - $actualOutput = $executeCommand($this->commandTester); + public function test_it_can_display_the_gnu_diff_of_two_phar_files(): void { + $pharPath = realpath(self::FIXTURES_DIR.'/simple-phar-foo.phar'); - if (null !== $expectedOutput) { - self::assertSame($expectedOutput, $actualOutput); - } + $this->commandTester->execute( + [ + 'command' => 'diff', + 'pharA' => $pharPath, + 'pharB' => $pharPath, + '--gnu-diff' => null, + ], + ); - self::assertSame($expectedStatusCode, $this->commandTester->getStatusCode()); + $expected = <<<'OUTPUT' + + // Comparing the two archives... (do not check the signatures) + + [OK] The two archives are identical + + // Comparing the two archives contents... + + [OK] The contents are identical + + + OUTPUT; + + $actual = DisplayNormalizer::removeTrailingSpaces($this->commandTester->getDisplay(true)); + + self::assertSame($expected, $actual); + self::assertSame(ExitCode::SUCCESS, $this->commandTester->getStatusCode()); } public function test_it_can_check_the_sum_of_two_phar_files(): void @@ -397,23 +446,19 @@ static function (CommandTester $commandTester): string { ])(); } - public static function gitDiffPharsProvider(): iterable + private static function gitDiffPharsProvider(): iterable { - yield (static fn (): array => [ - static function (CommandTester $commandTester): string { - $pharPath = realpath(self::FIXTURES_DIR.'/simple-phar-foo.phar'); + // TODO: enable back + yield from []; + return; - $commandTester->execute( - [ - 'command' => 'diff', - 'pharA' => $pharPath, - 'pharB' => $pharPath, - '--git-diff' => null, - ], - ); + $pharPath = realpath(self::FIXTURES_DIR.'/simple-phar-foo.phar'); + $diffMode = DiffMode::GIT; - return DisplayNormalizer::removeTrailingSpaces($commandTester->getDisplay(true)); - }, + yield 'same PHAR' => [ + $pharPath, + $pharPath, + $diffMode, <<<'OUTPUT' // Comparing the two archives... (do not check the signatures) @@ -426,22 +471,13 @@ static function (CommandTester $commandTester): string { OUTPUT, - 0, - ])(); - - yield (static fn (): array => [ - static function (CommandTester $commandTester): string { - $commandTester->execute( - [ - 'command' => 'diff', - 'pharA' => realpath(self::FIXTURES_DIR.'/simple-phar-foo.phar'), - 'pharB' => realpath(self::FIXTURES_DIR.'/simple-phar-bar.phar'), - '--git-diff' => null, - ], - ); + ExitCode::SUCCESS, + ]; - return DisplayNormalizer::removeTrailingSpaces($commandTester->getDisplay(true)); - }, + yield 'simple different PHAR' => [ + realpath(self::FIXTURES_DIR.'/simple-phar-foo.phar'), + realpath(self::FIXTURES_DIR.'/simple-phar-bar.phar'), + $diffMode, <<<'OUTPUT' // Comparing the two archives... (do not check the signatures) @@ -457,38 +493,12 @@ static function (CommandTester $commandTester): string { OUTPUT, 3, - ])(); - - yield (static fn (): array => [ - static function (CommandTester $commandTester): string { - $commandTester->execute( - [ - 'command' => 'diff', - 'pharA' => realpath(self::FIXTURES_DIR.'/simple-phar-bar.phar'), - 'pharB' => realpath(self::FIXTURES_DIR.'/simple-phar-bar-compressed.phar'), - '--git-diff' => null, - ], - ); - - return DisplayNormalizer::removeTrailingSpaces($commandTester->getDisplay(true)); - }, - null, - 2, - ])(); + ]; - yield (static fn (): array => [ - static function (CommandTester $commandTester): string { - $commandTester->execute( - [ - 'command' => 'diff', - 'pharA' => realpath(self::FIXTURES_DIR.'/simple-phar-bar.phar'), - 'pharB' => realpath(self::FIXTURES_DIR.'/simple-phar-baz.phar'), - '--git-diff' => null, - ], - ); - - return DisplayNormalizer::removeTrailingSpaces($commandTester->getDisplay(true)); - }, + yield 'same files different content PHAR' => [ + realpath(self::FIXTURES_DIR.'/simple-phar-bar.phar'), + realpath(self::FIXTURES_DIR.'/simple-phar-baz.phar'), + $diffMode, <<<'OUTPUT' // Comparing the two archives... (do not check the signatures) @@ -509,26 +519,18 @@ static function (CommandTester $commandTester): string { OUTPUT, 1, - ])(); + ]; } - public static function GNUDiffPharsProvider(): iterable + private static function GNUDiffPharsProvider(): iterable { - yield (static fn (): array => [ - static function (CommandTester $commandTester): string { - $pharPath = realpath(self::FIXTURES_DIR.'/simple-phar-foo.phar'); + $pharPath = realpath(self::FIXTURES_DIR.'/simple-phar-foo.phar'); + $diffMode = DiffMode::GNU; - $commandTester->execute( - [ - 'command' => 'diff', - 'pharA' => $pharPath, - 'pharB' => $pharPath, - '--gnu-diff' => null, - ], - ); - - return DisplayNormalizer::removeTrailingSpaces($commandTester->getDisplay(true)); - }, + yield 'same PHAR' => [ + $pharPath, + $pharPath, + $diffMode, <<<'OUTPUT' // Comparing the two archives... (do not check the signatures) @@ -541,22 +543,13 @@ static function (CommandTester $commandTester): string { OUTPUT, - 0, - ])(); + ExitCode::SUCCESS, + ]; - yield (static fn (): array => [ - static function (CommandTester $commandTester): string { - $commandTester->execute( - [ - 'command' => 'diff', - 'pharA' => realpath(self::FIXTURES_DIR.'/simple-phar-foo.phar'), - 'pharB' => realpath(self::FIXTURES_DIR.'/simple-phar-bar.phar'), - '--gnu-diff' => null, - ], - ); - - return DisplayNormalizer::removeTrailingSpaces($commandTester->getDisplay(true)); - }, + yield 'different PHARs' => [ + realpath(self::FIXTURES_DIR.'/simple-phar-foo.phar'), + realpath(self::FIXTURES_DIR.'/simple-phar-bar.phar'), + $diffMode, <<<'OUTPUT' // Comparing the two archives... (do not check the signatures) @@ -570,7 +563,15 @@ static function (CommandTester $commandTester): string { OUTPUT, 1, - ])(); + ]; + + yield 'same files different content PHARs' => [ + realpath(self::FIXTURES_DIR.'/simple-phar-bar.phar'), + realpath(self::FIXTURES_DIR.'/simple-phar-bar-compressed.phar'), + $diffMode, + null, + 1, + ]; yield (static fn (): array => [ static function (CommandTester $commandTester): string {