mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-03-17 20:34:51 +08:00
Add support for custom source check-update callbacks in artifacts
This commit is contained in:
parent
0a07f6b27c
commit
28f4a5c523
@ -27,6 +27,9 @@ class Artifact
|
||||
/** @var null|callable Bind custom source fetcher callback */
|
||||
protected mixed $custom_source_callback = null;
|
||||
|
||||
/** @var null|callable Bind custom source check-update callback */
|
||||
protected mixed $custom_source_check_update_callback = null;
|
||||
|
||||
/** @var array<string, callable> Bind custom binary fetcher callbacks */
|
||||
protected mixed $custom_binary_callbacks = [];
|
||||
|
||||
@ -408,6 +411,19 @@ class Artifact
|
||||
return $this->custom_source_callback ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set custom source check-update callback.
|
||||
*/
|
||||
public function setCustomSourceCheckUpdateCallback(callable $callback): void
|
||||
{
|
||||
$this->custom_source_check_update_callback = $callback;
|
||||
}
|
||||
|
||||
public function getCustomSourceCheckUpdateCallback(): ?callable
|
||||
{
|
||||
return $this->custom_source_check_update_callback ?? null;
|
||||
}
|
||||
|
||||
public function getCustomBinaryCallback(): ?callable
|
||||
{
|
||||
$current_platform = SystemTarget::getCurrentPlatformString();
|
||||
|
||||
@ -332,17 +332,14 @@ class ArtifactDownloader
|
||||
throw new WrongUsageException("Artifact '{$artifact_name}' not found, please check the name.");
|
||||
}
|
||||
if ($bare) {
|
||||
$config = $artifact->getDownloadConfig('source');
|
||||
if (!is_array($config)) {
|
||||
throw new WrongUsageException("Artifact '{$artifact_name}' has no source config for bare update check.");
|
||||
[$first, $second] = $prefer_source
|
||||
? [fn () => $this->probeSourceCheckUpdate($artifact, $artifact_name), fn () => $this->probeBinaryCheckUpdate($artifact, $artifact_name)]
|
||||
: [fn () => $this->probeBinaryCheckUpdate($artifact, $artifact_name), fn () => $this->probeSourceCheckUpdate($artifact, $artifact_name)];
|
||||
$result = $first() ?? $second();
|
||||
if ($result !== null) {
|
||||
return $result;
|
||||
}
|
||||
$cls = $this->downloaders[$config['type']] ?? null;
|
||||
if (!is_a($cls, CheckUpdateInterface::class, true)) {
|
||||
throw new WrongUsageException("Artifact '{$artifact_name}' downloader does not support update checking.");
|
||||
}
|
||||
/** @var CheckUpdateInterface $downloader */
|
||||
$downloader = new $cls();
|
||||
return $downloader->checkUpdate($artifact_name, $config, null, $this);
|
||||
throw new WrongUsageException("Artifact '{$artifact_name}' downloader does not support update checking.");
|
||||
}
|
||||
$cache = ApplicationContext::get(ArtifactCache::class);
|
||||
if ($prefer_source) {
|
||||
@ -358,7 +355,15 @@ class ArtifactDownloader
|
||||
/** @var CheckUpdateInterface $downloader */
|
||||
$downloader = new $cls();
|
||||
return $downloader->checkUpdate($artifact_name, $info['config'], $info['version'], $this);
|
||||
} // custom binary: delegate to registered check-update callback
|
||||
}
|
||||
// custom source: delegate to registered check-update callback
|
||||
if (($info['lock_type'] ?? null) === 'source' && ($callback = $artifact->getCustomSourceCheckUpdateCallback()) !== null) {
|
||||
return ApplicationContext::invoke($callback, [
|
||||
ArtifactDownloader::class => $this,
|
||||
'old_version' => $info['version'],
|
||||
]);
|
||||
}
|
||||
// custom binary: delegate to registered check-update callback
|
||||
if (($callback = $artifact->getCustomBinaryCheckUpdateCallback()) !== null) {
|
||||
return ApplicationContext::invoke($callback, [
|
||||
ArtifactDownloader::class => $this,
|
||||
@ -383,6 +388,50 @@ class ArtifactDownloader
|
||||
return $this->options[$name] ?? $default;
|
||||
}
|
||||
|
||||
private function probeSourceCheckUpdate(Artifact $artifact, string $artifact_name): ?CheckUpdateResult
|
||||
{
|
||||
if (($callback = $artifact->getCustomSourceCheckUpdateCallback()) !== null) {
|
||||
return ApplicationContext::invoke($callback, [
|
||||
ArtifactDownloader::class => $this,
|
||||
'old_version' => null,
|
||||
]);
|
||||
}
|
||||
$config = $artifact->getDownloadConfig('source');
|
||||
if (!is_array($config)) {
|
||||
return null;
|
||||
}
|
||||
$cls = $this->downloaders[$config['type']] ?? null;
|
||||
if (!is_a($cls, CheckUpdateInterface::class, true)) {
|
||||
return null;
|
||||
}
|
||||
/** @var CheckUpdateInterface $dl */
|
||||
$dl = new $cls();
|
||||
return $dl->checkUpdate($artifact_name, $config, null, $this);
|
||||
}
|
||||
|
||||
private function probeBinaryCheckUpdate(Artifact $artifact, string $artifact_name): ?CheckUpdateResult
|
||||
{
|
||||
// custom binary callback takes precedence over config-based binary
|
||||
if (($callback = $artifact->getCustomBinaryCheckUpdateCallback()) !== null) {
|
||||
return ApplicationContext::invoke($callback, [
|
||||
ArtifactDownloader::class => $this,
|
||||
'old_version' => null,
|
||||
]);
|
||||
}
|
||||
$binary_config = $artifact->getDownloadConfig('binary');
|
||||
$platform_config = is_array($binary_config) ? ($binary_config[SystemTarget::getCurrentPlatformString()] ?? null) : null;
|
||||
if (!is_array($platform_config)) {
|
||||
return null;
|
||||
}
|
||||
$cls = $this->downloaders[$platform_config['type']] ?? null;
|
||||
if (!is_a($cls, CheckUpdateInterface::class, true)) {
|
||||
return null;
|
||||
}
|
||||
/** @var CheckUpdateInterface $dl */
|
||||
$dl = new $cls();
|
||||
return $dl->checkUpdate($artifact_name, $platform_config, null, $this);
|
||||
}
|
||||
|
||||
private function downloadWithType(Artifact $artifact, int $current, int $total, bool $parallel = false, bool $interactive = true): int
|
||||
{
|
||||
$queue = $this->generateQueue($artifact);
|
||||
|
||||
11
src/StaticPHP/Attribute/Artifact/CustomSourceCheckUpdate.php
Normal file
11
src/StaticPHP/Attribute/Artifact/CustomSourceCheckUpdate.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace StaticPHP\Attribute\Artifact;
|
||||
|
||||
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||
class CustomSourceCheckUpdate
|
||||
{
|
||||
public function __construct(public string $artifact_name) {}
|
||||
}
|
||||
@ -11,6 +11,7 @@ use StaticPHP\Attribute\Artifact\BinaryExtract;
|
||||
use StaticPHP\Attribute\Artifact\CustomBinary;
|
||||
use StaticPHP\Attribute\Artifact\CustomBinaryCheckUpdate;
|
||||
use StaticPHP\Attribute\Artifact\CustomSource;
|
||||
use StaticPHP\Attribute\Artifact\CustomSourceCheckUpdate;
|
||||
use StaticPHP\Attribute\Artifact\SourceExtract;
|
||||
use StaticPHP\Config\ArtifactConfig;
|
||||
use StaticPHP\Exception\ValidationException;
|
||||
@ -62,6 +63,7 @@ class ArtifactLoader
|
||||
|
||||
foreach ($ref->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
|
||||
self::processCustomSourceAttribute($ref, $method, $class_instance);
|
||||
self::processCustomSourceCheckUpdateAttribute($ref, $method, $class_instance);
|
||||
self::processCustomBinaryAttribute($ref, $method, $class_instance);
|
||||
self::processCustomBinaryCheckUpdateAttribute($ref, $method, $class_instance);
|
||||
self::processSourceExtractAttribute($ref, $method, $class_instance);
|
||||
@ -100,6 +102,24 @@ class ArtifactLoader
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process #[CustomSourceCheckUpdate] attribute.
|
||||
*/
|
||||
private static function processCustomSourceCheckUpdateAttribute(\ReflectionClass $ref, \ReflectionMethod $method, object $class_instance): void
|
||||
{
|
||||
$attributes = $method->getAttributes(CustomSourceCheckUpdate::class);
|
||||
foreach ($attributes as $attribute) {
|
||||
/** @var CustomSourceCheckUpdate $instance */
|
||||
$instance = $attribute->newInstance();
|
||||
$artifact_name = $instance->artifact_name;
|
||||
if (isset(self::$artifacts[$artifact_name])) {
|
||||
self::$artifacts[$artifact_name]->setCustomSourceCheckUpdateCallback([$class_instance, $method->getName()]);
|
||||
} else {
|
||||
throw new ValidationException("Artifact '{$artifact_name}' not found for #[CustomSourceCheckUpdate] on '{$ref->getName()}::{$method->getName()}'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process #[CustomBinary] attribute.
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user