Skip to content

Commit a0dbe00

Browse files
committed
[FIX] Installer.
1 parent 78bb006 commit a0dbe00

1 file changed

Lines changed: 97 additions & 34 deletions

File tree

bin/evo

Lines changed: 97 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -120,22 +120,22 @@ final class EvoBootstrapper
120120
$memoryLimit = ini_get('memory_limit') ?: 'Unknown';
121121

122122
$items = [
123-
['key' => 'os', 'label' => $os, 'level' => 'ok'],
124-
['key' => 'php', 'label' => "PHP - {$phpVersion}", 'level' => $phpOk ? 'ok' : 'error'],
125-
['key' => 'composer', 'label' => "Composer" . ($composerVersion ? " - {$composerVersion}" : ''), 'level' => $composerOk ? 'ok' : 'warn'],
126-
['key' => 'pdo', 'label' => 'PDO extension', 'level' => $pdoOk ? 'ok' : 'error'],
123+
['key' => 'os', 'label' => $os, 'level' => 'ok'],
124+
['key' => 'php', 'label' => "PHP - {$phpVersion}", 'level' => $phpOk ? 'ok' : 'error'],
125+
['key' => 'composer', 'label' => "Composer" . ($composerVersion ? " - {$composerVersion}" : ''), 'level' => $composerOk ? 'ok' : 'warn'],
126+
['key' => 'pdo', 'label' => 'PDO extension', 'level' => $pdoOk ? 'ok' : 'error'],
127127
// DB drivers: if unavailable, mark as warning (optional until user chooses a DB).
128-
['key' => 'pdo_mysql', 'label' => 'PDO MySQL driver', 'level' => $pdoMysqlOk ? 'ok' : 'warn'],
129-
['key' => 'pdo_pgsql', 'label' => 'PDO PostgreSQL driver', 'level' => $pdoPgsqlOk ? 'ok' : 'warn'],
130-
['key' => 'pdo_sqlite', 'label' => 'PDO SQLite driver', 'level' => $pdoSqliteOk ? 'ok' : 'warn'],
131-
['key' => 'pdo_sqlsrv', 'label' => 'PDO SQL Server driver', 'level' => $pdoSqlsrvOk ? 'ok' : 'warn'],
132-
['key' => 'json', 'label' => 'JSON extension', 'level' => $jsonOk ? 'ok' : 'error'],
133-
['key' => 'mysqli', 'label' => 'MySQLi extension', 'level' => $mysqliOk ? 'ok' : 'error'],
134-
['key' => 'mbstring', 'label' => 'MBString extension', 'level' => $mbstringOk ? 'ok' : 'error'],
135-
['key' => 'curl', 'label' => 'cURL extension', 'level' => $curlOk ? 'ok' : 'warn'],
136-
['key' => 'image', 'label' => $imageLabel, 'level' => $imageOk ? 'ok' : 'warn'],
137-
['key' => 'disk_free', 'label' => 'Disk free - ' . ($diskFree ?: 'Unknown'), 'level' => $diskFree !== null ? 'ok' : 'warn'],
138-
['key' => 'memory_limit', 'label' => 'Memory limit - ' . $memoryLimit, 'level' => 'ok'],
128+
['key' => 'pdo_mysql', 'label' => 'PDO MySQL driver', 'level' => $pdoMysqlOk ? 'ok' : 'warn'],
129+
['key' => 'pdo_pgsql', 'label' => 'PDO PostgreSQL driver', 'level' => $pdoPgsqlOk ? 'ok' : 'warn'],
130+
['key' => 'pdo_sqlite', 'label' => 'PDO SQLite driver', 'level' => $pdoSqliteOk ? 'ok' : 'warn'],
131+
['key' => 'pdo_sqlsrv', 'label' => 'PDO SQL Server driver', 'level' => $pdoSqlsrvOk ? 'ok' : 'warn'],
132+
['key' => 'json', 'label' => 'JSON extension', 'level' => $jsonOk ? 'ok' : 'error'],
133+
['key' => 'mysqli', 'label' => 'MySQLi extension', 'level' => $mysqliOk ? 'ok' : 'error'],
134+
['key' => 'mbstring', 'label' => 'MBString extension', 'level' => $mbstringOk ? 'ok' : 'error'],
135+
['key' => 'curl', 'label' => 'cURL extension', 'level' => $curlOk ? 'ok' : 'warn'],
136+
['key' => 'image', 'label' => $imageLabel, 'level' => $imageOk ? 'ok' : 'warn'],
137+
['key' => 'disk_free', 'label' => 'Disk free - ' . ($diskFree ?: 'Unknown'), 'level' => $diskFree !== null ? 'ok' : 'warn'],
138+
['key' => 'memory_limit', 'label' => 'Memory limit - ' . $memoryLimit, 'level' => 'ok'],
139139
];
140140

141141
$overall = 'ok';
@@ -150,9 +150,9 @@ final class EvoBootstrapper
150150
}
151151

152152
return [
153-
'status' => $overall,
154-
'overall' => $overall,
155-
'items' => $items,
153+
'status' => $overall,
154+
'overall' => $overall,
155+
'items' => $items,
156156
];
157157
}
158158

@@ -240,7 +240,11 @@ final class EvoBootstrapper
240240
private function selfUpdate(): void
241241
{
242242
$current = $this->getInstalledVersion() ?? '(not installed)';
243-
[$tag] = $this->getLatestReleaseInfo();
243+
try {
244+
[$tag] = $this->getLatestReleaseInfo();
245+
} catch (RuntimeException $e) {
246+
$tag = $this->resolveLatestReleaseTagFallback() ?? 'latest';
247+
}
244248
$this->out("Current: {$current}");
245249
$this->out("Latest: {$tag}");
246250
$this->installBinary(true);
@@ -250,11 +254,19 @@ final class EvoBootstrapper
250254
{
251255
$this->assertWritableDir($this->binDir);
252256

253-
[$tag, $assets] = $this->getLatestReleaseInfo();
254257
[$expectedAssetName, $installedBinaryPath] = $this->resolveAssetNameAndBinaryPath();
255258

256-
$checksumsUrl = $this->findAssetUrl($assets, 'checksums.txt');
257-
$binaryUrl = $this->findAssetUrl($assets, $expectedAssetName);
259+
try {
260+
[$tag, $assets] = $this->getLatestReleaseInfo();
261+
$checksumsUrl = $this->findAssetUrl($assets, 'checksums.txt');
262+
$binaryUrl = $this->findAssetUrl($assets, $expectedAssetName);
263+
} catch (RuntimeException $e) {
264+
// GitHub API may return 403 due to rate limits or enterprise firewalls.
265+
// Fall back to direct "latest" asset URLs which do not require API access.
266+
$tag = $this->resolveLatestReleaseTagFallback() ?? 'latest';
267+
$checksumsUrl = $this->getLatestDirectAssetUrl('checksums.txt');
268+
$binaryUrl = $this->getLatestDirectAssetUrl($expectedAssetName);
269+
}
258270

259271
$checksums = $this->downloadString($checksumsUrl);
260272
$shaMap = $this->parseChecksums($checksums);
@@ -385,6 +397,57 @@ final class EvoBootstrapper
385397
return [$tag, $assets];
386398
}
387399

400+
private function getLatestDirectAssetUrl(string $assetName): string
401+
{
402+
$assetName = ltrim($assetName, "/\\");
403+
$url = 'https://github.com/' . self::REPO . '/releases/latest/download/' . rawurlencode($assetName);
404+
$this->assertHttpsUrl($url);
405+
return $url;
406+
}
407+
408+
private function resolveLatestReleaseTagFallback(): ?string
409+
{
410+
$url = 'https://github.com/' . self::REPO . '/releases/latest';
411+
$this->assertHttpsUrl($url);
412+
413+
if (function_exists('curl_init')) {
414+
$ch = curl_init();
415+
if ($ch !== false) {
416+
curl_setopt($ch, CURLOPT_URL, $url);
417+
curl_setopt($ch, CURLOPT_NOBODY, true);
418+
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
419+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
420+
curl_setopt($ch, CURLOPT_HEADER, true);
421+
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
422+
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->createHttpHeaders(false));
423+
curl_exec($ch);
424+
$redirect = curl_getinfo($ch, CURLINFO_REDIRECT_URL);
425+
curl_close($ch);
426+
427+
if (is_string($redirect) && $redirect !== '') {
428+
if (preg_match('~/releases/tag/([^/?#]+)~', $redirect, $m)) {
429+
return $m[1];
430+
}
431+
}
432+
}
433+
}
434+
435+
$headers = @get_headers($url, true);
436+
if (is_array($headers)) {
437+
$location = $headers['Location'] ?? $headers['location'] ?? null;
438+
if (is_array($location)) {
439+
$location = end($location) ?: null;
440+
}
441+
if (is_string($location) && $location !== '') {
442+
if (preg_match('~/releases/tag/([^/?#]+)~', $location, $m)) {
443+
return $m[1];
444+
}
445+
}
446+
}
447+
448+
return null;
449+
}
450+
388451
/**
389452
* @param array<int, array<string, mixed>> $assets
390453
*/
@@ -538,7 +601,7 @@ final class EvoBootstrapper
538601
private function createHttpHeaders(bool $isApi): array
539602
{
540603
$headers = [
541-
'User-Agent: evo-bootstrapper',
604+
'User-Agent: evo-bootstrapper',
542605
];
543606
if ($isApi) {
544607
$headers[] = 'Accept: application/vnd.github+json';
@@ -554,17 +617,17 @@ final class EvoBootstrapper
554617
private function createHttpContext(bool $isApi): mixed
555618
{
556619
return stream_context_create([
557-
'http' => [
558-
'method' => 'GET',
559-
'header' => implode("\r\n", $this->createHttpHeaders($isApi)),
560-
'timeout' => 60,
561-
'follow_location' => 1,
562-
'max_redirects' => 5,
563-
],
564-
'ssl' => [
565-
'verify_peer' => true,
566-
'verify_peer_name' => true,
567-
],
620+
'http' => [
621+
'method' => 'GET',
622+
'header' => implode("\r\n", $this->createHttpHeaders($isApi)),
623+
'timeout' => 60,
624+
'follow_location' => 1,
625+
'max_redirects' => 5,
626+
],
627+
'ssl' => [
628+
'verify_peer' => true,
629+
'verify_peer_name' => true,
630+
],
568631
]);
569632
}
570633

0 commit comments

Comments
 (0)