mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-03-18 04:44:53 +08:00
Add HostedPackageBin downloader and enhance artifact handling
This commit is contained in:
parent
52553fb5ed
commit
7fa6fd08d4
@ -12,6 +12,7 @@ use StaticPHP\Artifact\Downloader\Type\FileList;
|
||||
use StaticPHP\Artifact\Downloader\Type\Git;
|
||||
use StaticPHP\Artifact\Downloader\Type\GitHubRelease;
|
||||
use StaticPHP\Artifact\Downloader\Type\GitHubTarball;
|
||||
use StaticPHP\Artifact\Downloader\Type\HostedPackageBin;
|
||||
use StaticPHP\Artifact\Downloader\Type\LocalDir;
|
||||
use StaticPHP\Artifact\Downloader\Type\PhpRelease;
|
||||
use StaticPHP\Artifact\Downloader\Type\PIE;
|
||||
@ -35,6 +36,19 @@ use ZM\Logger\ConsoleColor;
|
||||
*/
|
||||
class ArtifactDownloader
|
||||
{
|
||||
public const array DOWNLOADERS = [
|
||||
'bitbuckettag' => BitBucketTag::class,
|
||||
'filelist' => FileList::class,
|
||||
'git' => Git::class,
|
||||
'ghrel' => GitHubRelease::class,
|
||||
'ghtar', 'ghtagtar' => GitHubTarball::class,
|
||||
'local' => LocalDir::class,
|
||||
'pie' => PIE::class,
|
||||
'url' => Url::class,
|
||||
'php-release' => PhpRelease::class,
|
||||
'hosted' => HostedPackageBin::class,
|
||||
];
|
||||
|
||||
/** @var array<string, Artifact> Artifact objects */
|
||||
protected array $artifacts = [];
|
||||
|
||||
@ -355,18 +369,7 @@ class ArtifactDownloader
|
||||
foreach ($queue as $item) {
|
||||
try {
|
||||
$instance = null;
|
||||
$call = match ($item['config']['type']) {
|
||||
'bitbuckettag' => BitBucketTag::class,
|
||||
'filelist' => FileList::class,
|
||||
'git' => Git::class,
|
||||
'ghrel' => GitHubRelease::class,
|
||||
'ghtar', 'ghtagtar' => GitHubTarball::class,
|
||||
'local' => LocalDir::class,
|
||||
'pie' => PIE::class,
|
||||
'url' => Url::class,
|
||||
'php-release' => PhpRelease::class,
|
||||
default => null,
|
||||
};
|
||||
$call = self::DOWNLOADERS[$item['config']['type']] ?? null;
|
||||
$type_display_name = match (true) {
|
||||
$item['lock'] === 'source' && ($callback = $artifact->getCustomSourceCallback()) !== null => 'user defined source downloader',
|
||||
$item['lock'] === 'binary' && ($callback = $artifact->getCustomBinaryCallback()) !== null => 'user defined binary downloader',
|
||||
|
||||
@ -21,6 +21,26 @@ class GitHubRelease implements DownloadTypeInterface, ValidatorInterface
|
||||
|
||||
private ?string $version = null;
|
||||
|
||||
public function getGitHubReleases(string $name, string $repo, bool $prefer_stable = true): array
|
||||
{
|
||||
logger()->debug("Fetching {$name} GitHub releases from {$repo}");
|
||||
$url = str_replace('{repo}', $repo, self::API_URL);
|
||||
$headers = $this->getGitHubTokenHeaders();
|
||||
$data2 = default_shell()->executeCurl($url, headers: $headers);
|
||||
$data = json_decode($data2 ?: '', true);
|
||||
if (!is_array($data)) {
|
||||
throw new DownloaderException("Failed to get GitHub release API info for {$repo} from {$url}");
|
||||
}
|
||||
$releases = [];
|
||||
foreach ($data as $release) {
|
||||
if ($prefer_stable && $release['prerelease'] === true) {
|
||||
continue;
|
||||
}
|
||||
$releases[] = $release;
|
||||
}
|
||||
return $releases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the latest GitHub release assets for a given repository.
|
||||
* match_asset is provided, only return the asset that matches the regex.
|
||||
|
||||
@ -7,6 +7,11 @@ namespace StaticPHP\Artifact\Downloader\Type;
|
||||
trait GitHubTokenSetupTrait
|
||||
{
|
||||
public function getGitHubTokenHeaders(): array
|
||||
{
|
||||
return self::getGitHubTokenHeadersStatic();
|
||||
}
|
||||
|
||||
public static function getGitHubTokenHeadersStatic(): array
|
||||
{
|
||||
// GITHUB_TOKEN support
|
||||
if (($token = getenv('GITHUB_TOKEN')) !== false && ($user = getenv('GITHUB_USER')) !== false) {
|
||||
|
||||
63
src/StaticPHP/Artifact/Downloader/Type/HostedPackageBin.php
Normal file
63
src/StaticPHP/Artifact/Downloader/Type/HostedPackageBin.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace StaticPHP\Artifact\Downloader\Type;
|
||||
|
||||
use StaticPHP\Artifact\ArtifactDownloader;
|
||||
use StaticPHP\Artifact\Downloader\DownloadResult;
|
||||
use StaticPHP\Exception\DownloaderException;
|
||||
use StaticPHP\Runtime\SystemTarget;
|
||||
|
||||
class HostedPackageBin implements DownloadTypeInterface
|
||||
{
|
||||
use GitHubTokenSetupTrait;
|
||||
|
||||
public const string BASE_REPO = 'static-php/package-bin';
|
||||
|
||||
public const array ASSET_MATCHES = [
|
||||
'linux' => '{name}-{arch}-{os}-{libc}-{libcver}.txz',
|
||||
'darwin' => '{name}-{arch}-{os}.txz',
|
||||
'windows' => '{name}-{arch}-{os}.tgz',
|
||||
];
|
||||
|
||||
private static array $release_info = [];
|
||||
|
||||
public static function getReleaseInfo(): array
|
||||
{
|
||||
if (empty(self::$release_info)) {
|
||||
$rel = (new GitHubRelease())->getGitHubReleases('hosted', self::BASE_REPO);
|
||||
if (empty($rel)) {
|
||||
throw new DownloaderException('No releases found for hosted package-bin');
|
||||
}
|
||||
self::$release_info = $rel[0];
|
||||
}
|
||||
return self::$release_info;
|
||||
}
|
||||
|
||||
public function download(string $name, array $config, ArtifactDownloader $downloader): DownloadResult
|
||||
{
|
||||
$info = self::getReleaseInfo();
|
||||
$replace = [
|
||||
'{name}' => $name,
|
||||
'{arch}' => SystemTarget::getTargetArch(),
|
||||
'{os}' => strtolower(SystemTarget::getTargetOS()),
|
||||
'{libc}' => SystemTarget::getLibc() ?? 'default',
|
||||
'{libcver}' => SystemTarget::getLibcVersion() ?? 'default',
|
||||
];
|
||||
$find_str = str_replace(array_keys($replace), array_values($replace), self::ASSET_MATCHES[strtolower(SystemTarget::getTargetOS())]);
|
||||
foreach ($info['assets'] as $asset) {
|
||||
if ($asset['name'] === $find_str) {
|
||||
$download_url = $asset['browser_download_url'];
|
||||
$filename = $asset['name'];
|
||||
$version = ltrim($info['tag_name'], 'v');
|
||||
logger()->debug("Downloading hosted package-bin {$name} version {$version} from GitHub: {$download_url}");
|
||||
$path = DOWNLOAD_PATH . DIRECTORY_SEPARATOR . $filename;
|
||||
$headers = $this->getGitHubTokenHeaders();
|
||||
default_shell()->executeCurlDownload($download_url, $path, headers: $headers, retries: $downloader->getRetry());
|
||||
return DownloadResult::archive($filename, $config, extract: $config['extract'] ?? null, version: $version);
|
||||
}
|
||||
}
|
||||
throw new DownloaderException("No matching asset found for hosted package-bin {$name} with criteria: {$find_str}");
|
||||
}
|
||||
}
|
||||
@ -33,7 +33,7 @@ class SPCConfigCommand extends BaseCommand
|
||||
{
|
||||
// transform string to array
|
||||
$libraries = parse_comma_list($this->getOption('with-libs'));
|
||||
$libraries = array_merge($libraries, $this->getOption('with-packages'));
|
||||
$libraries = array_merge($libraries, parse_comma_list($this->getOption('with-packages')));
|
||||
// transform string to array
|
||||
$extensions = $this->getArgument('extensions') ? parse_extension_list($this->getArgument('extensions')) : [];
|
||||
$include_suggests = $this->getOption('with-suggests') ?: $this->getOption('with-suggested-libs') || $this->getOption('with-suggested-exts');
|
||||
|
||||
@ -137,8 +137,14 @@ class ConfigValidator
|
||||
];
|
||||
continue;
|
||||
}
|
||||
// TODO: expand hosted to static-php hosted download urls
|
||||
if ($v === 'hosted') {
|
||||
$data[$name][$k] = [
|
||||
'linux-x86_64' => ['type' => 'hosted'],
|
||||
'linux-aarch64' => ['type' => 'hosted'],
|
||||
'windows-x86_64' => ['type' => 'hosted'],
|
||||
'macos-x86_64' => ['type' => 'hosted'],
|
||||
'macos-aarch64' => ['type' => 'hosted'],
|
||||
];
|
||||
continue;
|
||||
}
|
||||
if (is_assoc_array($v)) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user