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 ( 1e95b8...e09157 )
by Cees-Jan
03:36 queued 32s
created

Installer::findEventListeners()   B

Complexity

Conditions 10
Paths 9

Size

Total Lines 36
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 20
c 1
b 0
f 0
nc 9
nop 1
dl 0
loc 36
rs 7.6666

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('name', $json) && $json['name'] === 'wyrihaximus/test-utilities') {
80
            self::addMakeOnInstallOrUpdate($event->getIO(), $rootPackagePath);
81
82
            return;
83
        }
84
85
        if (! array_key_exists('require-dev', $json)) {
86
            return;
87
        }
88
89
        if (! is_array($json['require-dev'])) {
90
            return;
91
        }
92
93
        foreach (array_keys($json['require-dev']) as $package) {
94
            if ($package === 'wyrihaximus/test-utilities') {
95
                self::addMakeOnInstallOrUpdate($event->getIO(), $rootPackagePath);
96
97
                return;
98
            }
99
        }
100
    }
101
102
    private static function addMakeOnInstallOrUpdate(IOInterface $io, string $rootPackagePath): void
103
    {
104
        $io->write('<info>wyrihaximus/test-utilities:</info> Adding <fg=cyan>make on-install-or-update || true</> to scripts');
105
        $composerJsonString = file_get_contents($rootPackagePath . '/composer.json');
106
        if (! is_string($composerJsonString)) {
0 ignored issues
show
introduced by
The condition is_string($composerJsonString) is always true.
Loading history...
107
            $io->write('<error>wyrihaximus/test-utilities:</error> Unable to read <fg=cyan>composer.json</> aborting');
108
109
            return;
110
        }
111
112
        $composerJson     = json_decode($composerJsonString, true);
113
        $composerJsonHash = hash('sha512', (string) json_encode($composerJson, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
114
        if (is_array($composerJson) && array_key_exists('scripts', $composerJson) && is_array($composerJson['scripts'])) {
115
            if (array_key_exists('post-install-cmd', $composerJson['scripts'])) {
116
                $composerJson['scripts']['post-install-cmd'] = self::addMakeOnInstallOrUpdateToScriptsSectionAndRemoveCommandsItReplaces($composerJson['scripts']['post-install-cmd']);
117
            }
118
119
            if (array_key_exists('post-update-cmd', $composerJson['scripts'])) {
120
                $composerJson['scripts']['post-update-cmd'] = self::addMakeOnInstallOrUpdateToScriptsSectionAndRemoveCommandsItReplaces($composerJson['scripts']['post-update-cmd']);
121
            }
122
        }
123
124
        $replacementComposerJsonString = json_encode($composerJson, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
125
        if (is_string($replacementComposerJsonString)) {
0 ignored issues
show
introduced by
The condition is_string($replacementComposerJsonString) is always true.
Loading history...
126
            $replacementComposerJsonHash = hash('sha512', $replacementComposerJsonString);
127
            if (! hash_equals($composerJsonHash, $replacementComposerJsonHash)) {
128
                $replacementComposerJsonString = preg_replace('/^(  +?)\\1(?=[^ ])/m', '$1', $replacementComposerJsonString);
129
                if (is_string($replacementComposerJsonString)) {
0 ignored issues
show
introduced by
The condition is_string($replacementComposerJsonString) is always true.
Loading history...
130
                    $io->write('<info>wyrihaximus/test-utilities:</info> Writing new <fg=cyan>composer.json</>');
131
                    file_put_contents($rootPackagePath . '/composer.json', $replacementComposerJsonString);
132
                }
133
            }
134
        }
135
136
        if (is_array($composerJson) && array_key_exists('scripts', $composerJson) && is_array($composerJson['scripts'])) {
137
            if (array_key_exists('post-install-cmd', $composerJson['scripts'])) {
138
                $composerJson['scripts']['post-install-cmd'] = self::addMakeOnInstallOrUpdateToScriptsSectionAndRemoveCommandsItReplaces($composerJson['scripts']['post-install-cmd']);
139
            }
140
141
            if (array_key_exists('post-update-cmd', $composerJson['scripts'])) {
142
                $composerJson['scripts']['post-update-cmd'] = self::addMakeOnInstallOrUpdateToScriptsSectionAndRemoveCommandsItReplaces($composerJson['scripts']['post-update-cmd']);
143
            }
144
        }
145
146
        $replacementComposerJsonString = json_encode($composerJson, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
147
        if (is_string($replacementComposerJsonString)) {
0 ignored issues
show
introduced by
The condition is_string($replacementComposerJsonString) is always true.
Loading history...
148
            $replacementComposerJsonHash = hash('sha512', $replacementComposerJsonString);
149
            if (! hash_equals($composerJsonHash, $replacementComposerJsonHash)) {
150
                $replacementComposerJsonString = preg_replace('/^(  +?)\\1(?=[^ ])/m', '$1', $replacementComposerJsonString);
151
                if (is_string($replacementComposerJsonString)) {
0 ignored issues
show
introduced by
The condition is_string($replacementComposerJsonString) is always true.
Loading history...
152
                    $io->write('<info>wyrihaximus/test-utilities:</info> Writing new <fg=cyan>composer.json</>');
153
                    file_put_contents($rootPackagePath . '/composer.json', $replacementComposerJsonString);
154
                }
155
            }
156
        }
157
158
        $io->write('<info>wyrihaximus/test-utilities:</info> Finished <fg=cyan>make on-install-or-update || true</> to scripts');
159
    }
160
161
    /**
162
     * @param array<int, string> $scriptsSection
163
     *
164
     * @return array<int, string>
165
     */
166
    private static function addMakeOnInstallOrUpdateToScriptsSectionAndRemoveCommandsItReplaces(array $scriptsSection): array
167
    {
168
        foreach ($scriptsSection as $script) {
169
            if ($script === 'make on-install-or-update || true') {
170
                return $scriptsSection;
171
            }
172
        }
173
174
        $scripts = [];
175
        foreach ($scriptsSection as $script) {
176
            if ($script === 'composer normalize' || $script === 'composer update --lock --no-scripts') {
177
                continue;
178
            }
179
180
            $scripts[] = $script;
181
        }
182
183
        $scripts[] = 'make on-install-or-update || true';
184
185
        return $scripts;
186
    }
187
188
    /** @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...
189
    private static function getVendorDir(Composer $composer): string
190
    {
191
        $vendorDir = $composer->getConfig()->get('vendor-dir');
192
        if ($vendorDir === '' || ! file_exists($vendorDir)) {
193
            throw new Exception('vendor-dir must be a string');
194
        }
195
196
        return $vendorDir;
197
    }
198
}
199