Completed
Pull Request — master (#15)
by Marco
03:10
created

Installer::getRootPackageAlias()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2
Metric Value
dl 0
loc 10
ccs 5
cts 5
cp 1
rs 9.4285
cc 2
eloc 5
nc 2
nop 1
crap 2
1
<?php
2
3
namespace PackageVersions;
4
5
use Composer\Composer;
6
use Composer\Config;
7
use Composer\EventDispatcher\EventSubscriberInterface;
8
use Composer\IO\IOInterface;
9
use Composer\Package\AliasPackage;
10
use Composer\Package\Locker;
11
use Composer\Package\PackageInterface;
12
use Composer\Package\RootPackageInterface;
13
use Composer\Plugin\PluginInterface;
14
use Composer\Script\Event;
15
use Composer\Script\ScriptEvents;
16
17
final class Installer implements PluginInterface, EventSubscriberInterface
18
{
19
    private static $generatedClassTemplate = <<<'PHP'
20
<?php
21
22
namespace PackageVersions;
23
24
/**
25
 * This class is generated by ocramius/package-versions, specifically by
26
 * @see \PackageVersions\Installer
27
 *
28
 * This file is overwritten at every run of `composer install` or `composer update`.
29
 */
30
final class Versions
31
{
32
    const VERSIONS = %s;
33
34
    private function __construct()
35
    {
36
    }
37
38
    /**
39
     * @throws \OutOfBoundsException if a version cannot be located
40
     */
41
    public static function getVersion(string $packageName) : string
42
    {
43
        if (! isset(self::VERSIONS[$packageName])) {
44
            throw new \OutOfBoundsException(
45
                'Required package "' . $packageName . '" is not installed: cannot detect its version'
46
            );
47
        }
48
49
        return self::VERSIONS[$packageName];
50
    }
51
}
52
53
PHP;
54
55
    /**
56
     * {@inheritDoc}
57
     */
58 1
    public function activate(Composer $composer, IOInterface $io)
59
    {
60 1
        $composer->getEventDispatcher()->addSubscriber($this);
61 1
    }
62
63
    /**
64
     * {@inheritDoc}
65
     */
66 1
    public static function getSubscribedEvents()
67
    {
68
        return [
69 1
            ScriptEvents::POST_INSTALL_CMD => 'dumpVersionsClass',
70 1
            ScriptEvents::POST_UPDATE_CMD  => 'dumpVersionsClass',
71
        ];
72
    }
73
74
    /**
75
     * @param Event $composerEvent
76
     *
77
     * @return void
78
     *
79
     * @throws \RuntimeException
80
     */
81 9
    public static function dumpVersionsClass(Event $composerEvent)
82
    {
83 9
        $io = $composerEvent->getIO();
84
85 9
        $io->write('<info>ocramius/package-versions:</info>  Generating version class...');
86
87 9
        $composer = $composerEvent->getComposer();
88
89 9
        self::writeVersionClassToFile(
90 9
            self::generateVersionsClass($composer),
91 9
            $composer->getConfig(),
92 9
            $composer->getPackage()
93
        );
94
95 9
        $io->write('<info>ocramius/package-versions:</info> ...done generating version class');
96 9
    }
97
98 9
    private static function generateVersionsClass(Composer $composer) : string
99
    {
100 9
        return sprintf(
101 9
            self::$generatedClassTemplate,
102 9
            var_export(iterator_to_array(self::getVersions($composer->getLocker(), $composer->getPackage())), true)
103
        );
104
    }
105
106
    /**
107
     * @param string               $versionClassSource
108
     * @param Config               $composerConfig
109
     * @param RootPackageInterface $rootPackage
110
     *
111
     * @return void
112
     *
113
     * @throws \RuntimeException
114
     */
115 9
    private static function writeVersionClassToFile(
116
        string $versionClassSource,
117
        Config $composerConfig,
118
        RootPackageInterface $rootPackage
119
    ) {
120 9
        file_put_contents(
121 9
            self::locateRootPackageInstallPath($composerConfig, $rootPackage)
122 9
            . '/src/PackageVersions/Versions.php',
123
            $versionClassSource,
124 9
            0664
125
        );
126 9
    }
127
128
    /**
129
     * @param Config               $composerConfig
130
     * @param RootPackageInterface $rootPackage
131
     *
132
     * @return string
133
     *
134
     * @throws \RuntimeException
135
     */
136 9
    private static function locateRootPackageInstallPath(
137
        Config $composerConfig,
138
        RootPackageInterface $rootPackage
139
    ) : string {
0 ignored issues
show
Coding Style introduced by
There must be a single space between the closing parenthesis and the opening brace of a multi-line function declaration
Loading history...
140 9
        if ('ocramius/package-versions' === self::getRootPackageAlias($rootPackage)->getName()) {
141 3
            return dirname($composerConfig->get('vendor-dir'));
142
        }
143
144 6
        return $composerConfig->get('vendor-dir') . '/ocramius/package-versions';
145
    }
146
147 9
    private static function getRootPackageAlias(RootPackageInterface $rootPackage) : PackageInterface
148
    {
149 9
        $package = $rootPackage;
150
151 9
        while ($package instanceof AliasPackage) {
152 4
            $package = $package->getAliasOf();
153
        }
154
155 9
        return $package;
156
    }
157
158
    /**
159
     * @param Locker               $locker
160
     * @param RootPackageInterface $rootPackage
161
     *
162
     * @return \Generator|\string[]
163
     */
164 9
    private static function getVersions(Locker $locker, RootPackageInterface $rootPackage) : \Generator
165
    {
166 9
        $lockData = $locker->getLockData();
167
168 9
        $lockData['packages-dev'] = $lockData['packages-dev'] ?? [];
169
170 9
        foreach (array_merge($lockData['packages'], $lockData['packages-dev'])  as $package) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space before "as"; 2 found
Loading history...
171 3
            yield $package['name'] => $package['version'] . '@' . (
172 3
                $package['source']['reference']?? $package['dist']['reference'] ?? ''
173
            );
174
        }
175
176 9
        yield $rootPackage->getName() => $rootPackage->getVersion() . '@' . $rootPackage->getSourceReference();
177
    }
178
}