Files
Home/github-client.js
2026-08-14 14:02:51 -07:00

179 lines
5.3 KiB
JavaScript

const { execSync, spawnSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const REPOS = {
frontend: { branch: 'main' },
player: { branch: 'main' },
'stream-api': { branch: 'main' },
'live-api-streampk': { branch: 'main' },
'auth-proxy': { branch: 'main' }
};
const GITLAB_GROUP = 'vyla-entertainment';
class GitlabClient {
constructor(appDataPath, credentialManager) {
this.appDataPath = appDataPath;
this.credentialManager = credentialManager;
}
getToken() {
return this.credentialManager.getCredential('gitlab', 'TOKEN') || null;
}
setToken(token) {
this.credentialManager.setCredential('gitlab', 'TOKEN', token);
}
hasToken() {
return !!this.getToken();
}
buildRepoUrl(repoName) {
const token = this.getToken();
if (token) {
return `https://oauth2:${token}@gitlab.com/${GITLAB_GROUP}/${repoName}.git`;
}
return `https://gitlab.com/${GITLAB_GROUP}/${repoName}.git`;
}
repoDir(repoName) {
return path.join(this.appDataPath, repoName);
}
isRepoCloned(repoName) {
const gitDir = path.join(this.repoDir(repoName), '.git');
return fs.existsSync(gitDir);
}
allReposCloned() {
return Object.keys(REPOS).every((name) => this.isRepoCloned(name));
}
cloneRepo(repoName, onLog) {
const { branch } = REPOS[repoName];
const targetDir = this.repoDir(repoName);
const url = this.buildRepoUrl(repoName);
if (fs.existsSync(targetDir)) {
fs.rmSync(targetDir, { recursive: true, force: true });
}
if (onLog) onLog(`Cloning ${repoName}...`);
const result = spawnSync('git', ['clone', '--depth', '1', '--branch', branch, url, targetDir], {
stdio: 'pipe',
env: { ...process.env, GIT_TERMINAL_PROMPT: '0' }
});
if (result.status !== 0) {
const stderr = result.stderr ? result.stderr.toString() : 'unknown error';
throw new Error(`Failed to clone ${repoName}: ${stderr}`);
}
}
cloneAll(onLog) {
for (const repoName of Object.keys(REPOS)) {
this.cloneRepo(repoName, onLog);
}
}
installDependencies(repoName, onLog) {
const repoDir = this.repoDir(repoName);
const pkgJsonPath = path.join(repoDir, 'package.json');
if (!fs.existsSync(pkgJsonPath)) {
return;
}
if (onLog) onLog(`Installing dependencies for ${repoName}...`);
const result = spawnSync('npm', ['install', '--omit=dev'], {
cwd: repoDir,
stdio: 'pipe',
shell: process.platform === 'win32'
});
if (result.status !== 0) {
const stderr = result.stderr ? result.stderr.toString() : 'unknown error';
throw new Error(`npm install failed for ${repoName}: ${stderr}`);
}
}
installAllDependencies(onLog) {
for (const repoName of Object.keys(REPOS)) {
this.installDependencies(repoName, onLog);
}
}
getLocalHead(repoName) {
const repoDir = this.repoDir(repoName);
try {
return execSync('git rev-parse HEAD', { cwd: repoDir }).toString().trim();
} catch (e) {
return null;
}
}
getRemoteHead(repoName) {
const { branch } = REPOS[repoName];
const repoDir = this.repoDir(repoName);
const url = this.buildRepoUrl(repoName);
try {
const output = execSync(`git ls-remote "${url}" refs/heads/${branch}`, { cwd: repoDir }).toString().trim();
return output.split('\t')[0] || null;
} catch (e) {
return null;
}
}
checkForUpdates() {
const outdated = [];
for (const repoName of Object.keys(REPOS)) {
const local = this.getLocalHead(repoName);
const remote = this.getRemoteHead(repoName);
if (local && remote && local !== remote) {
outdated.push(repoName);
}
}
return outdated;
}
updateRepo(repoName, onLog) {
const { branch } = REPOS[repoName];
const repoDir = this.repoDir(repoName);
if (onLog) onLog(`Updating ${repoName}...`);
const fetchResult = spawnSync('git', ['fetch', 'origin', branch], {
cwd: repoDir,
stdio: 'pipe',
env: { ...process.env, GIT_TERMINAL_PROMPT: '0' }
});
if (fetchResult.status !== 0) {
const stderr = fetchResult.stderr ? fetchResult.stderr.toString() : 'unknown error';
throw new Error(`Failed to fetch ${repoName}: ${stderr}`);
}
const resetResult = spawnSync('git', ['reset', '--hard', `origin/${branch}`], {
cwd: repoDir,
stdio: 'pipe'
});
if (resetResult.status !== 0) {
const stderr = resetResult.stderr ? resetResult.stderr.toString() : 'unknown error';
throw new Error(`Failed to reset ${repoName}: ${stderr}`);
}
}
updateAll(repoNames, onLog) {
for (const repoName of repoNames) {
this.updateRepo(repoName, onLog);
this.installDependencies(repoName, onLog);
}
}
}
module.exports = GitlabClient