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.

Issues (8)

src/Composer/Installer.php (7 issues)

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