Repository navigation
Expand file tree
/
Copy pathDiffBaseResolver.php
More file actions
94 lines (70 loc) · 2.68 KB
/
Copy pathDiffBaseResolver.php
File metadata and controls
94 lines (70 loc) · 2.68 KB
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
<?php
declare(strict_types=1);
namespace DocbookCS\Diff;
use DocbookCS\Git\GitException;
use DocbookCS\Git\GitClient;
final readonly class DiffBaseResolver
{
private const string DEFAULT_BRANCH = 'master';
private const string DEFAULT_BRANCH_REFERENCE = 'refs/heads/master';
private const string PHP_DOCS_REPO_PATTERN = '/^doc-(?:base|[a-z]{2}(?:_[a-z]{2})?)$/i';
public function __construct(
private GitClient $git,
private UpstreamResolver $officialUpstream,
) {}
/** @throws GitException */
public function resolve(string $repoRoot): string
{
$repoName = $this->repositoryName($repoRoot);
if ($repoName === null) {
return $this->localMergeBase($repoRoot);
}
return $this->officialUpstream->resolve($repoRoot, $repoName)
?? $this->localMergeBase($repoRoot);
}
/** @throws GitException */
private function localMergeBase(string $repoRoot): string
{
$baseReference = $this->localBaseReference($repoRoot);
if (null === $mergeBase = $this->git->findMergeBase($repoRoot, 'HEAD', $baseReference)) {
throw GitException::mergeBaseNotFound($baseReference);
}
return $mergeBase;
}
/** @throws GitException */
private function localBaseReference(string $repoRoot): string
{
if ($this->git->currentBranchName($repoRoot) === self::DEFAULT_BRANCH) {
return $this->git->upstreamReferenceFromLocalConfiguration($repoRoot, self::DEFAULT_BRANCH) ?? 'HEAD';
}
if ($this->git->resolveCommitHash($repoRoot, self::DEFAULT_BRANCH_REFERENCE) !== null) {
return self::DEFAULT_BRANCH_REFERENCE;
}
throw GitException::localMasterNotFound();
}
/** @throws GitException */
private function repositoryName(string $repoRoot): ?string
{
$repoNames = [];
foreach ($this->git->remoteUrlsFromLocalConfiguration($repoRoot) as $url) {
$repoName = $this->repositoryNameFrom($url);
if ($repoName !== null) {
$repoNames[$repoName] = true;
}
}
if (count($repoNames) === 1) {
return array_key_first($repoNames);
}
return $repoNames === []
? $this->repositoryNameFrom($repoRoot)
: null;
}
private function repositoryNameFrom(string $path): ?string
{
$path = rtrim(str_replace(['\\', ':'], '/', $path), '/');
$name = preg_replace('/\\.git$/i', '', basename($path));
$isPhpDocsRepo = is_string($name)
&& preg_match(self::PHP_DOCS_REPO_PATTERN, $name) === 1;
return $isPhpDocsRepo ? strtolower($name) : null;
}
}