Completed
Pull Request — master (#163)
by Guillaume
04:49
created

__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace ComposerRequireChecker\FileLocator;
4
5
use ComposerRequireChecker\Exception\DependenciesNotInstalledException;
6
use ComposerRequireChecker\Exception\NotReadableException;
7
use ComposerRequireChecker\JsonLoader;
8
use Generator;
9
use function array_key_exists;
10
use function file_get_contents;
11
use function json_decode;
12
13
final class LocateComposerPackageDirectDependenciesSourceFiles
14
{
15
    /**
16
     * @var bool
17
     */
18
    private $includeDev;
19
20
    /**
21
     * LocateComposerPackageDirectDependenciesSourceFiles constructor.
22
     *
23
     * @param bool $includeDev Wether to include packages from require-dev or not.
24
     */
25 12
    public function __construct(bool $includeDev)
26
    {
27 12
        $this->includeDev = $includeDev;
28 12
    }
29
30 12
    public function __invoke(string $composerJsonPath): Generator
31
    {
32 12
        $packageDir = dirname($composerJsonPath);
33
34 12
        $composerJson = json_decode(file_get_contents($composerJsonPath), true);
35 12
        $configVendorDir = $composerJson['config']['vendor-dir'] ?? 'vendor';
36 12
        $vendorDirs = [];
37 12
        foreach ($composerJson['require'] ?? [] as $vendorName => $vendorRequiredVersion) {
38 11
            $vendorDirs[$vendorName] = $packageDir . '/' . $configVendorDir . '/' . $vendorName;
39
        }
40 12
        if ($this->includeDev) {
41 1
            foreach ($composerJson['require-dev'] ?? [] as $vendorName => $vendorRequiredVersion) {
42 1
                $vendorDirs[$vendorName] = $packageDir . '/' . $configVendorDir . '/' . $vendorName;
43
            }
44
        }
45
46 12
        $installedPackages = $this->getInstalledPackages($packageDir . '/' . $configVendorDir);
47
48 12
        foreach ($vendorDirs as $vendorName => $vendorDir) {
49 11
            if (!array_key_exists($vendorName, $installedPackages)) {
50 5
                continue;
51
            }
52
53 10
            yield from (new LocateComposerPackageSourceFiles(false))->__invoke($installedPackages[$vendorName], $vendorDir);
54
        }
55 12
    }
56
57
58
    /**
59
     * Lookup each vendor package's composer.json info from installed.json
60
     *
61
     * @param string $vendorDir
62
     *
63
     * @return array Keys are the package name and value is the composer.json as an array
64
     * @throws DependenciesNotInstalledException When composer install/update has not been run
65
     */
66 12
    private function getInstalledPackages(string $vendorDir): array
67
    {
68
        try {
69 12
            $installedData = (new JsonLoader($vendorDir . '/composer/installed.json'))->getData();
70
        } catch (NotReadableException $e) {
71
            $message = 'The composer dependencies have not been installed, run composer install/update first';
72
            throw new DependenciesNotInstalledException($message);
73
        }
74
75 12
        $installedPackages = [];
76
77 12
        $packages = $installedData['packages'] ?? $installedData;
78 12
        foreach ($packages as $vendorJson) {
79 10
            $vendorName = $vendorJson['name'];
80 10
            $installedPackages[$vendorName] = $vendorJson;
81
        }
82
83 12
        return $installedPackages;
84
    }
85
}
86