feat: implement CLI binary service and add Turkish localization support
This commit is contained in:
+1
-1
@@ -8,7 +8,7 @@
|
||||
"allowRemoteAccess": false,
|
||||
"language": "tr",
|
||||
"cliEnvEnabled": true,
|
||||
"defaultPhpVersion": "7.4.33",
|
||||
"defaultPhpVersion": "php-7.4.33",
|
||||
"defaultMariaDbVersion": "mariadb-11.4.2",
|
||||
"mysqlPort": "3306",
|
||||
"mysqlPorts": {}
|
||||
|
||||
@@ -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 })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
))}
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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": {
|
||||
|
||||
Reference in New Issue
Block a user