Skip to content

Commit

Permalink
Merge pull request #34 from huangzhhui/pkgs-remote-definition
Browse files Browse the repository at this point in the history
Pkgs remote definition
  • Loading branch information
huangzhhui authored Oct 4, 2022
2 parents 3a46f1c + 81cd4c3 commit c1dcb55
Show file tree
Hide file tree
Showing 13 changed files with 528 additions and 85 deletions.
75 changes: 75 additions & 0 deletions pkgs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{
"php-cs-fixer": {
"repo": "FriendsOfPHP/PHP-CS-Fixer",
"bin": "php-cs-fixer.phar"
},
"phpunit": {
"url": "https://phar.phpunit.de/phpunit-${{version}}.phar",
"latest": "9",
"bin": "phpunit.phar"
},
"php": {
"repo": "dixyes/lwmbs",
"jobs": {
"Darwin.x86_64": "2969003447",
"Darwin.arm64": "2969003447",
"Linux.x86_64": "2961452571",
"Linux.aarch64": "2961452571"
},
"job_artifact_match_rule": {
"Darwin.x86_64": "${{prefix}}_${{php-version}}_${{arch}}",
"Darwin.arm64": "${{prefix}}_${{php-version}}_${{arch}}",
"Linux.x86_64": "${{prefix}}_static_${{php-version}}_musl_${{arch}}",
"Linux.aarch64": "${{prefix}}_static_${{php-version}}_musl_${{arch}}"
},
"latest": "8.1",
"versions": ["8.1", "8.0"]
},
"micro": {
"repo": "dixyes/lwmbs",
"jobs": {
"Darwin.x86_64": "2969003447",
"Darwin.arm64": "2969003447",
"Linux.x86_64": "2961452571",
"Linux.aarch64": "2961452571"
},
"job_artifact_match_rule": {
"Darwin.x86_64": "${{prefix}}_${{php-version}}_${{arch}}",
"Darwin.arm64": "${{prefix}}_${{php-version}}_${{arch}}",
"Linux.x86_64": "${{prefix}}_static_${{php-version}}_musl_${{arch}}",
"Linux.aarch64": "${{prefix}}_static_${{php-version}}_musl_${{arch}}"
},
"latest": "8.1",
"versions": ["8.1", "8.0"]
},
"box": {
"repo": "hyperf/box",
"bin": "box.phar",
"release_asset_match_rule": {
"Darwin.x86_64": "box_x86_64_macos",
"Darwin.arm64": "box_arm64_macos",
"Linux.x86_64": "box_x86_64_linux",
"Linux.aarch64": "box_aarch64_linux"
}
},
"composer": {
"repo": "composer/composer",
"bin": "composer.phar",
"sources": {
"github.com": {
"type": "github",
"url": "github.com"
},
"getcomposer.org": {
"type": "url",
"url": "https://getcomposer.org/download/${{version}}/${{bin}}"
},
"default": {
"type": "url",
"url": "https://getcomposer.org/download/${{version}}/${{bin}}"
}
},
"latest": "latest",
"latest_fetch_type": "github"
}
}
22 changes: 20 additions & 2 deletions src/app/DownloadHandler/AbstractDownloadHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
use App\Config;
use App\Exception\NotSupportVersionsException;
use App\GithubClient;
use App\PkgDefinition\Definition;
use App\PkgDefinitionManager;
use GuzzleHttp\Client;
use GuzzleHttp\TransferStats;
use Hyperf\Context\Context;
Expand All @@ -39,16 +41,19 @@ abstract class AbstractDownloadHandler
#[Inject]
protected Config $config;

#[Inject]
protected PkgDefinitionManager $pkgsDefinitionManager;

protected string $runtimePath;

public function __construct()
{
$this->runtimePath = $this->config->getConfig('path.runtime', getenv('HOME') . '/.box');
}

abstract public function handle(string $repo, string $version, array $options = []): ?SplFileInfo;
abstract public function handle(string $pkgName, string $version, array $options = []): ?SplFileInfo;

abstract public function versions(string $repo, array $options = []): array;
abstract public function versions(string $pkgName, array $options = []): array;

protected function fetchDownloadUrlFromGithubRelease(string $assetName, string $fullRepo, string $version): ?string
{
Expand Down Expand Up @@ -161,4 +166,17 @@ protected function byteToKb(int $byte): int
{
return (int)ceil($byte / 1024);
}

protected function getDefinition(string $pkgName): ?Definition
{
return $this->pkgsDefinitionManager->getDefinition($pkgName);
}

protected function replaces(string $subject, array $replaces): string
{
foreach ($replaces as $search => $replace) {
$subject = str_replace('${{' . $search . '}}', $replace, $subject);
}
return $subject;
}
}
4 changes: 2 additions & 2 deletions src/app/DownloadHandler/BoxHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ public function __construct()
$this->binName = $this->getAssetName();
}

public function handle(string $repo, string $version, array $options = []): ?SplFileInfo
public function handle(string $pkgName, string $version, array $options = []): ?SplFileInfo
{
$url = $this->fetchDownloadUrlFromGithubRelease($this->getAssetName(), $this->fullRepo, $version);
$savePath = Phar::running(false) ?: $this->runtimePath . '/';

return $this->download($url, $savePath, 0755, $this->binName);
}

public function versions(string $repo, array $options = []): array
public function versions(string $pkgName, array $options = []): array
{
return $this->fetchVersionsFromGithubRelease($this->fullRepo, $this->getAssetName());
}
Expand Down
36 changes: 21 additions & 15 deletions src/app/DownloadHandler/ComposerHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,52 +13,58 @@
namespace App\DownloadHandler;

use App\Exception\NotSupportVersionsException;
use App\PkgDefinition\Definition;
use SplFileInfo;

class ComposerHandler extends AbstractDownloadHandler
{
protected string $fullRepo = 'composer/composer';

protected string $binName = 'composer.phar';

protected string $getComposerOrgBaseUrl = 'getcomposer.org';

protected string $githubBaseUrl = 'github.com';

public function handle(string $repo, string $version, array $options = []): ?SplFileInfo
public function handle(string $pkgName, string $version, array $options = []): ?SplFileInfo
{
$definition = $this->getDefinition($pkgName);
if (! isset($options['source'])) {
$options['source'] = $this->getComposerOrgBaseUrl;
$options['source'] = $definition->getSources()->getSource('default')?->getUrl();
}
$url = match ($options['source']) {
$this->githubBaseUrl => $this->fetchDownloadUrlFromGithubRelease($this->binName, $this->fullRepo, $version),
default => $this->fetchDownloadUrlFromGetComposerOrg($version),
$this->githubBaseUrl => $this->fetchDownloadUrlFromGithubRelease($definition->getBin(), $definition->getRepo(), $version),
default => $this->fetchDownloadUrlFromGetComposerOrg($definition, $version),
};
return $this->download($url, $this->runtimePath . '/', 0755);
}

public function versions(string $repo, array $options = []): array
public function versions(string $pkgName, array $options = []): array
{
$definition = $this->getDefinition($pkgName);
if (! isset($options['source'])) {
$options['source'] = $this->getComposerOrgBaseUrl;
$options['source'] = $definition->getSources()->getSource('default')?->getUrl();
}
return match ($options['source']) {
$this->githubBaseUrl => $this->fetchVersionsFromGithubRelease($this->fullRepo),
default => throw new NotSupportVersionsException($repo),
$this->githubBaseUrl => $this->fetchVersionsFromGithubRelease($definition->getRepo()),
default => throw new NotSupportVersionsException($pkgName),
};
}

protected function fetchDownloadUrlFromGetComposerOrg(string $version): string
protected function fetchDownloadUrlFromGetComposerOrg(Definition $definition, string $version): string
{
if ($version === 'latest') {
$release = $this->githubClient->getRelease($this->fullRepo, $version);
$release = $this->githubClient->getRelease($definition->getRepo(), $version);
if (! isset($release['tag_name'])) {
throw new \RuntimeException('Cannot match the specified version from github releases.');
}
$specifiedVersion = $release['tag_name'];
} else {
$specifiedVersion = $version;
}
return 'https://' . $this->getComposerOrgBaseUrl . '/download/' . $specifiedVersion . '/' . $this->binName;
$url = $definition->getSources()?->getSource('getcomposer.org')?->getUrl();
if (! $url) {
throw new \RuntimeException('Cannot parse the download url by getcomposer.org.');
}
return $this->replaces($url, [
'version' => $specifiedVersion,
'bin' => $definition->getBin(),
]);
}
}
44 changes: 16 additions & 28 deletions src/app/DownloadHandler/DefaultHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,46 +17,34 @@

class DefaultHandler extends AbstractDownloadHandler
{
protected array $definitions = [
'php-cs-fixer' => [
'repo' => 'FriendsOfPHP/PHP-CS-Fixer',
'bin' => 'php-cs-fixer.phar',
],
'phpunit' => [
'url' => 'https://phar.phpunit.de/phpunit-${{version}}.phar',
'latest' => '9',
'bin' => 'phpunit.phar',
],
];

public function handle(string $repo, string $version, array $options = []): ?SplFileInfo
public function handle(string $pkgName, string $version, array $options = []): ?SplFileInfo
{
if (! isset($this->definitions[$repo])) {
$definition = $this->getDefinition($pkgName);
if (! $definition) {
throw new \RuntimeException('The package not found');
}
$definition = $this->definitions[$repo];
if (isset($definition['repo'])) {
$url = $this->fetchDownloadUrlFromGithubRelease($definition['bin'], $definition['repo'], $version);
} elseif (isset($definition['url'])) {
if ($version === 'latest' && isset($definition['latest'])) {
$version = $definition['latest'];
if ($definition->getRepo()) {
$url = $this->fetchDownloadUrlFromGithubRelease($definition->getBin(), $definition->getRepo(), $version);
} elseif ($definition->getUrl()) {
if ($version === 'latest' && $definition->getLatest()) {
$version = $definition->getLatest();
}
$url = str_replace('${{version}}', $version, $definition['url']);
$url = str_replace('${{version}}', $version, $definition->getUrl());
} else {
throw new \RuntimeException('The definition of package is invalid');
}
return $this->download($url, $this->runtimePath . '/', 0755, $definition['bin']);
return $this->download($url, $this->runtimePath . '/', 0755, $definition->getBin());
}

public function versions(string $repo, array $options = []): array
public function versions(string $pkgName, array $options = []): array
{
if (! isset($this->definitions[$repo])) {
$definition = $this->getDefinition($pkgName);
if (! $definition) {
throw new \RuntimeException('The package not found');
}
$definition = $this->definitions[$repo];
if (! isset($definition['repo'])) {
throw new NotSupportVersionsException($repo);
if (! $definition->getRepo()) {
throw new NotSupportVersionsException($pkgName);
}
return $this->fetchVersionsFromGithubRelease($definition['repo'], $definition['bin']);
return $this->fetchVersionsFromGithubRelease($definition->getRepo(), $definition->getBin());
}
}
4 changes: 2 additions & 2 deletions src/app/DownloadHandler/MicroHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ class MicroHandler extends PhpHandler
#[Inject]
protected Client $httpClient;

public function handle(string $repo, string $version, array $options = []): ?SplFileInfo
public function handle(string $pkgName, string $version, array $options = []): ?SplFileInfo
{
$version = $this->prehandleVersion($version);
try {
$response = $this->getArtifact($version, 'micro');
$response = $this->getArtifact($this->getDefinition($pkgName), $version, 'micro');
if ($response->getStatusCode() !== 302 || ! $response->getHeaderLine('Location')) {
throw new \RuntimeException('Download failed, cannot retrieve the download url from artifact.');
}
Expand Down
46 changes: 10 additions & 36 deletions src/app/DownloadHandler/PhpHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

namespace App\DownloadHandler;

use App\Exception\NotSupportVersionsException;
use App\PkgDefinition\Definition;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\Di\Annotation\Inject;
Expand All @@ -24,27 +24,11 @@ class PhpHandler extends AbstractDownloadHandler
#[Inject]
protected Client $httpClient;

protected string $repo = 'dixyes/lwmbs';

protected array $jobs
= [
'Darwin.x86_64' => '2969003447',
'Darwin.arm64' => '2969003447',
'Linux.x86_64' => '2961452571',
'Linux.aarch64' => '2961452571',
];

protected array $matchRules
= [
'Darwin' => '${{prefix}}_${{php-version}}_${{arch}}',
'Linux' => '${{prefix}}_static_${{php-version}}_musl_${{arch}}',
];

public function handle(string $repo, string $version, array $options = []): ?SplFileInfo
public function handle(string $pkgName, string $version, array $options = []): ?SplFileInfo
{
$version = $this->prehandleVersion($version);
try {
$response = $this->getArtifact($version, 'cli');
$response = $this->getArtifact($this->getDefinition($pkgName), $version, 'cli');
if ($response->getStatusCode() !== 302 || ! $response->getHeaderLine('Location')) {
throw new \RuntimeException('Download failed, cannot retrieve the download url from artifact.');
}
Expand Down Expand Up @@ -98,7 +82,7 @@ protected function prehandleVersion(string $version): string
/**
* @throws \GuzzleHttp\Exception\GuzzleException
*/
protected function getArtifact(string $version, string $prefix): ResponseInterface
protected function getArtifact(Definition $definition, string $version, string $prefix): ResponseInterface
{
$githubToken = $this->githubClient->getGithubToken();
if (! $githubToken) {
Expand All @@ -107,8 +91,8 @@ protected function getArtifact(string $version, string $prefix): ResponseInterfa
$os = PHP_OS_FAMILY;
$arch = php_uname('m');
$key = $os . '.' . $arch;
$response = $this->githubClient->getActionsArtifacts($this->repo, $this->jobs[$key]);
$searchKey = $this->buildSearchKey($os, $prefix, $version, $arch);
$response = $this->githubClient->getActionsArtifacts($definition->getRepo(), $definition->getJobs()?->getJob($key)?->getJobId());
$searchKey = $this->buildSearchKey($definition, $key, $prefix, $version, $arch);
$artifact = $this->matchArtifact($response['artifacts'] ?? [], $searchKey);
if (! isset($artifact['archive_download_url'])) {
throw new \RuntimeException('Does not match any artifact.');
Expand All @@ -122,33 +106,23 @@ protected function getArtifact(string $version, string $prefix): ResponseInterfa
]);
}

protected function buildSearchKey(string $os, string $prefix, string $version, string $arch): string
protected function buildSearchKey(Definition $definition, string $key, string $prefix, string $version, string $arch): string
{
return $this->replaces($this->matchRules[$os], [
return $this->replaces($definition->getJobArtifactMatchRule()[$key], [
'prefix' => $prefix,
'php-version' => $version,
'arch' => $arch,
]);
}

protected function replaces(string $subject, array $replaces): string
{
foreach ($replaces as $search => $replace) {
$subject = str_replace('${{' . $search . '}}', $replace, $subject);
}
return $subject;
}

protected function isBinExists(string $string): bool
{
$result = shell_exec(sprintf("which %s", escapeshellarg($string)));
return ! empty($result) && ! str_contains($result, 'not found');
}

public function versions(string $repo, array $options = []): array
public function versions(string $pkgName, array $options = []): array
{
return [
'8.1', '8.0'
];
return $this->getDefinition($pkgName)->getVersions();
}
}
Loading

0 comments on commit c1dcb55

Please sign in to comment.