-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathLoader.php
127 lines (107 loc) · 4.32 KB
/
Loader.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<?php
namespace Wieni\ComposerPatchSet\PatchRepository;
use Composer\Installer\InstallationManager;
use Composer\IO\IOInterface;
use Composer\Package\PackageInterface;
use Composer\Package\RootPackageInterface;
use Composer\Repository\InstalledRepositoryInterface;
use cweagans\Composer\Patch;
use cweagans\Composer\Resolver\ResolverBase;
class Loader
{
public function __construct(
private readonly string $projectRootDirectory,
private readonly RootPackageInterface $rootPackage,
private readonly InstalledRepositoryInterface $installedRepository,
private readonly InstallationManager $installationManager,
private readonly ResolverBase $resolver,
private readonly IOInterface $io,
)
{
}
public function loadPatches(PatchRepository $patchRepository): array
{
$package = $this->installedRepository->findPackage($patchRepository->name, '*');
if (!$package) {
throw new \Exception(sprintf('Package %s not found', $patchRepository->name));
}
$patches = [];
foreach ($this->getPatchesFromPatchRepository($package) as $patch) {
if ($patchRepository->isExcluded($patch)) {
$this->io->write(sprintf(
' - <info>Excluding patch %s: %s</info>',
$patch->package,
$patch->description,
));
continue;
}
$patches[] = $patch;
}
return $patches;
}
public function findPatchRepositories(): array
{
$patchRepositories = [];
foreach ($this->rootPackage->getExtra()['patchRepositories'] ?? [] as $patchRepositoryJson) {
$patchRepositories[] = $this->createPatchRepositoryFromJson($patchRepositoryJson);
}
return $patchRepositories;
}
private function createPatchRepositoryFromJson(string|array $patchRepositoryJson): PatchRepository
{
if (is_string($patchRepositoryJson)) {
$patchRepositoryJson = [
'name' => $patchRepositoryJson,
'excludedPatches' => [],
];
}
return new PatchRepository(
$patchRepositoryJson['name'],
$this->createExcludedPatchesFromJson($patchRepositoryJson),
);
}
private function createExcludedPatchesFromJson(array $patchRepositoryJson): array
{
$excludedPatches = [];
foreach ($patchRepositoryJson['excludedPatches'] ?? [] as $package => $urls) {
foreach ($urls as $url) {
$excludedPatches[] = new ExcludedPatch($package, $url);
}
}
return $excludedPatches;
}
/** @return Patch[] */
private function getPatchesFromPatchRepository(PackageInterface $package): array
{
$packagePatches = $this->resolver->findPatchesInJson($package->getExtra()['patches'] ?? []);
$allPatches = [];
foreach ($packagePatches as $patches) {
foreach ($patches as $patch) {
$allPatches[] = $patch;
}
}
// In case Patch url is a file path, we need to resolve it to a path
// relative to the root composer.json.
foreach ($allPatches as $patch) {
if (!str_starts_with($patch->url, 'http')) {
// /home/user/project/vendor/your-org/drupal-patches/patches/core/case_insensitive_langcode.patch
$newUrl = $this->installationManager->getInstaller($package->getType())->getInstallPath($package) . '/' . trim($patch->url, '/');
// /vendor/your-org/drupal-patches/patches/core/case_insensitive_langcode.patch
$newUrl = str_replace(trim($this->projectRootDirectory, '/') . '/', '', $newUrl);
// vendor/your-org/drupal-patches/patches/core/case_insensitive_langcode.patch
$newUrl = ltrim($newUrl, '/');
$this->io->write(sprintf(
' - <info>Renaming patch path %s to %s</info>',
$patch->url,
$newUrl,
));
$patch->url = $newUrl;
}
}
// sort the patches by package name.
usort($allPatches, function (Patch $a, Patch $b) {
return strcmp($a->package, $b->package);
});
return $allPatches;
}
}