-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDiffCollector.php
112 lines (97 loc) · 3.25 KB
/
DiffCollector.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<?php
declare(strict_types=1);
namespace O0h\PhpAstCheckDiff\Differ;
use O0h\PhpAstCheckDiff\Differ\Port\GitInterface;
use O0h\PhpAstCheckDiff\Value\AstDiff;
use O0h\PhpAstCheckDiff\Value\Diff;
/**
* @phpstan-type commit array{hash: string, message: string}
*/
class DiffCollector
{
/** @var array{base: commit, head:commit} */
private array $commits;
/** @var array{php: list<AstDiff>, nonPhp:list<Diff>} */
private array $diffs;
public function __construct(private readonly GitInterface $git, private DiffFactory $diffFactory) {}
/**
* Initializes the object with the provided base and head commit hashes.
*
* @param string $base the hash of the base commit
* @param string $head the hash of the head commit
*
* @throws \InvalidArgumentException if either the base or head commit hash is invalid
*/
public function initialize(string $base, string $head): void
{
foreach (compact('base', 'head') as $place => $commitHash) {
if (!$this->git->verifyCommit($commitHash)) {
throw new \InvalidArgumentException("{$commitHash}({$place}) is invalid");
}
}
$this->commits = [
'base' => [
'hash' => $base,
'message' => $this->git->getCommitLog($base),
],
'head' => [
'hash' => $head,
'message' => $this->git->getCommitLog($head),
],
];
$this->diffFactory->setCommitHashes($base, $head);
$this->setCollections();
}
/**
* Get the commits.
*
* @return array{base: commit, head: commit} the commits dict
*/
public function getCommits(): array
{
return $this->commits;
}
/**
* Get the PHP diffs for the changed files.
*
* @param bool $includeNonAstChanged Flag to include non-AST changed files. Default is true.
*
* @return list<AstDiff> an array of Diff objects representing the PHP diffs
*/
public function getPhpDiffs(bool $includeNonAstChanged = true): array
{
if ($includeNonAstChanged) {
return $this->diffs['php'];
}
return array_values(array_filter($this->diffs['php'], static fn($diff) => $diff->hasChanged()));
}
/**
* Get the non-PHP diffs.
*
* @return list<Diff> the array of non-PHP diffs
*/
public function getNonPhpDiffs(): array
{
return $this->diffs['nonPhp'];
}
/**
* Set the collections of PHP and non-PHP diffs.
*/
private function setCollections(): void
{
$phpDiffs = $nonPhpDiffs = [];
$diffFiles = $this->git->getDiffFiles($this->commits['base']['hash'], $this->commits['head']['hash']);
foreach ($diffFiles as $diffFile) {
$isPhpFile = 'php' === pathinfo($diffFile['path'], \PATHINFO_EXTENSION);
if ($isPhpFile) {
$phpDiffs[] = $this->diffFactory->createForPhp($diffFile['path'], $diffFile['status']);
} else {
$nonPhpDiffs[] = $this->diffFactory->createForNonPhp($diffFile['path'], $diffFile['status']);
}
}
$this->diffs = [
'php' => $phpDiffs,
'nonPhp' => $nonPhpDiffs,
];
}
}