Completed
Push — master ( 922e61...fe7e59 )
by Marco
10s
created

FallbackVersions::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
crap 2
1
<?php
2
3
namespace PackageVersions;
4
5
/**
6
 * @internal
7
 *
8
 * This is a fallback for {@see \PackageVersions\Versions::getVersion()}
9
 * Do not use this class directly: it is intended to be only used when
10
 * {@see \PackageVersions\Versions} fails to be generated, which typically
11
 * happens when running composer with `--no-scripts` flag)
12
 */
13
final class FallbackVersions
14
{
15
    private function __construct()
16
    {
17
    }
18
19
    /**
20
     * @param string $packageName
21
     *
22
     * @return string
23
     *
24
     * @throws \OutOfBoundsException if a version cannot be located
25
     * @throws \UnexpectedValueException if the composer.lock file could not be located
26
     */
27 1
    public static function getVersion(string $packageName) : string
28
    {
29 1
        $versions = iterator_to_array(self::getVersions(self::getComposerLockPath()));
30
31
        if (! array_key_exists($packageName, $versions)) {
32
            throw new \OutOfBoundsException(
33
                'Required package "' . $packageName . '" is not installed: cannot detect its version'
34
            );
35
        }
36
37
        return $versions[$packageName];
38
    }
39
40
    /**
41
     * @return string
42
     *
43
     * @throws \UnexpectedValueException
44
     */
45 1
    private static function getComposerLockPath() : string
46
    {
47
        // bold assumption, but there's not here to fix everyone's problems.
48 1
        $checkedPaths = [__DIR__ . '/../../../../../composer.lock', __DIR__ . '/../../composer.lock'];
49
50 1
        foreach ($checkedPaths as $path) {
51 1
            if (file_exists($path)) {
52 1
                return $path;
53
            }
54
        }
55
56 1
        throw new \UnexpectedValueException(sprintf(
57
            'PackageVersions could not locate your `composer.lock` location. This is assumed to be in %s. '
58
            . 'If you customized your composer vendor directory and ran composer installation with --no-scripts, '
59 1
            . 'then you are on your own, and we can\'t really help you. Fix your shit and cut the tooling some slack.',
60
            json_encode($checkedPaths)
61
        ));
62
    }
63
64
    private static function getVersions(string $composerLockFile) : \Generator
65
    {
66
        $lockData = json_decode(file_get_contents($composerLockFile), true);
67
68
        $lockData['packages-dev'] = $lockData['packages-dev'] ?? [];
69
70
        foreach (array_merge($lockData['packages'], $lockData['packages-dev']) as $package) {
71
            yield $package['name'] => $package['version'] . '@' . (
72
                $package['source']['reference']?? $package['dist']['reference'] ?? ''
73
            );
74
        }
75
76
        yield 'unknown/root-package@UNKNOWN';
77
    }
78
}
79