You've already forked Atomcms-edit
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:
@@ -13,6 +13,7 @@ use App\Services\AutoDetectService;
|
|||||||
use App\Services\CatalogService;
|
use App\Services\CatalogService;
|
||||||
use App\Services\Diagnostics\DiagnosticRunner;
|
use App\Services\Diagnostics\DiagnosticRunner;
|
||||||
use App\Services\EmulatorUpdateService;
|
use App\Services\EmulatorUpdateService;
|
||||||
|
use App\Services\GitHubService;
|
||||||
use App\Services\RconService;
|
use App\Services\RconService;
|
||||||
use App\Services\SettingsService;
|
use App\Services\SettingsService;
|
||||||
use App\Services\UpdateHistoryService;
|
use App\Services\UpdateHistoryService;
|
||||||
@@ -715,7 +716,7 @@ final class Commandocentrum extends Page implements HasForms
|
|||||||
$githubUrl = $this->getSetting('emulator_github_url', '');
|
$githubUrl = $this->getSetting('emulator_github_url', '');
|
||||||
$currentBranch = $this->data['emulator_github_branch'] ?? 'main';
|
$currentBranch = $this->data['emulator_github_branch'] ?? 'main';
|
||||||
|
|
||||||
$branches = $this->fetchGitHubBranches($githubUrl);
|
$branches = app(GitHubService::class)->getBranches($githubUrl);
|
||||||
|
|
||||||
$html = '<option value="main">main</option>';
|
$html = '<option value="main">main</option>';
|
||||||
foreach ($branches as $branch) {
|
foreach ($branches as $branch) {
|
||||||
@@ -731,7 +732,7 @@ final class Commandocentrum extends Page implements HasForms
|
|||||||
$githubUrl = $this->getSetting('nitro_github_url', '');
|
$githubUrl = $this->getSetting('nitro_github_url', '');
|
||||||
$currentBranch = $this->data['nitro_github_branch'] ?? 'main';
|
$currentBranch = $this->data['nitro_github_branch'] ?? 'main';
|
||||||
|
|
||||||
$branches = $this->fetchGitHubBranches($githubUrl);
|
$branches = app(GitHubService::class)->getBranches($githubUrl);
|
||||||
|
|
||||||
$html = '<option value="main">main</option>';
|
$html = '<option value="main">main</option>';
|
||||||
foreach ($branches as $branch) {
|
foreach ($branches as $branch) {
|
||||||
@@ -742,68 +743,6 @@ final class Commandocentrum extends Page implements HasForms
|
|||||||
return $html;
|
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
|
private function renderAlertForm(): HtmlString
|
||||||
{
|
{
|
||||||
return new HtmlString(<<<'HTML'
|
return new HtmlString(<<<'HTML'
|
||||||
@@ -941,7 +880,7 @@ final class Commandocentrum extends Page implements HasForms
|
|||||||
$jarExists = $this->fileExists($jarPath);
|
$jarExists = $this->fileExists($jarPath);
|
||||||
|
|
||||||
$sourceCommit = $this->getGitCommit($sourcePath);
|
$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;
|
$canBuild = false;
|
||||||
$pomPath = '';
|
$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 {
|
$commit = app(GitHubService::class)->getLatestCommit($githubUrl, $branch);
|
||||||
if ($githubUrl === '' || $githubUrl === '0') {
|
|
||||||
return 'N/A';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to get latest commit using git ls-remote (doesn't hit rate limit)
|
return $commit ?? 'N/A';
|
||||||
$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';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function renderNitroSettings(): HtmlString
|
private function renderNitroSettings(): HtmlString
|
||||||
@@ -1153,8 +1052,8 @@ final class Commandocentrum extends Page implements HasForms
|
|||||||
$clientCommit = $this->getGitCommit($clientPath);
|
$clientCommit = $this->getGitCommit($clientPath);
|
||||||
$rendererCommit = $this->getGitCommit($rendererPath);
|
$rendererCommit = $this->getGitCommit($rendererPath);
|
||||||
|
|
||||||
$clientRemote = $clientGithubUrl !== '' && $clientGithubUrl !== '0' ? $this->getEmulatorRemoteVersion($clientGithubUrl) : 'N/A';
|
$clientRemote = $clientGithubUrl !== '' && $clientGithubUrl !== '0' ? $this->getRemoteCommit($clientGithubUrl, $this->getSetting('nitro_github_branch', 'main')) : 'N/A';
|
||||||
$rendererRemote = $rendererGithubUrl !== '' && $rendererGithubUrl !== '0' ? $this->getEmulatorRemoteVersion($rendererGithubUrl) : '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)
|
// Compare only first 7 characters (short hash)
|
||||||
$clientCommitShort = substr($clientCommit, 0, 7);
|
$clientCommitShort = substr($clientCommit, 0, 7);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace App\Services\Emulator;
|
namespace App\Services\Emulator;
|
||||||
|
|
||||||
|
use App\Services\GitHubService;
|
||||||
use App\Services\SettingsService;
|
use App\Services\SettingsService;
|
||||||
use Illuminate\Support\Facades\Process;
|
use Illuminate\Support\Facades\Process;
|
||||||
|
|
||||||
@@ -134,38 +135,18 @@ trait EmulatorConfiguration
|
|||||||
|
|
||||||
private function parseGitHubUrl(string $url): void
|
private function parseGitHubUrl(string $url): void
|
||||||
{
|
{
|
||||||
$parsed = $this->parseGithubRepoUrl($url);
|
$parsed = app(GitHubService::class)->parseUrl($url);
|
||||||
$this->githubRepo = $parsed['repo'];
|
$this->githubRepo = $parsed['repo'];
|
||||||
$this->githubBranch = $parsed['branch'];
|
$this->githubBranch = $parsed['branch'];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function parseSourceRepo(string $url): void
|
private function parseSourceRepo(string $url): void
|
||||||
{
|
{
|
||||||
$parsed = $this->parseGithubRepoUrl($url);
|
$parsed = app(GitHubService::class)->parseUrl($url);
|
||||||
$this->sourceRepo = $parsed['repo'];
|
$this->sourceRepo = $parsed['repo'];
|
||||||
$this->sourceBranch = $parsed['branch'];
|
$this->sourceBranch = $parsed['branch'];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function parseGithubRepoUrl(string $url): array
|
|
||||||
{
|
|
||||||
if ($url === '' || $url === '0') {
|
|
||||||
return ['repo' => null, 'branch' => 'main'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (preg_match('/github\.com\/([^\/]+)\/([^\/\?#]+)/', $url, $matches)) {
|
|
||||||
$repo = $matches[1] . '/' . $matches[2];
|
|
||||||
$branch = 'main';
|
|
||||||
|
|
||||||
if (preg_match('/\/tree\/([^\/]+)/', $url, $branchMatch)) {
|
|
||||||
$branch = $branchMatch[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
return ['repo' => $repo, 'branch' => $branch];
|
|
||||||
}
|
|
||||||
|
|
||||||
return ['repo' => null, 'branch' => 'main'];
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function extractVersionFromFilename(string $filename): string
|
protected function extractVersionFromFilename(string $filename): string
|
||||||
{
|
{
|
||||||
$filename = basename($filename, '.jar');
|
$filename = basename($filename, '.jar');
|
||||||
|
|||||||
Executable
+151
@@ -0,0 +1,151 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Http;
|
||||||
|
use Illuminate\Support\Facades\Process;
|
||||||
|
|
||||||
|
class GitHubService
|
||||||
|
{
|
||||||
|
public function parseUrl(string $url): array
|
||||||
|
{
|
||||||
|
if ($url === '' || $url === '0') {
|
||||||
|
return ['repo' => null, 'branch' => 'main'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match('/github\.com\/([^\/]+)\/([^\/\?#]+)/', $url, $matches)) {
|
||||||
|
$repo = $matches[1] . '/' . $matches[2];
|
||||||
|
$branch = 'main';
|
||||||
|
|
||||||
|
if (preg_match('/\/tree\/([^\/]+)/', $url, $branchMatch)) {
|
||||||
|
$branch = $branchMatch[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['repo' => $repo, 'branch' => $branch];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['repo' => null, 'branch' => 'main'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function extractRepo(string $url): string
|
||||||
|
{
|
||||||
|
$url = trim($url, '/');
|
||||||
|
|
||||||
|
if (str_contains($url, 'github.com/')) {
|
||||||
|
$parts = explode('github.com/', $url);
|
||||||
|
if (isset($parts[1])) {
|
||||||
|
$path = trim($parts[1], '/');
|
||||||
|
$path = explode('/tree/', $path)[0];
|
||||||
|
$path = explode('/blob/', $path)[0];
|
||||||
|
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBranches(string $githubUrl): array
|
||||||
|
{
|
||||||
|
if ($githubUrl === '' || $githubUrl === '0' || ! str_contains($githubUrl, 'github.com')) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$repo = $this->extractRepo($githubUrl);
|
||||||
|
$gitUrl = "https://github.com/{$repo}.git";
|
||||||
|
|
||||||
|
$result = Process::timeout(30)->run('git ls-remote --heads ' . escapeshellarg($gitUrl) . ' 2>/dev/null');
|
||||||
|
if ($result->successful() && trim($result->output())) {
|
||||||
|
$branches = [];
|
||||||
|
foreach (explode("\n", trim($result->output())) as $line) {
|
||||||
|
$parts = explode("\t", $line);
|
||||||
|
if (isset($parts[1]) && str_starts_with($parts[1], 'refs/heads/')) {
|
||||||
|
$branches[] = str_replace('refs/heads/', '', $parts[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $branches;
|
||||||
|
}
|
||||||
|
|
||||||
|
$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 [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLatestCommit(string $githubUrl, string $branch = 'main'): ?string
|
||||||
|
{
|
||||||
|
if ($githubUrl === '' || $githubUrl === '0') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$repo = $this->extractRepo($githubUrl);
|
||||||
|
$gitUrl = "https://github.com/{$repo}.git";
|
||||||
|
|
||||||
|
$result = Process::timeout(30)->run('git ls-remote ' . escapeshellarg($gitUrl) . ' ' . escapeshellarg($branch) . ' 2>/dev/null');
|
||||||
|
if ($result->successful() && trim($result->output())) {
|
||||||
|
$parts = explode("\t", trim($result->output()));
|
||||||
|
if ($parts[0] !== '' && $parts[0] !== '0') {
|
||||||
|
return substr($parts[0], 0, 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$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($data[0]['sha'], 0, 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (\Exception) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLatestRelease(string $githubUrl): ?string
|
||||||
|
{
|
||||||
|
if ($githubUrl === '' || $githubUrl === '0') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$repo = $this->extractRepo($githubUrl);
|
||||||
|
|
||||||
|
$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'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (\Exception) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasUpdates(string $githubUrl, string $localCommit, string $branch = 'main'): bool
|
||||||
|
{
|
||||||
|
$remoteCommit = $this->getLatestCommit($githubUrl, $branch);
|
||||||
|
|
||||||
|
if ($remoteCommit === null || $localCommit === 'N/A') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $localCommit !== $remoteCommit;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user