Passed
Pull Request — master (#105)
by Craig
08:59
created

getInstalledPackages()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 3

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 18
ccs 11
cts 11
cp 1
rs 9.9332
c 0
b 0
f 0
cc 3
nc 3
nop 1
crap 3
1
<?php
2
3
namespace ComposerRequireChecker\FileLocator;
4
5
use Generator;
6
use function array_key_exists;
7
use function file_exists;
8
use function file_get_contents;
9
use function file_put_contents;
10
use function json_decode;
11
use function json_encode;
12
use function unlink;
13
14
final class LocateComposerPackageDirectDependenciesSourceFiles
15
{
16 9
    public function __invoke(string $composerJsonPath): Generator
17
    {
18 9
        $packageDir = dirname($composerJsonPath);
19
20 9
        $composerJson = json_decode(file_get_contents($composerJsonPath), true);
21 9
        $configVendorDir = $composerJson['config']['vendor-dir'] ?? 'vendor';
22
23 9
        $installedPackages = $this->getInstalledPackages($packageDir . '/' . $configVendorDir);
24
25 9
        $vendorDirs = [];
26 9
        foreach ($composerJson['require'] ?? [] as $vendorName => $vendorRequiredVersion) {
27 8
            $vendorDirs[$vendorName] = $packageDir . '/' . $configVendorDir . '/' . $vendorName;
28
        };
29
30 9
        foreach ($vendorDirs as $vendorName => $vendorDir) {
31 8
            $tmp = null;
32
33
            # If this package doesn't export its composer.json file then create a temporary one from installed.json
34 8
            if (!file_exists($vendorDir . '/composer.json')) {
35 6
                if (array_key_exists($vendorName, $installedPackages)) {
36 2
                    $tmp = $vendorDir . '/composer.json';
37 2
                    file_put_contents($tmp, json_encode($installedPackages[$vendorName]));
38
                } else {
39 4
                    continue;
40
                }
41
            }
42
43 7
            yield from (new LocateComposerPackageSourceFiles())->__invoke($vendorDir . '/composer.json');
44
45 7
            if ($tmp !== null) {
46 7
                unlink($tmp);
47
            }
48
        }
49 9
    }
50
51
52
    /**
53
     * Lookup each vendor package's composer.json info from installed.json
54
     *
55
     * @param string $vendorDir
56
     *
57
     * @return array Keys are the package name and value is the composer.json as an array
58
     */
59 9
    private function getInstalledPackages(string $vendorDir): array
60
    {
61 9
        $installedJsonPath = $vendorDir . '/composer/installed.json';
62
63 9
        if (!file_exists($installedJsonPath)) {
64 4
            return [];
65
        }
66
67 5
        $installedPackages = [];
68
69 5
        $installedJson = json_decode(file_get_contents($installedJsonPath), true);
70 5
        $packages = $installedJson['packages'] ?? $installedJson;
71 5
        foreach ($packages as $vendorJson) {
72 5
            $vendorName = $vendorJson['name'];
73 5
            $installedPackages[$vendorName] = $vendorJson;
74
        }
75
76 5
        return $installedPackages;
77
    }
78
}
79