feat: implement CLI binary service and add Turkish localization support

This commit is contained in:
Ümit Tunç
2026-04-02 11:46:05 +03:00
parent 6be62c6908
commit f6876367bc
5 changed files with 37 additions and 24 deletions
+16 -18
View File
@@ -11,7 +11,7 @@ const execAsync = promisify(exec)
export class CliBinService {
private _binDir: string | null = null
private aliases: { command: string, target: string }[] = []
private aliases: { command: string, target: string, version: string }[] = []
constructor() {}
@@ -45,6 +45,7 @@ export class CliBinService {
for (const v of installedPhp) {
const binaryPath = await phpManagerService.getPhpBinaryPath(v.version)
if (binaryPath) {
const versionName = `PHP ${v.version}`
// version: 8.1.2 -> php812, php81, php8, php8.1
const vParts = v.version.split('.')
const aliases = [
@@ -54,12 +55,13 @@ export class CliBinService {
]
for (const alias of aliases) {
this.createWindowsShim(alias, binaryPath)
this.createWindowsShim(alias, binaryPath, versionName)
}
// If this is the chosen default binary for general 'php'
if (settings.defaultPhpVersion === v.version) {
this.createWindowsShim('php', binaryPath)
// Use v.id for more robust comparison if available, or fallback to version
if (settings.defaultPhpVersion === v.id || settings.defaultPhpVersion === v.version) {
this.createWindowsShim('php', binaryPath, versionName)
}
}
}
@@ -68,13 +70,14 @@ export class CliBinService {
if (!settings.defaultPhpVersion && installedPhp.length > 0) {
const latest = installedPhp[0]
const path = await phpManagerService.getPhpBinaryPath(latest.version)
if (path) this.createWindowsShim('php', path)
if (path) this.createWindowsShim('php', path, `PHP ${latest.version}`)
}
// Generate MariaDB shims
for (const v of installedMariaDb) {
const binaryPath = await mariaDbManagerService.getMariaDbBinaryPath(v.version)
if (binaryPath) {
const versionName = `MariaDB ${v.version}`
const vParts = v.version.split('.')
const aliases = [
`mysql${vParts[0]}${vParts[1]}`,
@@ -84,12 +87,12 @@ export class CliBinService {
]
for (const alias of aliases) {
this.createWindowsShim(alias, binaryPath)
this.createWindowsShim(alias, binaryPath, versionName)
}
if (settings.defaultMariaDbVersion === v.id) {
this.createWindowsShim('mysql', binaryPath)
this.createWindowsShim('mariadb', binaryPath)
this.createWindowsShim('mysql', binaryPath, versionName)
this.createWindowsShim('mariadb', binaryPath, versionName)
}
}
}
@@ -99,8 +102,9 @@ export class CliBinService {
const latest = installedMariaDb[0]
const path = await mariaDbManagerService.getMariaDbBinaryPath(latest.version)
if (path) {
this.createWindowsShim('mysql', path)
this.createWindowsShim('mariadb', path)
const vName = `MariaDB ${latest.version}`
this.createWindowsShim('mysql', path, vName)
this.createWindowsShim('mariadb', path, vName)
}
}
@@ -110,25 +114,19 @@ export class CliBinService {
}
}
private createWindowsShim(name: string, targetPath: string) {
private createWindowsShim(name: string, targetPath: string, version: string) {
if (process.platform !== 'win32') {
// For Unix we could use symlinks, but Multi-PHP target is mainly Windows for now
// Symlinks are also fine: fs.symlinkSync(targetPath, path.join(this.binDir, name))
return
}
// Create a small .cmd proxy for each command
// Using "@%* " to pass all arguments correctly
const content = `@echo off\n"${targetPath}" %*\n`
const binDir = this.getBinDirInternal()
fs.writeFileSync(path.join(binDir, `${name}.cmd`), content)
// Also create a .bat just in case
fs.writeFileSync(path.join(binDir, `${name}.bat`), content)
// Track alias
if (!this.aliases.some(a => a.command === name)) {
this.aliases.push({ command: name, target: targetPath })
this.aliases.push({ command: name, target: targetPath, version })
}
}
+17 -4
View File
@@ -1,4 +1,4 @@
import { useState, useEffect, useRef, useMemo } from 'react'
import { useState, useEffect } from 'react'
import logo from './assets/logo.svg'
import {
Box,
@@ -1280,7 +1280,7 @@ function App(): JSX.Element {
>
<MenuItem value=""><em>{t('common.ready')}</em></MenuItem>
{phpVersions.filter(v => v.status === 'installed').map(v => (
<MenuItem key={v.id} value={v.version}>PHP {v.version}</MenuItem>
<MenuItem key={v.id} value={v.id}>PHP {v.version}</MenuItem>
))}
</Select>
<Typography variant="caption" color="text.secondary" sx={{ mt: 0.5 }}>{t('settings.cli_default_php_desc')}</Typography>
@@ -1330,6 +1330,12 @@ function App(): JSX.Element {
</Button>
</Box>
{cliConfig.enabled && (
<Alert severity="info" sx={{ bgcolor: 'rgba(2, 136, 209, 0.1)', color: '#91d5ff', '& .MuiAlert-icon': { color: '#91d5ff' } }}>
{t('settings.cli_restart_warning')}
</Alert>
)}
{cliConfig.aliases && cliConfig.aliases.length > 0 && (
<Box sx={{ mt: 2 }}>
<Typography variant="subtitle2" sx={{ mb: 1, fontWeight: 600, color: 'primary.main' }}>
@@ -1340,10 +1346,17 @@ function App(): JSX.Element {
{cliConfig.aliases.map((a: any) => (
<ListItem key={a.command} divider sx={{ py: 0.5, borderColor: 'rgba(255,255,255,0.05)' }}>
<ListItemText
primary={<code>{a.command}</code>}
primary={
<Box component="span" sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<code>{a.command}</code>
<Typography variant="caption" sx={{ opacity: 0.5, fontWeight: 'normal' }}>
({a.version})
</Typography>
</Box>
}
secondary={a.target}
primaryTypographyProps={{ variant: 'body2', fontWeight: 'bold' }}
secondaryTypographyProps={{ variant: 'caption', sx: { opacity: 0.5 } }}
secondaryTypographyProps={{ variant: 'caption', sx: { opacity: 0.5, fontStyle: 'italic' } }}
/>
</ListItem>
))}
+1
View File
@@ -114,6 +114,7 @@
"cli_path_not_found": "PATH Not Set Yet",
"cli_sync_success": "CLI commands updated successfully.",
"cli_aliases_title": "Generated Commands (Aliases)",
"cli_restart_warning": "Notice: You must restart your terminal/CMD windows for PATH changes to take effect.",
"server_settings": "Server Settings"
},
"server": {
+2 -1
View File
@@ -114,7 +114,8 @@
"cli_path_found": "PATH Ayarı Bulundu:",
"cli_path_not_found": "PATH Ayarı Henüz Yapılmamış",
"cli_sync_success": "CLI komutları başarıyla güncellendi.",
"cli_aliases_title": "Oluşturulan Komutlar (Takma Adlar)"
"cli_aliases_title": "Oluşturulan Komutlar (Takma Adlar)",
"cli_restart_warning": "Dikkat: PATH değişikliklerinin geçerli olması için açık olan terminal/CMD pencerelerinizi kapatıp yeniden açmalısınız."
},
"server": {
"nginx": {