Repository navigation
Expand file tree
/
Copy pathPlatform.php
More file actions
136 lines (118 loc) · 3.86 KB
/
Copy pathPlatform.php
File metadata and controls
136 lines (118 loc) · 3.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<?php
declare(strict_types=1);
namespace App\Launcher;
use function implode;
use function array_keys;
use function strtolower;
use function php_uname;
/**
* Maps the host operating system and CPU architecture onto the identifiers
* used for release artifacts and for the runtime cache directory.
*
* Every supported combination is enumerated explicitly; unknown combinations
* are an error rather than a guess, so a user on an unsupported platform gets
* a clear message instead of a download that cannot run.
*/
final class Platform
{
/**
* The release artifacts published for each supported platform.
*
* @var array<string, string>
*/
private const ASSETS = [
'linux-x86_64' => 'hyde-linux-x86_64',
'linux-arm64' => 'hyde-linux-arm64',
'macos-x86_64' => 'hyde-macos-x86_64',
'macos-arm64' => 'hyde-macos-arm64',
'windows-x86_64' => 'hyde-windows-x86_64.exe',
];
public function __construct(
/** The operating system family, as reported by PHP_OS_FAMILY. */
public readonly string $os,
/** The raw machine architecture, as reported by php_uname('m'). */
public readonly string $architecture,
) {
//
}
public static function current(): self
{
return new self(PHP_OS_FAMILY, php_uname('m'));
}
public function isWindows(): bool
{
return $this->os === 'Windows';
}
/**
* The canonical platform slug, such as `macos-arm64`.
*
* Used both to name release assets and to namespace the extracted runtime cache,
* so a cache directory shared over a network mount can never hand a binary
* for one platform to a machine running another.
*/
public function slug(): string
{
return $this->normalizeOs().'-'.$this->normalizeArchitecture();
}
/**
* The name of the release asset to download for this platform.
*
* @throws \App\Launcher\LauncherException If this platform has no published artifact.
*/
public function releaseAsset(): string
{
$slug = $this->slug();
return self::ASSETS[$slug] ?? throw new LauncherException(
"There is no HydeCLI release artifact for your platform ($this->os $this->architecture).\n\n".
'Supported platforms are: '.implode(', ', array_keys(self::ASSETS)).'.'
);
}
/**
* The name of the detached GPG signature published alongside this platform's artifact.
*/
public function signatureAsset(): string
{
return $this->releaseAsset().'.sig';
}
/**
* The name of the OpenSSL signature published alongside this platform's artifact.
*
* This is the signature the self-update command verifies, since OpenSSL is bundled
* with the executable while GPG may not be present on the user's machine.
*/
public function opensslSignatureAsset(): string
{
return $this->releaseAsset().'.sig.bin';
}
public function supported(): bool
{
return isset(self::ASSETS[$this->slug()]);
}
/** @return array<string, string> */
public static function assetMap(): array
{
return self::ASSETS;
}
/** The file name the PHP CLI runtime has on this platform. */
public function runtimeFilename(): string
{
return $this->isWindows() ? 'php.exe' : 'php';
}
private function normalizeOs(): string
{
return match ($this->os) {
'Darwin' => 'macos',
'Linux' => 'linux',
'Windows' => 'windows',
default => strtolower($this->os),
};
}
private function normalizeArchitecture(): string
{
return match (strtolower($this->architecture)) {
'x86_64', 'amd64', 'x64' => 'x86_64',
'arm64', 'aarch64' => 'arm64',
default => strtolower($this->architecture),
};
}
}