refactor: centralize GitHub logic into GitHubService

- Create GitHubService with parseUrl, extractRepo, getBranches, getLatestCommit, getLatestRelease, hasUpdates
- Replace duplicated GitHub parsing in EmulatorConfiguration with GitHubService
- Replace fetchGitHubBranches, extractGitHubRepo, getEmulatorRemoteVersion in Commandocentrum
- Reduce code duplication across services and controllers
This commit is contained in:
root
2026-05-19 21:07:16 +02:00
parent cbe189fd96
commit 0bb35d6c8a
3 changed files with 163 additions and 132 deletions
@@ -13,6 +13,7 @@ use App\Services\AutoDetectService;
use App\Services\CatalogService;
use App\Services\Diagnostics\DiagnosticRunner;
use App\Services\EmulatorUpdateService;
use App\Services\GitHubService;
use App\Services\RconService;
use App\Services\SettingsService;
use App\Services\UpdateHistoryService;
@@ -715,7 +716,7 @@ final class Commandocentrum extends Page implements HasForms
$githubUrl = $this->getSetting('emulator_github_url', '');
$currentBranch = $this->data['emulator_github_branch'] ?? 'main';
$branches = $this->fetchGitHubBranches($githubUrl);
$branches = app(GitHubService::class)->getBranches($githubUrl);
$html = '<option value="main">main</option>';
foreach ($branches as $branch) {
@@ -731,7 +732,7 @@ final class Commandocentrum extends Page implements HasForms
$githubUrl = $this->getSetting('nitro_github_url', '');
$currentBranch = $this->data['nitro_github_branch'] ?? 'main';
$branches = $this->fetchGitHubBranches($githubUrl);
$branches = app(GitHubService::class)->getBranches($githubUrl);
$html = '<option value="main">main</option>';
foreach ($branches as $branch) {
@@ -742,68 +743,6 @@ final class Commandocentrum extends Page implements HasForms
return $html;
}
private function fetchGitHubBranches(string $githubUrl): array
{
if ($githubUrl === '' || $githubUrl === '0' || ! str_contains($githubUrl, 'github.com')) {
return [];
}
try {
$repo = $this->extractGitHubRepo($githubUrl);
$gitUrl = "https://github.com/{$repo}.git";
// Use git ls-remote to get all branches (doesn't hit rate limit)
$result = $this->runCommand('git ls-remote --heads ' . escapeshellarg($gitUrl) . ' 2>/dev/null', 30);
if ($result) {
$branches = [];
foreach (explode("\n", trim($result)) as $line) {
$parts = explode("\t", $line);
if (isset($parts[1]) && ($parts[1] !== '' && $parts[1] !== '0') && str_starts_with($parts[1], 'refs/heads/')) {
$branches[] = str_replace('refs/heads/', '', $parts[1]);
}
}
return $branches;
}
// Fallback to GitHub API
$response = Http::timeout(10)->get("https://api.github.com/repos/{$repo}/branches");
if ($response->successful()) {
$data = $response->json();
return array_column($data, 'name');
}
} catch (Exception) {
// Ignore
}
return [];
}
private function extractGitHubRepo(string $url): string
{
$url = trim($url, '/');
// Handle GitHub URLs with /tree/ or /blob/
if (str_contains($url, 'github.com/')) {
$parts = explode('github.com/', $url);
if (isset($parts[1])) {
$path = trim($parts[1], '/');
// Remove /tree/... or /blob/...
if (str_contains($path, '/tree/')) {
$path = explode('/tree/', $path)[0];
}
if (str_contains($path, '/blob/')) {
$path = explode('/blob/', $path)[0];
}
return $path;
}
}
return $url;
}
private function renderAlertForm(): HtmlString
{
return new HtmlString(<<<'HTML'
@@ -941,7 +880,7 @@ final class Commandocentrum extends Page implements HasForms
$jarExists = $this->fileExists($jarPath);
$sourceCommit = $this->getGitCommit($sourcePath);
$remoteVersion = $githubUrl !== '' && $githubUrl !== '0' ? $this->getEmulatorRemoteVersion($githubUrl) : 'N/A';
$remoteVersion = $githubUrl !== '' && $githubUrl !== '0' ? $this->getRemoteCommit($githubUrl, $this->getSetting('emulator_github_branch', 'main')) : 'N/A';
$canBuild = false;
$pomPath = '';
@@ -1028,51 +967,11 @@ final class Commandocentrum extends Page implements HasForms
}
}
private function getEmulatorRemoteVersion(string $githubUrl): string
private function getRemoteCommit(string $githubUrl, string $branch = 'main'): string
{
try {
if ($githubUrl === '' || $githubUrl === '0') {
return 'N/A';
}
$commit = app(GitHubService::class)->getLatestCommit($githubUrl, $branch);
// Try to get latest commit using git ls-remote (doesn't hit rate limit)
$repo = $this->extractGitHubRepo($githubUrl);
// Use nitro branch if it's a nitro repo, otherwise use emulator branch
$isNitroRepo = str_contains($githubUrl, 'Nitro');
$branch = $isNitroRepo
? $this->getSetting('nitro_github_branch', 'main')
: $this->getSetting('emulator_github_branch', 'main');
$gitUrl = "https://github.com/{$repo}.git";
$result = $this->runCommand('git ls-remote ' . escapeshellarg($gitUrl) . ' ' . escapeshellarg($branch) . ' 2>/dev/null', 30);
if ($result) {
$parts = explode("\t", trim($result));
if ($parts[0] !== '' && $parts[0] !== '0') {
return substr($parts[0], 0, 7);
}
}
// Fallback to GitHub API
$response = Http::timeout(10)->get("https://api.github.com/repos/{$repo}/releases/latest");
if ($response->successful()) {
$data = $response->json();
if (! empty($data['tag_name'])) {
return $data['tag_name'];
}
}
$response = Http::timeout(10)->get("https://api.github.com/repos/{$repo}/commits?per_page=1");
if ($response->successful()) {
$data = $response->json();
if (! empty($data[0]['sha'])) {
return substr((string) $data[0]['sha'], 0, 7);
}
}
} catch (Exception) {
// Ignore
}
return 'N/A';
return $commit ?? 'N/A';
}
private function renderNitroSettings(): HtmlString
@@ -1153,8 +1052,8 @@ final class Commandocentrum extends Page implements HasForms
$clientCommit = $this->getGitCommit($clientPath);
$rendererCommit = $this->getGitCommit($rendererPath);
$clientRemote = $clientGithubUrl !== '' && $clientGithubUrl !== '0' ? $this->getEmulatorRemoteVersion($clientGithubUrl) : 'N/A';
$rendererRemote = $rendererGithubUrl !== '' && $rendererGithubUrl !== '0' ? $this->getEmulatorRemoteVersion($rendererGithubUrl) : 'N/A';
$clientRemote = $clientGithubUrl !== '' && $clientGithubUrl !== '0' ? $this->getRemoteCommit($clientGithubUrl, $this->getSetting('nitro_github_branch', 'main')) : 'N/A';
$rendererRemote = $rendererGithubUrl !== '' && $rendererGithubUrl !== '0' ? $this->getRemoteCommit($rendererGithubUrl, $this->getSetting('nitro_renderer_github_branch', 'main')) : 'N/A';
// Compare only first 7 characters (short hash)
$clientCommitShort = substr($clientCommit, 0, 7);