From a952f0d8dd2f3b8ff6afcfa3af4fdcb22fbe960e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Cmit=20Tun=C3=A7?= Date: Mon, 30 Mar 2026 11:13:53 +0300 Subject: [PATCH] feat: implement IPC handlers and core management services for Nginx, PHP, and MariaDB processes --- src/main/index.ts | 4 + src/main/ipc/index.ts | 25 +++- src/main/services/CliAliasService.ts | 126 +++++++++++++++++++++ src/main/services/MariaDbManagerService.ts | 21 ++++ src/main/services/PhpManagerService.ts | 16 +-- 5 files changed, 184 insertions(+), 8 deletions(-) create mode 100644 src/main/services/CliAliasService.ts diff --git a/src/main/index.ts b/src/main/index.ts index f3fa735..429da10 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -2,6 +2,7 @@ import { app, shell, BrowserWindow, Tray, Menu, nativeImage } from 'electron' import { join } from 'path' import { electronApp, optimizer, is } from '@electron-toolkit/utils' import { registerIpcHandlers } from './ipc' +import { cliAliasService } from './services/CliAliasService' let tray: Tray | null = null let mainWindow: BrowserWindow | null = null @@ -80,6 +81,9 @@ app.whenReady().then(() => { createTray() registerIpcHandlers() + // Generate CLI aliases on start + cliAliasService.generateAliases().catch(console.error) + app.on('activate', function () { if (BrowserWindow.getAllWindows().length === 0) createWindow() }) diff --git a/src/main/ipc/index.ts b/src/main/ipc/index.ts index cb4690f..e38e49d 100644 --- a/src/main/ipc/index.ts +++ b/src/main/ipc/index.ts @@ -11,6 +11,7 @@ import { phpMyAdminService } from '../services/PhpMyAdminService' import { portMappingService } from '../services/PortMappingService' import path from 'path' import { mariaDbOperationService } from '../services/MariaDbOperationService' +import { cliAliasService } from '../services/CliAliasService' function findExecutable(dir: string, name: string): string | null { if (!fs.existsSync(dir)) return null @@ -331,6 +332,8 @@ export function registerIpcHandlers(): void { }) phpManagerService.updateProgress(id, 100, 'installed') + // Regenerate aliases after install + await cliAliasService.generateAliases() return { success: true, message: 'İndirme tamamlandı.' } } catch (error: any) { phpManagerService.updateProgress(id, 0, 'available') @@ -358,6 +361,8 @@ export function registerIpcHandlers(): void { }) mariaDbManagerService.updateProgress(id, 100, 'installed') + // Regenerate aliases after install + await cliAliasService.generateAliases() return { success: true, message: 'MariaDB indirme tamamlandı.' } } catch (error: any) { mariaDbManagerService.updateProgress(id, 0, 'available') @@ -427,10 +432,28 @@ export function registerIpcHandlers(): void { }) ipcMain.handle('binaries:download', async (_event, { name, url }) => { - return downloadService.downloadAndExtract(url, name, (p) => { + const result = await downloadService.downloadAndExtract(url, name, (p) => { // TODO: Emit progress to renderer via webContents.send console.log(`Download progress for ${name}: ${p}%`) }) + await cliAliasService.generateAliases() + return result + }) + + ipcMain.handle('cli:generate-aliases', async () => { + try { + await cliAliasService.generateAliases() + return { + success: true, + message: 'CLI aliasları başarıyla oluşturuldu.', + paths: { + powershell: configService.getGeneratedPath('aliases.ps1'), + bash: configService.getGeneratedPath('aliases.sh') + } + } + } catch (error: any) { + return { success: false, message: `Hata: ${error.message}` } + } }) // Project management diff --git a/src/main/services/CliAliasService.ts b/src/main/services/CliAliasService.ts new file mode 100644 index 0000000..5451010 --- /dev/null +++ b/src/main/services/CliAliasService.ts @@ -0,0 +1,126 @@ +import fs from 'fs' +import { phpManagerService } from './PhpManagerService' +import { mariaDbManagerService } from './MariaDbManagerService' +import { configService } from './ConfigService' + +export class CliAliasService { + async generateAliases() { + const phpVersions = await phpManagerService.getVersions() + const mariaDbVersions = await mariaDbManagerService.getVersions() + + const installedPhp = phpVersions.filter(v => v.status === 'installed') + const installedMariaDb = mariaDbVersions.filter(v => v.status === 'installed') + + await this.generatePowerShellAliases(installedPhp, installedMariaDb) + await this.generateBashAliases(installedPhp, installedMariaDb) + } + + private async generatePowerShellAliases(phpVersions: any[], mariaDbVersions: any[]) { + let content = '# MultiPHP PowerShell Aliases\n\n' + + // PHP Aliases + for (const v of phpVersions) { + const binaryPath = await phpManagerService.getPhpBinaryPath(v.version) + if (binaryPath) { + const shortVersion = v.version.split('.').slice(0, 2).join('') // 7.4 -> 74 + const majorVersion = v.version.split('.')[0] // 8.1 -> 8 + + content += `function php${v.version.replace(/\./g, '')} { & "${binaryPath}" @args }\n` + content += `function php${shortVersion} { & "${binaryPath}" @args }\n` + + // If it's the latest of its major version (they are sorted descending) + const isLatestMajor = phpVersions.find(pv => pv.version.startsWith(majorVersion)) === v + if (isLatestMajor) { + content += `function php${majorVersion} { & "${binaryPath}" @args }\n` + } + } + } + + // Global php (latest installed) + if (phpVersions.length > 0) { + const latestPhp = phpVersions[0] + const latestPath = await phpManagerService.getPhpBinaryPath(latestPhp.version) + if (latestPath) { + content += `function php { & "${latestPath}" @args }\n` + } + } + + // MariaDB/MySQL Aliases + for (const v of mariaDbVersions) { + const binaryPath = await mariaDbManagerService.getMariaDbBinaryPath(v.version) + if (binaryPath) { + const shortVersion = v.version.split('.').slice(0, 2).join('') // 10.11 -> 1011 + content += `function mysql${shortVersion} { & "${binaryPath}" @args }\n` + content += `function mariadb${shortVersion} { & "${binaryPath}" @args }\n` + } + } + + // Global mysql/mariadb (latest installed) + if (mariaDbVersions.length > 0) { + const latestDb = mariaDbVersions[0] + const latestPath = await mariaDbManagerService.getMariaDbBinaryPath(latestDb.version) + if (latestPath) { + content += `function mysql { & "${latestPath}" @args }\n` + content += `function mariadb { & "${latestPath}" @args }\n` + } + } + + const targetPath = configService.getGeneratedPath('aliases.ps1') + fs.writeFileSync(targetPath, content) + } + + private async generateBashAliases(phpVersions: any[], mariaDbVersions: any[]) { + let content = '# MultiPHP Bash/Zsh Aliases\n\n' + + // PHP Aliases + for (const v of phpVersions) { + const binaryPath = await phpManagerService.getPhpBinaryPath(v.version) + if (binaryPath) { + const normalizedPath = binaryPath.replace(/\\/g, '/') + const shortVersion = v.version.split('.').slice(0, 2).join('') + const majorVersion = v.version.split('.')[0] + + content += `alias php${v.version.replace(/\./g, '')}='${normalizedPath}'\n` + content += `alias php${shortVersion}='${normalizedPath}'\n` + + const isLatestMajor = phpVersions.find(pv => pv.version.startsWith(majorVersion)) === v + if (isLatestMajor) { + content += `alias php${majorVersion}='${normalizedPath}'\n` + } + } + } + + if (phpVersions.length > 0) { + const latestPhp = phpVersions[0] + const latestPath = (await phpManagerService.getPhpBinaryPath(latestPhp.version))?.replace(/\\/g, '/') + if (latestPath) { + content += `alias php='${latestPath}'\n` + } + } + + // MariaDB Aliases + for (const v of mariaDbVersions) { + const binaryPath = await mariaDbManagerService.getMariaDbBinaryPath(v.version) + if (binaryPath) { + const normalizedPath = binaryPath.replace(/\\/g, '/') + const shortVersion = v.version.split('.').slice(0, 2).join('') + content += `alias mysql${shortVersion}='${normalizedPath}'\n` + content += `alias mariadb${shortVersion}='${normalizedPath}'\n` + } + } + + if (mariaDbVersions.length > 0) { + const latestDb = mariaDbVersions[0] + const latestPath = (await mariaDbManagerService.getMariaDbBinaryPath(latestDb.version))?.replace(/\\/g, '/') + if (latestPath) { + content += `alias mysql='${latestPath}'\n` + content += `alias mariadb='${latestPath}'\n` + } + } + + const targetPath = configService.getGeneratedPath('aliases.sh') + fs.writeFileSync(targetPath, content) + } +} + +export const cliAliasService = new CliAliasService() diff --git a/src/main/services/MariaDbManagerService.ts b/src/main/services/MariaDbManagerService.ts index 9f6a581..7a919eb 100644 --- a/src/main/services/MariaDbManagerService.ts +++ b/src/main/services/MariaDbManagerService.ts @@ -135,6 +135,27 @@ export class MariaDbManagerService { version.status = status } } + + async getMariaDbBinaryPath(version: string): Promise { + const isWindows = process.platform === 'win32' + const binaryName = isWindows ? 'mariadbd.exe' : 'mariadbd' + const targetDir = path.join(this.binDir, `mariadb-${version}`) + + const possibleBinPaths = [ + path.join(targetDir, 'bin', binaryName), + path.join(targetDir, `mariadb-${version}-${isWindows ? 'winx64' : (process.arch === 'arm64' ? 'macosx-arm64' : 'macosx-x86_64')}`, 'bin', binaryName), + path.join(targetDir, `mariadb-${version}-${isWindows ? 'winx64' : 'linux-systemd-x86_64'}`, 'bin', binaryName) + ] + + for (const p of possibleBinPaths) { + if (fs.existsSync(p)) { + // Return mysql/mariadb client instead of the daemon for CLI usage + const clientName = isWindows ? 'mysql.exe' : 'mysql' + return path.join(path.dirname(p), clientName) + } + } + return null + } } export const mariaDbManagerService = new MariaDbManagerService() diff --git a/src/main/services/PhpManagerService.ts b/src/main/services/PhpManagerService.ts index 677d7c5..82114f7 100644 --- a/src/main/services/PhpManagerService.ts +++ b/src/main/services/PhpManagerService.ts @@ -96,13 +96,6 @@ export class PhpManagerService { }) } - // Also check for supported versions list (e.g. older 8.x) - if (majorEntry.supported_versions) { - for (const branch of majorEntry.supported_versions) { - // This JSON doesn't give specific patch versions for these branches, - // but winData usually covers the latest of each branch anyway. - } - } } // De-duplicate and sort @@ -152,6 +145,15 @@ export class PhpManagerService { version.status = status } } + + async getPhpBinaryPath(version: string): Promise { + const targetDir = path.join(this.binDir, `php-${version}`) + const phpExe = path.join(targetDir, 'php.exe') + if (fs.existsSync(phpExe)) { + return phpExe + } + return null + } } export const phpManagerService = new PhpManagerService()