Passed
Pull Request — master (#238)
by Théo
02:39
created

Diff   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 108
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 8
dl 0
loc 108
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
B execute() 0 59 7
B configure() 0 30 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the box project.
7
 *
8
 * (c) Kevin Herrera <[email protected]>
9
 *     Théo Fidry <[email protected]>
10
 *
11
 * This source file is subject to the MIT license that is bundled
12
 * with this source code in the file LICENSE.
13
 */
14
15
namespace KevinGH\Box\Console\Command;
16
17
use Assert\Assertion;
18
use KevinGH\Box\PhpSettingsHandler;
19
use ParagonIE\Pharaoh\Pharaoh;
20
use ParagonIE\Pharaoh\PharDiff;
21
use Symfony\Component\Console\Command\Command;
22
use Symfony\Component\Console\Input\InputArgument;
23
use Symfony\Component\Console\Input\InputInterface;
24
use Symfony\Component\Console\Input\InputOption;
25
use Symfony\Component\Console\Logger\ConsoleLogger;
26
use Symfony\Component\Console\Output\OutputInterface;
27
use Symfony\Component\Console\Style\SymfonyStyle;
28
use Throwable;
29
use function array_map;
30
use function KevinGH\Box\FileSystem\remove;
31
32
/**
33
 * @private
34
 */
35
final class Diff extends Command
36
{
37
    use CreateTemporaryPharFile;
38
39
    private const FIRST_PHAR_ARG = 'pharA';
40
    private const SECOND_PHAR_ARG = 'pharB';
41
42
    private const GNU_DIFF_OPTION = 'gnu-diff';
43
    private const CHECK_OPTION = 'check';
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    protected function configure(): void
49
    {
50
        parent::configure();
51
52
        $this->setName('diff');
53
        $this->setDescription('Display the differences between all of the files in two PHARs');
54
55
        $this->addArgument(
56
            self::FIRST_PHAR_ARG,
57
            InputArgument::OPTIONAL,
58
            'The first PHAR'
59
        );
60
        $this->addArgument(
61
            self::SECOND_PHAR_ARG,
62
            InputArgument::OPTIONAL,
63
            'The second PHAR'
64
        );
65
66
        $this->addOption(
67
            self::GNU_DIFF_OPTION,
68
            'd',
69
            InputOption::VALUE_NONE,
70
            'Displays a GNU diff instead of the default git diff'
71
        );
72
        $this->addOption(
73
            self::CHECK_OPTION,
74
            'c',
75
            InputOption::VALUE_OPTIONAL,
76
            'Verify the authenticity of the contents between the two PHARs with the given hash function.',
77
            'sha384'
78
        );
79
    }
80
81
    /**
82
     * {@inheritdoc}
83
     */
84
    protected function execute(InputInterface $input, OutputInterface $output): int
85
    {
86
        $io = new SymfonyStyle($input, $output);
87
88
        (new PhpSettingsHandler(new ConsoleLogger($output)))->check();
89
90
        $paths = [
91
            $input->getArgument(self::FIRST_PHAR_ARG),
92
            $input->getArgument(self::SECOND_PHAR_ARG),
93
        ];
94
95
        Assertion::allFile($paths);
0 ignored issues
show
Bug introduced by
$paths of type array<integer,mixed> is incompatible with the type string expected by parameter $value of Assert\Assertion::allFile(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

95
        Assertion::allFile(/** @scrutinizer ignore-type */ $paths);
Loading history...
96
97
        $tmpFiles = [];
98
99
        try {
100
            $diff = new PharDiff(
101
                ...array_map(
102
                    function (string $path) use (&$tmpFiles): Pharaoh {
103
                        $path = false !== realpath($path) ? realpath($path) : $path;
104
105
                        $tmpPath = $this->createTemporaryPhar($path);
106
107
                        if ($path !== $tmpPath) {
108
                            $tmpFiles[] = $tmpPath;
109
                        }
110
111
                        return new Pharaoh($tmpPath);
112
                    },
113
                    $paths
114
                )
115
            );
116
            $diff->setVerbose(true);
117
        } catch (Throwable $throwable) {
118
            if ($output->isDebug()) {
119
                throw $throwable;
120
            }
121
122
            $io->writeln(
123
                sprintf(
124
                    '<error>Could not check the PHARs: %s</error>',
125
                    $throwable->getMessage()
126
                )
127
            );
128
129
            return 1;
130
        } finally {
131
            remove($tmpFiles);
132
        }
133
134
        if ($input->hasParameterOption(['-c', '--check'])) {
135
            return $diff->listChecksums($input->getOption(self::CHECK_OPTION) ?? 'sha384');
136
        }
137
138
        if ($input->getOption(self::GNU_DIFF_OPTION)) {
139
            return $diff->printGnuDiff();
140
        }
141
142
        return $diff->printGitDiff();
143
    }
144
}
145