Skip to content

Commit

Permalink
feat: Introduce a --diff=diffMode option (#1044)
Browse files Browse the repository at this point in the history
- Introduce a new option `--diff=list|git|gnu`.
- Deprecate `--list-diff`, `--git-diff` and `--gnu-diff` in favour of the `--diff` option.
  • Loading branch information
theofidry authored Oct 11, 2023
1 parent daac2b5 commit 3aaca35
Show file tree
Hide file tree
Showing 4 changed files with 235 additions and 73 deletions.
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

0 comments on commit 3aaca35

Please sign in to comment.