mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-03-19 13:24:51 +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\Git;
|
||||||
use StaticPHP\Artifact\Downloader\Type\GitHubRelease;
|
use StaticPHP\Artifact\Downloader\Type\GitHubRelease;
|
||||||
use StaticPHP\Artifact\Downloader\Type\GitHubTarball;
|
use StaticPHP\Artifact\Downloader\Type\GitHubTarball;
|
||||||
|
use StaticPHP\Artifact\Downloader\Type\HostedPackageBin;
|
||||||
use StaticPHP\Artifact\Downloader\Type\LocalDir;
|
use StaticPHP\Artifact\Downloader\Type\LocalDir;
|
||||||
use StaticPHP\Artifact\Downloader\Type\PhpRelease;
|
use StaticPHP\Artifact\Downloader\Type\PhpRelease;
|
||||||
use StaticPHP\Artifact\Downloader\Type\PIE;
|
use StaticPHP\Artifact\Downloader\Type\PIE;
|
||||||
@ -35,6 +36,19 @@ use ZM\Logger\ConsoleColor;
|
|||||||
*/
|
*/
|
||||||
class ArtifactDownloader
|
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 */
|
/** @var array<string, Artifact> Artifact objects */
|
||||||
protected array $artifacts = [];
|
protected array $artifacts = [];
|
||||||
|
|
||||||
@ -355,18 +369,7 @@ class ArtifactDownloader
|
|||||||
foreach ($queue as $item) {
|
foreach ($queue as $item) {
|
||||||
try {
|
try {
|
||||||
$instance = null;
|
$instance = null;
|
||||||
$call = match ($item['config']['type']) {
|
$call = self::DOWNLOADERS[$item['config']['type']] ?? null;
|
||||||
'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,
|
|
||||||
};
|
|
||||||
$type_display_name = match (true) {
|
$type_display_name = match (true) {
|
||||||
$item['lock'] === 'source' && ($callback = $artifact->getCustomSourceCallback()) !== null => 'user defined source downloader',
|
$item['lock'] === 'source' && ($callback = $artifact->getCustomSourceCallback()) !== null => 'user defined source downloader',
|
||||||
$item['lock'] === 'binary' && ($callback = $artifact->getCustomBinaryCallback()) !== null => 'user defined binary 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;
|
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.
|
* Get the latest GitHub release assets for a given repository.
|
||||||
* match_asset is provided, only return the asset that matches the regex.
|
* match_asset is provided, only return the asset that matches the regex.
|
||||||
|
|||||||
@ -7,6 +7,11 @@ namespace StaticPHP\Artifact\Downloader\Type;
|
|||||||
trait GitHubTokenSetupTrait
|
trait GitHubTokenSetupTrait
|
||||||
{
|
{
|
||||||
public function getGitHubTokenHeaders(): array
|
public function getGitHubTokenHeaders(): array
|
||||||
|
{
|
||||||
|
return self::getGitHubTokenHeadersStatic();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getGitHubTokenHeadersStatic(): array
|
||||||
{
|
{
|
||||||
// GITHUB_TOKEN support
|
// GITHUB_TOKEN support
|
||||||
if (($token = getenv('GITHUB_TOKEN')) !== false && ($user = getenv('GITHUB_USER')) !== false) {
|
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
|
// transform string to array
|
||||||
$libraries = parse_comma_list($this->getOption('with-libs'));
|
$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
|
// transform string to array
|
||||||
$extensions = $this->getArgument('extensions') ? parse_extension_list($this->getArgument('extensions')) : [];
|
$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');
|
$include_suggests = $this->getOption('with-suggests') ?: $this->getOption('with-suggested-libs') || $this->getOption('with-suggested-exts');
|
||||||
|
|||||||
@ -137,8 +137,14 @@ class ConfigValidator
|
|||||||
];
|
];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// TODO: expand hosted to static-php hosted download urls
|
|
||||||
if ($v === 'hosted') {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
if (is_assoc_array($v)) {
|
if (is_assoc_array($v)) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user