This commit is contained in:
lasta
2026-05-22 00:22:03 +09:00
parent 8d77bc659f
commit d841fb823a
49 changed files with 2732 additions and 3763 deletions

View File

@@ -43,6 +43,184 @@ function Get-CommandPath {
return $null
}
function Test-PythonModule {
param(
[string] $PythonPath,
[string] $ModuleName
)
if ([string]::IsNullOrWhiteSpace($PythonPath)) {
return $false
}
try {
$proc = Start-Process `
-FilePath $PythonPath `
-ArgumentList @("-c", "import $ModuleName") `
-WindowStyle Hidden `
-Wait `
-PassThru
return $proc.ExitCode -eq 0
} catch {
return $false
}
}
function Resolve-ProjectPython {
param([string] $ProjectRoot)
$projectVenvPython = Join-Path $ProjectRoot ".venv\Scripts\python.exe"
if (Test-Path -LiteralPath $projectVenvPython) {
return (Resolve-Path -LiteralPath $projectVenvPython).Path
}
$rootVenvPython = Join-Path $root ".venv\Scripts\python.exe"
if (Test-Path -LiteralPath $rootVenvPython) {
return (Resolve-Path -LiteralPath $rootVenvPython).Path
}
$candidates = @()
if ($env:VIRTUAL_ENV) {
$candidates += Join-Path $env:VIRTUAL_ENV "Scripts\python.exe"
}
$pyLauncher = Get-CommandPath @("py.exe", "py")
if ($pyLauncher) {
try {
$resolvedFromPy = & $pyLauncher -c "import sys; print(sys.executable)" 2>$null
if ($LASTEXITCODE -eq 0 -and -not [string]::IsNullOrWhiteSpace($resolvedFromPy)) {
$candidates += $resolvedFromPy.Trim()
}
} catch {
}
}
$pathPython = Get-CommandPath @("python.exe", "python")
if ($pathPython) {
$candidates += $pathPython
}
$seen = @{}
foreach ($candidate in $candidates) {
if ([string]::IsNullOrWhiteSpace($candidate)) {
continue
}
$resolved = $null
if (Test-Path -LiteralPath $candidate) {
$resolved = (Resolve-Path -LiteralPath $candidate).Path
} else {
$cmd = Get-Command $candidate -ErrorAction SilentlyContinue
if ($cmd) {
$resolved = $cmd.Source
}
}
if (-not $resolved -or $seen.ContainsKey($resolved)) {
continue
}
$seen[$resolved] = $true
if (Test-PythonModule -PythonPath $resolved -ModuleName "uvicorn") {
return $resolved
}
}
return $null
}
function Resolve-SystemPython {
$candidates = @()
if ($env:VIRTUAL_ENV) {
$candidates += Join-Path $env:VIRTUAL_ENV "Scripts\python.exe"
}
$pathPython = Get-CommandPath @("python.exe", "python")
if ($pathPython) {
$candidates += $pathPython
}
$pyLauncher = Get-CommandPath @("py.exe", "py")
if ($pyLauncher) {
try {
$resolvedFromPy = & $pyLauncher -c "import sys; print(sys.executable)" 2>$null
if ($LASTEXITCODE -eq 0 -and -not [string]::IsNullOrWhiteSpace($resolvedFromPy)) {
$candidates += $resolvedFromPy.Trim()
}
} catch {
}
}
$seen = @{}
foreach ($candidate in $candidates) {
if ([string]::IsNullOrWhiteSpace($candidate)) {
continue
}
$resolved = $null
if (Test-Path -LiteralPath $candidate) {
$resolved = (Resolve-Path -LiteralPath $candidate).Path
} else {
$cmd = Get-Command $candidate -ErrorAction SilentlyContinue
if ($cmd) {
$resolved = $cmd.Source
}
}
if (-not $resolved -or $seen.ContainsKey($resolved)) {
continue
}
$seen[$resolved] = $true
return $resolved
}
return $null
}
function Ensure-ProjectVenv {
param([string] $ProjectRoot)
$venvPython = Join-Path $ProjectRoot ".venv\Scripts\python.exe"
if (Test-PythonModule -PythonPath $venvPython -ModuleName "uvicorn") {
return $venvPython
}
$bootstrapPython = Resolve-SystemPython
if (-not $bootstrapPython) {
Write-Step "No system Python was found for bootstrapping the backend venv."
return $null
}
Write-Step "Bootstrapping backend virtual environment in $ProjectRoot\\.venv"
if (-not (Test-Path -LiteralPath $venvPython)) {
Invoke-LoggedCommand `
-FilePath $bootstrapPython `
-Arguments @("-m", "venv", ".venv") `
-WorkingDirectory $ProjectRoot `
-LogName "backend-venv-create.log"
}
Invoke-LoggedCommand `
-FilePath $venvPython `
-Arguments @("-m", "pip", "install", "--upgrade", "pip") `
-WorkingDirectory $ProjectRoot `
-LogName "backend-pip-upgrade.log"
Invoke-LoggedCommand `
-FilePath $venvPython `
-Arguments @("-m", "pip", "install", "-e", ".") `
-WorkingDirectory $ProjectRoot `
-LogName "backend-pip-install.log"
if (Test-PythonModule -PythonPath $venvPython -ModuleName "uvicorn") {
return $venvPython
}
Write-Step "Backend venv was created, but uvicorn is still unavailable. Check .server-logs\\backend-*.log"
return $null
}
function Read-DotEnv {
param([string] $Path)
@@ -185,6 +363,15 @@ function Start-LoggedServer {
}
}
function Clear-ServerLogs {
param([string] $Name)
Remove-Item -LiteralPath `
(Join-Path $logDir "$Name-stdout.log"), `
(Join-Path $logDir "$Name-stderr.log") `
-Force -ErrorAction SilentlyContinue
}
function Wait-Port {
param(
[int] $Port,
@@ -209,6 +396,28 @@ function Wait-Port {
return $false
}
function Resolve-FrontendDevCommand {
param(
[string] $FrontendDir,
[string] $NpmPath
)
$node = Get-CommandPath @("node.exe", "node")
$viteCli = Join-Path $FrontendDir "node_modules\vite\bin\vite.js"
if ($node -and (Test-Path -LiteralPath $viteCli)) {
return [pscustomobject]@{
FilePath = $node
Arguments = @($viteCli, "--host", "127.0.0.1", "--port", "8000")
}
}
return [pscustomobject]@{
FilePath = $NpmPath
Arguments = @("run", "dev", "--", "--host", "127.0.0.1", "--port", "8000")
}
}
function Start-Neo4jIfAvailable {
$composeFile = Join-Path $root "docker-compose.neo4j.yml"
if (-not (Test-Path -LiteralPath $composeFile)) {
@@ -249,13 +458,11 @@ if ((Test-Path -LiteralPath (Join-Path $frontendDir "package.json")) -and $npm)
$servers = @()
$ontologyRoot = Join-Path $root "ontology_platform"
$ontologyPython = Get-CommandPath @(
(Join-Path $ontologyRoot ".venv\Scripts\python.exe"),
(Join-Path $root ".venv\Scripts\python.exe"),
"C:\Users\lasta\AppData\Local\Python\bin\python.exe",
"C:\Users\lasta\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe",
"python"
)
$ontologyPython = Resolve-ProjectPython -ProjectRoot $ontologyRoot
if ((-not $ontologyPython) -and (Test-Path -LiteralPath (Join-Path $ontologyRoot "pyproject.toml"))) {
$ontologyPython = Ensure-ProjectVenv -ProjectRoot $ontologyRoot
}
if ((Test-Path -LiteralPath (Join-Path $ontologyRoot "ont_platform\api\main.py")) -and $ontologyPython) {
$ontologyEnv = Read-DotEnv -Path (Join-Path $ontologyRoot ".env")
@@ -271,15 +478,18 @@ if ((Test-Path -LiteralPath (Join-Path $ontologyRoot "ont_platform\api\main.py")
-WorkingDirectory $ontologyRoot `
-Environment $ontologyEnv
} else {
Write-Step "ontology_platform server entrypoint or Python was not found; skipped."
Clear-ServerLogs -Name "ontology-platform-8001"
Write-Step "ontology_platform server entrypoint was not found, or no Python with uvicorn is available for this project."
Write-Step "Create a venv under ontology_platform\\.venv (or .\\.venv) and install dependencies before rerunning."
}
if ($frontendReady) {
$frontendDev = Resolve-FrontendDevCommand -FrontendDir $frontendDir -NpmPath $npm
$servers += Start-LoggedServer `
-Name "ontology-frontend-8000" `
-Port 8000 `
-FilePath $npm `
-Arguments @("run", "dev", "--", "--host", "127.0.0.1", "--port", "8000") `
-FilePath $frontendDev.FilePath `
-Arguments $frontendDev.Arguments `
-WorkingDirectory $frontendDir
}
@@ -290,7 +500,7 @@ $servers | ForEach-Object {
$missingPorts = @()
foreach ($port in ($servers | Select-Object -ExpandProperty Port -Unique)) {
if (Wait-Port -Port $port -Seconds 25) {
if (Wait-Port -Port $port -Seconds 120) {
Write-Step ("Port {0} is listening." -f $port)
} else {
Write-Step ("Port {0} did not open. Check logs in {1}" -f $port, $logDir)
@@ -304,6 +514,10 @@ if ($missingPorts.Count -gt 0) {
Write-Host ""
Write-Step "Done."
Write-Host " Ontology UI: http://127.0.0.1:8000/static/"
Write-Host " Ontology API: http://127.0.0.1:8001/docs"
if ($servers | Where-Object { $_.Port -eq 8000 }) {
Write-Host " Ontology UI: http://127.0.0.1:8000/static/"
}
if ($servers | Where-Object { $_.Port -eq 8001 }) {
Write-Host " Ontology API: http://127.0.0.1:8001/docs"
}
Write-Host " Logs: $logDir"