GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( e09157...64b15f )
by Cees-Jan
03:50 queued 49s
created

Installer::findEventListeners()   C

Complexity

Conditions 13
Paths 20

Size

Total Lines 50
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 13
eloc 28
c 2
b 0
f 1
nc 20
nop 1
dl 0
loc 50
rs 6.6166

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace WyriHaximus\TestUtilities\Composer;
6
7
use Composer\Composer;
8
use Composer\EventDispatcher\EventSubscriberInterface;
9
use Composer\IO\IOInterface;
10
use Composer\Plugin\PluginInterface;
11
use Composer\Script\Event;
12
use Composer\Script\ScriptEvents;
13
use Exception;
14
15
use function array_key_exists;
16
use function array_keys;
17
use function dirname;
18
use function file_exists;
19
use function file_get_contents;
20
use function file_put_contents;
21
use function hash;
22
use function hash_equals;
23
use function is_array;
24
use function is_string;
25
use function json_decode;
26
use function json_encode;
27
use function preg_replace;
28
29
use const DIRECTORY_SEPARATOR;
30
use const JSON_PRETTY_PRINT;
31
use const JSON_UNESCAPED_SLASHES;
32
use const PHP_INT_MAX;
33
34
final class Installer implements PluginInterface, EventSubscriberInterface
35
{
36
    /** @return array<string, array<string|int>> */
37
    public static function getSubscribedEvents(): array
38
    {
39
        return [ScriptEvents::PRE_AUTOLOAD_DUMP => ['findEventListeners', PHP_INT_MAX]];
40
    }
41
42
    public function activate(Composer $composer, IOInterface $io): void
43
    {
44
        // does nothing, see getSubscribedEvents() instead.
45
    }
46
47
    public function deactivate(Composer $composer, IOInterface $io): void
48
    {
49
        // does nothing, see getSubscribedEvents() instead.
50
    }
51
52
    public function uninstall(Composer $composer, IOInterface $io): void
53
    {
54
        // does nothing, see getSubscribedEvents() instead.
55
    }
56
57
    /**
58
     * Called before every dump autoload, generates a fresh PHP class.
59
     *
60
     * @phpstan-ignore shipmonk.deadMethod
61
     */
62
    public static function findEventListeners(Event $event): void
63
    {
64
        $rootPackagePath = dirname(self::getVendorDir($event->getComposer())) . DIRECTORY_SEPARATOR;
65
        if (! file_exists($rootPackagePath . '/composer.json')) {
66
            return;
67
        }
68
69
        $jsonRaw = file_get_contents($rootPackagePath . '/composer.json');
70
        if (! is_string($jsonRaw)) {
0 ignored issues
show
introduced by
The condition is_string($jsonRaw) is always true.
Loading history...
71
            return;
72
        }
73
74
        $json = json_decode($jsonRaw, true);
75
        if (! is_array($json)) {
76
            return;
77
        }
78
79
        if (! array_key_exists('require-dev', $json)) {
80
            return;
81
        }
82
83
        if (! is_array($json['require-dev'])) {
84
            return;
85
        }
86
87
        $hasMakefiles = false;
88
        foreach (array_keys($json['require-dev']) as $package) {
89
            if ($package === 'wyrihaximus/makefiles') {
90
                $hasMakefiles = true;
91
                break;
92
            }
93
        }
94
95
        if (! $hasMakefiles) {
96
            return;
97
        }
98
99
        unset($hasMakefiles);
100
101
        if (array_key_exists('name', $json) && $json['name'] === 'wyrihaximus/test-utilities') {
102
            self::addMakeOnInstallOrUpdate($event->getIO(), $rootPackagePath);
103
104
            return;
105
        }
106
107
        foreach (array_keys($json['require-dev']) as $package) {
108
            if ($package === 'wyrihaximus/test-utilities') {
109
                self::addMakeOnInstallOrUpdate($event->getIO(), $rootPackagePath);
110
111
                return;
112
            }
113
        }
114
    }
115
116
    private static function addMakeOnInstallOrUpdate(IOInterface $io, string $rootPackagePath): void
117
    {
118
        $io->write('<info>wyrihaximus/test-utilities:</info> Adding <fg=cyan>make on-install-or-update || true</> to scripts');
119
        $composerJsonString = file_get_contents($rootPackagePath . '/composer.json');
120
        if (! is_string($composerJsonString)) {
0 ignored issues
show
introduced by
The condition is_string($composerJsonString) is always true.
Loading history...
121
            $io->write('<error>wyrihaximus/test-utilities:</error> Unable to read <fg=cyan>composer.json</> aborting');
122
123
            return;
124
        }
125
126
        $composerJson     = json_decode($composerJsonString, true);
127
        $composerJsonHash = hash('sha512', (string) json_encode($composerJson, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
128
        if (is_array($composerJson) && array_key_exists('scripts', $composerJson) && is_array($composerJson['scripts'])) {
129
            if (array_key_exists('post-install-cmd', $composerJson['scripts'])) {
130
                $composerJson['scripts']['post-install-cmd'] = self::addMakeOnInstallOrUpdateToScriptsSectionAndRemoveCommandsItReplaces($composerJson['scripts']['post-install-cmd']);
131
            }
132
133
            if (array_key_exists('post-update-cmd', $composerJson['scripts'])) {
134
                $composerJson['scripts']['post-update-cmd'] = self::addMakeOnInstallOrUpdateToScriptsSectionAndRemoveCommandsItReplaces($composerJson['scripts']['post-update-cmd']);
135
            }
136
        }
137
138
        $replacementComposerJsonString = json_encode($composerJson, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
139
        if (is_string($replacementComposerJsonString)) {
0 ignored issues
show
introduced by
The condition is_string($replacementComposerJsonString) is always true.
Loading history...
140
            $replacementComposerJsonHash = hash('sha512', $replacementComposerJsonString);
141
            if (! hash_equals($composerJsonHash, $replacementComposerJsonHash)) {
142
                $replacementComposerJsonString = preg_replace('/^(  +?)\\1(?=[^ ])/m', '$1', $replacementComposerJsonString);
143
                if (is_string($replacementComposerJsonString)) {
0 ignored issues
show
introduced by
The condition is_string($replacementComposerJsonString) is always true.
Loading history...
144
                    $io->write('<info>wyrihaximus/test-utilities:</info> Writing new <fg=cyan>composer.json</>');
145
                    file_put_contents($rootPackagePath . '/composer.json', $replacementComposerJsonString);
146
                }
147
            }
148
        }
149
150
        if (is_array($composerJson) && array_key_exists('scripts', $composerJson) && is_array($composerJson['scripts'])) {
151
            if (array_key_exists('post-install-cmd', $composerJson['scripts'])) {
152
                $composerJson['scripts']['post-install-cmd'] = self::addMakeOnInstallOrUpdateToScriptsSectionAndRemoveCommandsItReplaces($composerJson['scripts']['post-install-cmd']);
153
            }
154
155
            if (array_key_exists('post-update-cmd', $composerJson['scripts'])) {
156
                $composerJson['scripts']['post-update-cmd'] = self::addMakeOnInstallOrUpdateToScriptsSectionAndRemoveCommandsItReplaces($composerJson['scripts']['post-update-cmd']);
157
            }
158
        }
159
160
        $replacementComposerJsonString = json_encode($composerJson, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
161
        if (is_string($replacementComposerJsonString)) {
0 ignored issues
show
introduced by
The condition is_string($replacementComposerJsonString) is always true.
Loading history...
162
            $replacementComposerJsonHash = hash('sha512', $replacementComposerJsonString);
163
            if (! hash_equals($composerJsonHash, $replacementComposerJsonHash)) {
164
                $replacementComposerJsonString = preg_replace('/^(  +?)\\1(?=[^ ])/m', '$1', $replacementComposerJsonString);
165
                if (is_string($replacementComposerJsonString)) {
0 ignored issues
show
introduced by
The condition is_string($replacementComposerJsonString) is always true.
Loading history...
166
                    $io->write('<info>wyrihaximus/test-utilities:</info> Writing new <fg=cyan>composer.json</>');
167
                    file_put_contents($rootPackagePath . '/composer.json', $replacementComposerJsonString . "\r\n");
168
                }
169
            }
170
        }
171
172
        $io->write('<info>wyrihaximus/test-utilities:</info> Finished <fg=cyan>make on-install-or-update || true</> to scripts');
173
    }
174
175
    /**
176
     * @param array<int, string> $scriptsSection
177
     *
178
     * @return array<int, string>
179
     */
180
    private static function addMakeOnInstallOrUpdateToScriptsSectionAndRemoveCommandsItReplaces(array $scriptsSection): array
181
    {
182
        foreach ($scriptsSection as $script) {
183
            if ($script === 'make on-install-or-update || true') {
184
                return $scriptsSection;
185
            }
186
        }
187
188
        $scripts = [];
189
        foreach ($scriptsSection as $script) {
190
            if ($script === 'composer normalize' || $script === 'composer update --lock --no-scripts') {
191
                continue;
192
            }
193
194
            $scripts[] = $script;
195
        }
196
197
        $scripts[] = 'make on-install-or-update || true';
198
199
        return $scripts;
200
    }
201
202
    /** @return non-empty-string */
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
203
    private static function getVendorDir(Composer $composer): string
204
    {
205
        $vendorDir = $composer->getConfig()->get('vendor-dir');
206
        if ($vendorDir === '' || ! file_exists($vendorDir)) {
207
            throw new Exception('vendor-dir must be a string');
208
        }
209
210
        return $vendorDir;
211
    }
212
}
213