-
-
Notifications
You must be signed in to change notification settings - Fork 440
Expand file tree
/
Copy pathInstalledPackageResolver.php
More file actions
115 lines (91 loc) · 3.65 KB
/
InstalledPackageResolver.php
File metadata and controls
115 lines (91 loc) · 3.65 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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<?php
declare(strict_types=1);
namespace Rector\Composer;
use Nette\Utils\FileSystem;
use Nette\Utils\Json;
use Rector\Composer\ValueObject\InstalledPackage;
use Rector\Exception\ShouldNotHappenException;
use Rector\Skipper\FileSystem\PathNormalizer;
use Webmozart\Assert\Assert;
/**
* @see \Rector\Tests\Composer\InstalledPackageResolverTest
*/
final class InstalledPackageResolver
{
/**
* @var null|InstalledPackage[]
*/
private ?array $resolvedInstalledPackages = null;
public function __construct(
private readonly ?string $projectDirectory = null
) {
// fallback to root project directory
if ($projectDirectory === null) {
$projectDirectory = getcwd();
}
Assert::directory($projectDirectory);
}
/**
* @return InstalledPackage[]
*/
public function resolve(): array
{
// already cached, even only empty array
if ($this->resolvedInstalledPackages !== null) {
return $this->resolvedInstalledPackages;
}
$installedPackagesFilePath = $this->resolveVendorDir() . '/composer/installed.json';
if (! file_exists($installedPackagesFilePath)) {
throw new ShouldNotHappenException(
'The installed package json not found. Make sure you run `composer update` and the "vendor/composer/installed.json" file exists'
);
}
$installedPackageFileContents = FileSystem::read($installedPackagesFilePath);
$installedPackagesFilePath = Json::decode($installedPackageFileContents, true);
$installedPackages = $this->createInstalledPackages($installedPackagesFilePath['packages']);
$this->resolvedInstalledPackages = $installedPackages;
return $installedPackages;
}
public function resolvePackageVersion(string $packageName): ?string
{
$installedPackages = $this->resolve();
foreach ($installedPackages as $installedPackage) {
if ($installedPackage->getName() !== $packageName) {
continue;
}
return $installedPackage->getVersion();
}
return null;
}
/**
* @param mixed[] $packages
* @return InstalledPackage[]
*/
private function createInstalledPackages(array $packages): array
{
$installedPackages = [];
foreach ($packages as $package) {
$installedPackages[] = new InstalledPackage($package['name'], $package['version_normalized']);
}
return $installedPackages;
}
private function resolveVendorDir(): string
{
$projectComposerJsonFilePath = $this->projectDirectory . '/composer.json';
if (\file_exists($projectComposerJsonFilePath)) {
$projectComposerContents = FileSystem::read($projectComposerJsonFilePath);
$projectComposerJson = Json::decode($projectComposerContents, true);
if (isset($projectComposerJson['config']['vendor-dir']) &&
is_string($projectComposerJson['config']['vendor-dir'])
) {
$realPathVendorDir = realpath($projectComposerJson['config']['vendor-dir']) ?: '';
$normalizedRealPathVendorDir = PathNormalizer::normalize($realPathVendorDir);
$normalizedVendorDir = PathNormalizer::normalize($projectComposerJson['config']['vendor-dir']);
return $normalizedRealPathVendorDir === $normalizedVendorDir
? $projectComposerJson['config']['vendor-dir']
: $this->projectDirectory . '/' . $projectComposerJson['config']['vendor-dir'];
}
}
return $this->projectDirectory . '/vendor';
}
}