174 lines
5.2 KiB
PHP
Raw Normal View History

2025-06-26 12:29:58 +07:00
<?php
declare(strict_types=1);
namespace SPC\store\pkg;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
2025-06-26 12:29:58 +07:00
use SPC\store\CurlHook;
use SPC\store\Downloader;
use SPC\store\FileSystem;
use SPC\store\LockFile;
class Zig extends CustomPackage
{
2025-07-01 14:01:48 +07:00
public static function isInstalled(): bool
{
$path = self::getPath();
2025-07-01 14:02:10 +07:00
return file_exists("{$path}/zig") && file_exists("{$path}/zig-cc") && file_exists("{$path}/zig-c++");
2025-07-01 14:01:48 +07:00
}
2025-06-26 12:29:58 +07:00
public function getSupportName(): array
{
return [
'zig-x86_64-linux',
'zig-aarch64-linux',
'zig-x86_64-macos',
'zig-aarch64-macos',
'zig-x86_64-win',
];
}
public function fetch(string $name, bool $force = false, ?array $config = null): void
{
$pkgroot = PKG_ROOT_PATH;
$zig_exec = match (PHP_OS_FAMILY) {
2025-06-29 00:49:39 +07:00
'Windows' => "{$pkgroot}/{$name}/zig.exe",
default => "{$pkgroot}/{$name}/zig",
2025-06-26 12:29:58 +07:00
};
2025-06-28 22:55:30 +07:00
if ($force) {
2025-06-29 00:49:39 +07:00
FileSystem::removeDir("{$pkgroot}/{$name}");
2025-06-28 22:55:30 +07:00
}
if (file_exists($zig_exec)) {
2025-06-26 12:29:58 +07:00
return;
}
$parts = explode('-', $name);
$arch = $parts[1];
$os = $parts[2];
$zig_arch = match ($arch) {
'x86_64', 'aarch64' => $arch,
default => throw new WrongUsageException('Unsupported architecture: ' . $arch),
2025-06-26 12:29:58 +07:00
};
$zig_os = match ($os) {
'linux' => 'linux',
'macos' => 'macos',
'win' => 'windows',
default => throw new WrongUsageException('Unsupported OS: ' . $os),
2025-06-26 12:29:58 +07:00
};
$index_json = json_decode(Downloader::curlExec('https://ziglang.org/download/index.json', hooks: [[CurlHook::class, 'setupGithubToken']]), true);
$latest_version = null;
foreach ($index_json as $version => $data) {
$latest_version = $version;
break;
}
if (!$latest_version) {
throw new RuntimeException('Could not determine latest Zig version');
2025-06-26 12:29:58 +07:00
}
logger()->info("Installing Zig version {$latest_version}");
$platform_key = "{$zig_arch}-{$zig_os}";
if (!isset($index_json[$latest_version][$platform_key])) {
throw new RuntimeException("No download available for {$platform_key} in Zig version {$latest_version}");
2025-06-26 12:29:58 +07:00
}
$download_info = $index_json[$latest_version][$platform_key];
$url = $download_info['tarball'];
$filename = basename($url);
2025-06-28 22:55:30 +07:00
$pkg = [
2025-06-26 12:29:58 +07:00
'type' => 'url',
'url' => $url,
'filename' => $filename,
];
2025-06-28 22:55:30 +07:00
Downloader::downloadPackage($name, $pkg, $force);
2025-06-26 12:29:58 +07:00
}
public function extract(string $name): void
{
$pkgroot = PKG_ROOT_PATH;
$zig_bin_dir = "{$pkgroot}/{$name}";
$zig_exec = match (PHP_OS_FAMILY) {
'Windows' => "{$zig_bin_dir}/zig.exe",
default => "{$zig_bin_dir}/zig",
};
2025-06-28 22:55:30 +07:00
if (file_exists($zig_exec) && file_exists("{$zig_bin_dir}/zig-cc")) {
2025-06-26 12:29:58 +07:00
return;
}
$lock = json_decode(FileSystem::readFile(LockFile::LOCK_FILE), true);
$source_type = $lock[$name]['source_type'];
$filename = DOWNLOAD_PATH . '/' . ($lock[$name]['filename'] ?? $lock[$name]['dirname']);
$extract = "{$pkgroot}/{$name}";
FileSystem::extractPackage($name, $source_type, $filename, $extract);
$this->createZigCcScript($zig_bin_dir);
}
2025-06-26 14:29:00 +07:00
public static function getEnvironment(): array
2025-06-26 12:29:58 +07:00
{
2025-06-26 14:29:00 +07:00
$arch = arch2gnu(php_uname('m'));
$os = match (PHP_OS_FAMILY) {
'Windows' => 'win',
'Darwin' => 'macos',
'BSD' => 'freebsd',
default => 'linux',
};
2025-06-26 12:29:58 +07:00
2025-06-26 14:29:00 +07:00
$packageName = "zig-{$arch}-{$os}";
$path = PKG_ROOT_PATH . "/{$packageName}";
return [
'PATH' => $path,
];
}
/**
* @throws WrongUsageException
*/
2025-07-01 14:02:10 +07:00
private static function getPath(): string
{
$arch = arch2gnu(php_uname('m'));
$os = match (PHP_OS_FAMILY) {
'Windows' => 'win',
'Darwin' => 'macos',
'BSD' => 'freebsd',
default => 'linux',
};
$packageName = "zig-{$arch}-{$os}";
return PKG_ROOT_PATH . "/{$packageName}";
}
2025-06-26 14:29:00 +07:00
private function createZigCcScript(string $bin_dir): void
{
2025-06-26 16:03:57 +07:00
$script_path = __DIR__ . '/../scripts/zig-cc.sh';
$script_content = file_get_contents($script_path);
2025-06-26 12:29:58 +07:00
file_put_contents("{$bin_dir}/zig-cc", $script_content);
chmod("{$bin_dir}/zig-cc", 0755);
$script_content = str_replace('zig cc', 'zig c++', $script_content);
file_put_contents("{$bin_dir}/zig-c++", $script_content);
file_put_contents("{$bin_dir}/zig-ar", "#!/usr/bin/env bash\nexec zig ar $@");
file_put_contents("{$bin_dir}/zig-ranlib", "#!/usr/bin/env bash\nexec zig ranlib $@");
file_put_contents("{$bin_dir}/zig-objcopy", "#!/usr/bin/env bash\nexec zig objcopy $@");
chmod("{$bin_dir}/zig-c++", 0755);
chmod("{$bin_dir}/zig-ar", 0755);
chmod("{$bin_dir}/zig-ranlib", 0755);
chmod("{$bin_dir}/zig-objcopy", 0755);
}
2025-06-26 12:29:58 +07:00
}