78 lines
3.9 KiB
PowerShell
78 lines
3.9 KiB
PowerShell
|
|
$ErrorActionPreference = 'Stop'
|
||
|
|
$repoPath = (Resolve-Path (Join-Path $PSScriptRoot '../..')).Path
|
||
|
|
$runtimePath = Join-Path $PSScriptRoot '.runtime'
|
||
|
|
|
||
|
|
function Read-LocalSettings {
|
||
|
|
param([string]$Path = (Join-Path $PSScriptRoot 'secrets.psd1'))
|
||
|
|
if (-not (Test-Path -LiteralPath $Path)) {
|
||
|
|
throw 'Copy secrets.example.psd1 to secrets.psd1 and fill in the local database password first.'
|
||
|
|
}
|
||
|
|
$settings = Import-PowerShellDataFile -LiteralPath $Path
|
||
|
|
if ($settings.DatabaseName -notmatch '^elder_yudao_[a-z0-9_]+$') {
|
||
|
|
throw 'Use a separate database named elder_yudao_*; existing application databases are not supported by this initializer.'
|
||
|
|
}
|
||
|
|
return $settings
|
||
|
|
}
|
||
|
|
|
||
|
|
function Resolve-LocalProgram {
|
||
|
|
param([string]$ConfiguredPath, [string]$CommandName, [string]$FallbackPath = '')
|
||
|
|
if ($ConfiguredPath) {
|
||
|
|
if (-not (Test-Path -LiteralPath $ConfiguredPath -PathType Leaf)) { throw "Program not found: $ConfiguredPath" }
|
||
|
|
return (Resolve-Path -LiteralPath $ConfiguredPath).Path
|
||
|
|
}
|
||
|
|
$program = Get-Command $CommandName -ErrorAction SilentlyContinue
|
||
|
|
if ($program) { return $program.Source }
|
||
|
|
if ($FallbackPath -and (Test-Path -LiteralPath $FallbackPath)) { return $FallbackPath }
|
||
|
|
throw "Program not found: $CommandName. Install it or set its path in secrets.psd1."
|
||
|
|
}
|
||
|
|
|
||
|
|
function Invoke-LocalMySql {
|
||
|
|
param([hashtable]$Settings, [string]$Query, [string]$Database = '')
|
||
|
|
$mysqlExe = Resolve-LocalProgram $Settings.MySqlExe 'mysql.exe' 'C:\Program Files\MySQL\MySQL Server 8.0\bin\mysql.exe'
|
||
|
|
$arguments = @('--protocol=TCP', "--host=$($Settings.DatabaseHost)", "--port=$($Settings.DatabasePort)",
|
||
|
|
"--user=$($Settings.DatabaseUser)", '--connect-timeout=5', '--default-character-set=utf8mb4', '--batch', '--skip-column-names')
|
||
|
|
if ($Database) { $arguments += "--database=$Database" }
|
||
|
|
$arguments += "--execute=$Query"
|
||
|
|
$previousPassword = $env:MYSQL_PWD
|
||
|
|
try {
|
||
|
|
$env:MYSQL_PWD = $Settings.DatabasePassword
|
||
|
|
$result = @(& $mysqlExe @arguments)
|
||
|
|
if ($LASTEXITCODE -ne 0) { throw 'MySQL command failed; see the error above. No password is printed by this script.' }
|
||
|
|
return $result
|
||
|
|
} finally {
|
||
|
|
if ($null -eq $previousPassword) { Remove-Item Env:\MYSQL_PWD -ErrorAction SilentlyContinue }
|
||
|
|
else { $env:MYSQL_PWD = $previousPassword }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function Get-LocalServerProcess {
|
||
|
|
$pidFile = Join-Path $runtimePath 'server.pid'
|
||
|
|
if (-not (Test-Path -LiteralPath $pidFile)) { return $null }
|
||
|
|
$serverPid = 0
|
||
|
|
if (-not [int]::TryParse((Get-Content -LiteralPath $pidFile -Raw).Trim(), [ref]$serverPid)) {
|
||
|
|
throw 'Invalid server.pid; inspect the runtime directory before continuing.'
|
||
|
|
}
|
||
|
|
$process = Get-CimInstance Win32_Process -Filter "ProcessId=$serverPid" -ErrorAction SilentlyContinue
|
||
|
|
if (-not $process) { return $null }
|
||
|
|
$jarPath = Join-Path $repoPath 'yudao-server/target/yudao-server.jar'
|
||
|
|
if ($process.Name -notmatch '^java(w)?\.exe$' -or -not $process.CommandLine.Contains($jarPath)) {
|
||
|
|
throw 'The recorded PID belongs to another process; refusing to operate on it.'
|
||
|
|
}
|
||
|
|
return $process
|
||
|
|
}
|
||
|
|
|
||
|
|
function Get-LocalUiProcess {
|
||
|
|
$pidFile = Join-Path $runtimePath 'ui.pid'
|
||
|
|
if (-not (Test-Path -LiteralPath $pidFile)) { return $null }
|
||
|
|
$uiPid = 0
|
||
|
|
if (-not [int]::TryParse((Get-Content -LiteralPath $pidFile -Raw).Trim(), [ref]$uiPid)) { throw 'Invalid ui.pid.' }
|
||
|
|
$process = Get-CimInstance Win32_Process -Filter "ProcessId=$uiPid" -ErrorAction SilentlyContinue
|
||
|
|
if (-not $process) { return $null }
|
||
|
|
$vitePaths = @((Join-Path $repoPath 'yudao-ui-admin-vue3/node_modules/vite/bin/vite.js'), (Join-Path $runtimePath 'ui-src/node_modules/vite/bin/vite.js'))
|
||
|
|
$matchesUiPath = @($vitePaths | Where-Object { $process.CommandLine.Contains($_) }).Count -gt 0
|
||
|
|
if ($process.Name -ne 'node.exe' -or -not $matchesUiPath) {
|
||
|
|
throw 'The recorded UI PID belongs to another process; refusing to operate on it.'
|
||
|
|
}
|
||
|
|
return $process
|
||
|
|
}
|