Passed
Push — master ( e80b48...a06265 )
by Théo
02:43
created

PharDiff::listChecksums()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 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\PharInfo;
16
17
use function array_diff;
18
use function array_map;
19
use function escapeshellarg;
20
use function iterator_to_array;
21
use ParagonIE\Pharaoh\PharDiff as ParagoniePharDiff;
22
use function realpath;
23
use SplFileInfo;
24
use function str_replace;
25
use Symfony\Component\Finder\Finder;
26
27
final class PharDiff
28
{
29
    /** @var ParagoniePharDiff */
30
    private $diff;
31
32
    /** @var Pharaoh */
33
    private $pharA;
34
35
    /** @var Pharaoh */
36
    private $pharB;
37
38
    public function __construct(string $pathA, string $pathB)
39
    {
40
        $phars = array_map(
41
            static function (string $path): Pharaoh {
42
                $realPath = realpath($path);
43
44
                return new Pharaoh(false !== $realPath ? $realPath : $path);
45
            },
46
            [$pathA, $pathB]
47
        );
48
49
        $this->pharA = $phars[0];
50
        $this->pharB = $phars[1];
51
52
        $diff = new ParagoniePharDiff(...$phars);
53
        $diff->setVerbose(true);
54
55
        $this->diff = $diff;
56
    }
57
58
    public function getPharA(): Pharaoh
59
    {
60
        return $this->pharA;
61
    }
62
63
    public function getPharB(): Pharaoh
64
    {
65
        return $this->pharB;
66
    }
67
68
    public function gitDiff(): ?string
69
    {
70
        $argA = escapeshellarg($this->pharA->tmp);
71
        $argB = escapeshellarg($this->pharB->tmp);
72
73
        /** @var string $diff */
74
        $diff = `git diff --no-index $argA $argB`;
75
76
        $diff = str_replace(
77
            $this->pharA->tmp,
78
            $this->pharA->getFileName(),
79
            $diff
80
        );
81
        $diff = str_replace(
82
            $this->pharB->tmp,
83
            $this->pharB->getFileName(),
84
            $diff
85
        );
86
87
        return '' === $diff ? null : $diff;
88
    }
89
90
    public function gnuDiff(): ?string
91
    {
92
        $argA = escapeshellarg($this->pharA->tmp);
93
        $argB = escapeshellarg($this->pharB->tmp);
94
95
        /** @var string $diff */
96
        $diff = `diff $argA $argB`;
97
98
        $diff = str_replace(
99
            $this->pharA->tmp,
100
            $this->pharA->getFileName(),
101
            $diff
102
        );
103
        $diff = str_replace(
104
            $this->pharB->tmp,
105
            $this->pharB->getFileName(),
106
            $diff
107
        );
108
109
        return '' === $diff ? null : $diff;
110
    }
111
112
    /**
113
     * @see ParagoniePharDiff::listChecksums()
114
     */
115
    public function listChecksums(string $algo = 'sha384'): int
116
    {
117
        return $this->diff->listChecksums($algo);
118
    }
119
120
    /**
121
     * @return string[][] Returns two arrays of strings. The first one contains all the files present in the first PHAR
122
     *                    which are not in the second and the second array all the files present in the second PHAR but
123
     *                    not the first one.
124
     */
125
    public function listDiff(): array
126
    {
127
        $pharAFiles = $this->collectFiles($this->pharA);
128
        $pharBFiles = $this->collectFiles($this->pharB);
129
130
        return [
131
            array_diff($pharAFiles, $pharBFiles),
132
            array_diff($pharBFiles, $pharAFiles),
133
        ];
134
    }
135
136
    /**
137
     * @return string[]
138
     */
139
    private function collectFiles(Pharaoh $phar): array
140
    {
141
        $basePath = $phar->tmp;
142
143
        return array_map(
144
            static function (SplFileInfo $fileInfo) use ($basePath): string {
145
                return str_replace($basePath, '', $fileInfo->getRealPath());
146
            },
147
            iterator_to_array(
148
                Finder::create()
149
                    ->files()
150
                    ->in($basePath)
151
                    ->ignoreDotFiles(false),
152
                false
153
            )
154
        );
155
    }
156
}
157