import path from 'node:path'; import fs from 'node:fs'; import os from 'node:os'; import { execSync } from 'node:child_process'; export type KeepAliveData = { wsUrl: string; cookie: string; repo: string; pipelineId: string; createdTime: number; filePath: string; pm2Name: string; } type KeepAliveCache = { data: KeepAliveData[]; } const keepAliveFilePath = path.join(os.homedir(), '.cnb/keepAliveCache.json'); export const runLive = (filePath: string, pm2Name: string) => { // 使用 npx 运行命令 const cmdArgs = `cnb live -c ${filePath}`; // 先停止已存在的同名 pm2 进程 const stopCmd = `pm2 delete ${pm2Name} 2>/dev/null || true`; console.log('停止已存在的进程:', stopCmd); try { execSync(stopCmd, { stdio: 'inherit' }); } catch (error) { console.log('停止进程失败或进程不存在:', error); } // 使用pm2启动 const pm2Cmd = `pm2 start ev --name ${pm2Name} --no-autorestart -- ${cmdArgs}`; console.log('执行命令:', pm2Cmd); try { const result = execSync(pm2Cmd, { stdio: 'pipe', encoding: 'utf8' }); console.log(result); } catch (error) { console.error("状态码:", error.status); console.error("错误详情:", error.stderr.toString()); // 这里会显示 ev 命令报的具体错误 } } export const stopLive = (pm2Name: string): boolean => { const stopCmd = `pm2 delete ${pm2Name} 2>/dev/null || true`; console.log('停止进程:', stopCmd); try { execSync(stopCmd, { stdio: 'inherit' }); console.log(`已停止 ${pm2Name} 的保持存活任务`); return true; } catch (error) { console.error('停止进程失败:', error); } return false; } export function getKeepAliveCache(): KeepAliveCache { try { if (fs.existsSync(keepAliveFilePath)) { const data = fs.readFileSync(keepAliveFilePath, 'utf-8'); const cache = JSON.parse(data) as KeepAliveCache; return cache; } else { return { data: [] }; } } catch (error) { console.error('读取保持存活缓存文件失败:', error); return { data: [] }; } } export function addKeepAliveData(data: KeepAliveData): KeepAliveCache { const cache = getKeepAliveCache(); cache.data.push(data); runLive(data.filePath, data.pm2Name); try { if (!fs.existsSync(path.dirname(keepAliveFilePath))) { fs.mkdirSync(path.dirname(keepAliveFilePath), { recursive: true }); } fs.writeFileSync(keepAliveFilePath, JSON.stringify(cache, null, 2), 'utf-8'); return cache; } catch (error) { console.error('写入保持存活缓存文件失败:', error); return { data: [] }; } } export function removeKeepAliveData(repo: string, pipelineId: string): KeepAliveCache { const cache = getKeepAliveCache(); cache.data = cache.data.filter(item => item.repo !== repo || item.pipelineId !== pipelineId); try { fs.writeFileSync(keepAliveFilePath, JSON.stringify(cache, null, 2), 'utf-8'); return cache; } catch (error) { console.error('写入保持存活缓存文件失败:', error); return { data: [] }; } } export const createLiveData = (data: { wsUrl: string, cookie: string, repo: string, pipelineId: string }): KeepAliveData => { const { wsUrl, cookie, repo, pipelineId } = data; const createdTime = Date.now(); const pm2Name = `${repo}__${pipelineId}`.replace(/\//g, '__'); const filePath = path.join(os.homedir(), '.cnb', `${pm2Name}.json`); const _newData = { wss: wsUrl, wsUrl, cookie, repo, pipelineId, createdTime, filePath, pm2Name }; if (!fs.existsSync(path.dirname(filePath))) { fs.mkdirSync(path.dirname(filePath), { recursive: true }); } fs.writeFileSync(filePath, JSON.stringify(_newData, null, 2), 'utf-8'); return _newData; }