Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Introduce a --diff=diffMode option #1044

Merged
merged 9 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 68 additions & 10 deletions src/Console/Command/Diff.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use Fidry\Console\ExitCode;
use Fidry\Console\Input\IO;
use KevinGH\Box\Console\PharInfoRenderer;
use KevinGH\Box\Phar\DiffMode;
use KevinGH\Box\Phar\PharDiff;
use KevinGH\Box\Phar\PharInfo;
use Symfony\Component\Console\Input\InputArgument;
Expand All @@ -30,6 +31,7 @@
use function count;
// TODO: migrate to Safe API
use function explode;
use function implode;
use function is_string;
use function sprintf;
use const PHP_EOL;
Expand All @@ -42,9 +44,11 @@ final class Diff implements Command
private const FIRST_PHAR_ARG = 'pharA';
private const SECOND_PHAR_ARG = 'pharB';

// TODO: replace by DiffMode::X->value once bumping to PHP 8.2 as the min version.
private const LIST_FILES_DIFF_OPTION = 'list-diff';
private const GIT_DIFF_OPTION = 'git-diff';
private const GNU_DIFF_OPTION = 'gnu-diff';
private const DIFF_OPTION = 'diff';
private const CHECK_OPTION = 'check';

private const DEFAULT_CHECKSUM_ALGO = 'sha384';
Expand Down Expand Up @@ -72,19 +76,32 @@ public function getConfiguration(): Configuration
self::GNU_DIFF_OPTION,
null,
InputOption::VALUE_NONE,
'Displays a GNU diff',
'(deprecated) Displays a GNU diff',
),
new InputOption(
self::GIT_DIFF_OPTION,
null,
InputOption::VALUE_NONE,
'Displays a Git diff',
'(deprecated) Displays a Git diff',
),
new InputOption(
self::LIST_FILES_DIFF_OPTION,
null,
InputOption::VALUE_NONE,
'Displays a list of file names diff (default)',
'(deprecated) Displays a list of file names diff (default)',
),
new InputOption(
self::DIFF_OPTION,
null,
InputOption::VALUE_REQUIRED,
sprintf(
'Displays a diff of the files. Available options are: "%s"',
implode(
'", "',
DiffMode::values(),
),
),
DiffMode::LIST->value,
),
new InputOption(
self::CHECK_OPTION,
Expand Down Expand Up @@ -157,6 +174,50 @@ private function compareArchives(PharDiff $diff, IO $io): int
return ExitCode::FAILURE;
}

private static function getDiffMode(IO $io): DiffMode
{
if ($io->getOption(self::GNU_DIFF_OPTION)->asBoolean()) {
$io->writeln(
sprintf(
'⚠️ <warning>Using the option "%s" is deprecated. Use "--%s=%s" instead.</warning>',
self::GNU_DIFF_OPTION,
self::DIFF_OPTION,
DiffMode::GNU->value,
),
);

return DiffMode::GNU;
}

if ($io->getOption(self::GIT_DIFF_OPTION)->asBoolean()) {
$io->writeln(
sprintf(
'⚠️ <warning>Using the option "%s" is deprecated. Use "--%s=%s" instead.</warning>',
self::GIT_DIFF_OPTION,
self::DIFF_OPTION,
DiffMode::GIT->value,
),
);

return DiffMode::GIT;
}

if ($io->getOption(self::LIST_FILES_DIFF_OPTION)->asBoolean()) {
$io->writeln(
sprintf(
'⚠️ <warning>Using the option "%s" is deprecated. Use "--%s=%s" instead.</warning>',
self::LIST_FILES_DIFF_OPTION,
self::DIFF_OPTION,
DiffMode::LIST->value,
),
);

return DiffMode::LIST;
}

return DiffMode::from($io->getOption(self::DIFF_OPTION)->asNonEmptyString());
}

private function compareContents(PharDiff $diff, IO $io): int
{
$io->comment('<info>Comparing the two archives contents...</info>');
Expand All @@ -167,13 +228,9 @@ private function compareContents(PharDiff $diff, IO $io): int
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();
}
$diffMode = self::getDiffMode($io);

$diffResult = $diff->diff($diffMode);

if (null === $diffResult || [[], []] === $diffResult) {
$io->success('The contents are identical');
Expand Down Expand Up @@ -254,5 +311,6 @@ private static function renderArchive(string $fileName, PharInfo $pharInfo, IO $
PharInfoRenderer::renderSignature($pharInfo, $io);
PharInfoRenderer::renderMetadata($pharInfo, $io);
PharInfoRenderer::renderContentsSummary($pharInfo, $io);
// TODO: checksum
}
}
35 changes: 35 additions & 0 deletions src/Phar/DiffMode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

/*
* This file is part of the box project.
*
* (c) Kevin Herrera <kevin@herrera.io>
* Théo Fidry <theo.fidry@gmail.com>
*
* 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 function array_map;

enum DiffMode: string
{
case LIST = 'list';
case GIT = 'git';
case GNU = 'gnu';

/**
* @return list<string>
*/
public static function values(): array
{
return array_map(
static fn (self $enum) => $enum->value,
self::cases(),
);
}
}
27 changes: 18 additions & 9 deletions src/Phar/PharDiff.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
use function str_replace;
use const DIRECTORY_SEPARATOR;

/**
* @internal
*/
final class PharDiff
{
private readonly ParagoniePharDiff $diff;
Expand Down Expand Up @@ -58,22 +61,28 @@ public function getPharInfoB(): PharInfo
return $this->pharInfoB;
}

public function gitDiff(): ?string
/**
* @return null|string|array{string[], string[]}
*/
public function diff(DiffMode $mode): null|string|array
{
if (DiffMode::LIST === $mode) {
return $this->listDiff();
}

return self::getDiff(
$this->pharInfoA,
$this->pharInfoB,
'git diff --no-index',
self::getModeCommand($mode),
);
}

public function gnuDiff(): ?string
private static function getModeCommand(DiffMode $mode): string
{
return self::getDiff(
$this->pharInfoA,
$this->pharInfoB,
'diff --exclude='.Extract::PHAR_META_PATH,
);
return match ($mode) {
DiffMode::GIT => 'git diff --no-index',
DiffMode::GNU => 'diff --exclude='.Extract::PHAR_META_PATH,
};
}

/**
Expand All @@ -89,7 +98,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);
Expand Down
Loading
Loading