mirror of
https://github.com/hansjone/netx.git
synced 2026-10-09 04:20:45 +08:00
Fix portable Python: ship python/runtime and relink .venv on install (0.4.6).
Some checks failed
Release Windows / build (push) Has been cancelled
Some checks failed
Release Windows / build (push) Has been cancelled
0.4.5 venv pointed at the build machine user profile; other PCs failed to start API. Bundle stdlib under python/runtime, repair pyvenv.cfg, and health-check before start. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
3a89438e5b
commit
5429c07342
7 changed files with 158 additions and 27 deletions
|
|
@ -276,12 +276,21 @@ function Start-NetxPowerShell {
|
|||
function Get-NetxSystemPython {
|
||||
# Prefer a real interpreter; skip the WindowsApps Store stub.
|
||||
$candidates = @()
|
||||
foreach ($cmd in @("python", "python3", "py")) {
|
||||
foreach ($cmd in @("python", "python3")) {
|
||||
$c = Get-Command $cmd -ErrorAction SilentlyContinue
|
||||
if ($c -and $c.Source -and ($c.Source -notmatch '\\WindowsApps\\')) {
|
||||
$candidates += $c.Source
|
||||
}
|
||||
}
|
||||
$pyLauncher = Get-Command "py" -ErrorAction SilentlyContinue
|
||||
if ($pyLauncher -and $pyLauncher.Source -and ($pyLauncher.Source -notmatch '\\WindowsApps\\')) {
|
||||
try {
|
||||
$resolved = (& $pyLauncher.Source -3 -c "import sys; print(sys.executable)" 2>$null | Out-String).Trim()
|
||||
if ($resolved -and (Test-Path -LiteralPath $resolved)) {
|
||||
$candidates += $resolved
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
foreach ($p in @(
|
||||
"$env:LOCALAPPDATA\Python\pythoncore-3.14-64\python.exe",
|
||||
"$env:LOCALAPPDATA\Programs\Python\Python312\python.exe",
|
||||
|
|
@ -300,6 +309,65 @@ function Get-NetxSystemPython {
|
|||
return $null
|
||||
}
|
||||
|
||||
function Get-NetxBundledPythonRoot {
|
||||
param([Parameter(Mandatory = $true)][string]$ProgramRoot)
|
||||
return Join-Path $ProgramRoot "python\runtime"
|
||||
}
|
||||
|
||||
function Repair-NetxShippedVenv {
|
||||
param([Parameter(Mandatory = $true)][string]$ProgramRoot)
|
||||
$cfgPath = Join-Path $ProgramRoot ".venv\pyvenv.cfg"
|
||||
$rtRoot = Get-NetxBundledPythonRoot -ProgramRoot $ProgramRoot
|
||||
$rtPy = Join-Path $rtRoot "python.exe"
|
||||
if (-not (Test-Path -LiteralPath $rtPy)) { return $false }
|
||||
if (-not (Test-Path -LiteralPath $cfgPath)) { return $false }
|
||||
|
||||
$rtRootAbs = (Resolve-Path -LiteralPath $rtRoot).Path
|
||||
$rtPyAbs = (Resolve-Path -LiteralPath $rtPy).Path
|
||||
$ver = "3.14.0"
|
||||
try {
|
||||
$verOut = & $rtPyAbs -c "import sys; print('%d.%d.%d' % sys.version_info[:3])" 2>$null
|
||||
if ($verOut) { $ver = ($verOut | Out-String).Trim() }
|
||||
} catch {}
|
||||
|
||||
$lines = @(
|
||||
"home = $rtRootAbs",
|
||||
"include-system-site-packages = false",
|
||||
"version = $ver",
|
||||
"executable = $rtPyAbs"
|
||||
)
|
||||
Set-Content -LiteralPath $cfgPath -Value ($lines -join "`r`n") -Encoding ascii
|
||||
return $true
|
||||
}
|
||||
|
||||
function Test-NetxVenvRunnable {
|
||||
param([Parameter(Mandatory = $true)][string]$VenvPython)
|
||||
if (-not (Test-Path -LiteralPath $VenvPython)) { return $false }
|
||||
|
||||
$outFile = Join-Path $env:TEMP ("netx-venv-out-" + [Guid]::NewGuid().ToString("n") + ".txt")
|
||||
$errFile = Join-Path $env:TEMP ("netx-venv-err-" + [Guid]::NewGuid().ToString("n") + ".txt")
|
||||
try {
|
||||
$psi = New-Object System.Diagnostics.ProcessStartInfo
|
||||
$psi.FileName = $VenvPython
|
||||
$psi.Arguments = '-c "import encodings, sys; sys.exit(0 if sys.prefix else 1)"'
|
||||
$psi.UseShellExecute = $false
|
||||
$psi.RedirectStandardOutput = $true
|
||||
$psi.RedirectStandardError = $true
|
||||
$psi.CreateNoWindow = $true
|
||||
$p = [Diagnostics.Process]::Start($psi)
|
||||
$stderr = $p.StandardError.ReadToEnd()
|
||||
$null = $p.StandardOutput.ReadToEnd()
|
||||
$p.WaitForExit()
|
||||
if ($stderr -match 'did not find executable|No Python at|Fatal Python error') {
|
||||
return $false
|
||||
}
|
||||
if ($p.ExitCode -ne 0) { return $false }
|
||||
return $true
|
||||
} finally {
|
||||
Remove-Item -LiteralPath $outFile, $errFile -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
function Ensure-NetxVenv {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$ProgramRoot,
|
||||
|
|
@ -307,8 +375,27 @@ function Ensure-NetxVenv {
|
|||
)
|
||||
$venvPy = Join-Path $ProgramRoot ".venv\Scripts\python.exe"
|
||||
$req = Join-Path $ProgramRoot "requirements.txt"
|
||||
if ((Test-Path $venvPy) -and -not $ForcePip) {
|
||||
return $venvPy
|
||||
$rtPy = Join-Path (Get-NetxBundledPythonRoot -ProgramRoot $ProgramRoot) "python.exe"
|
||||
|
||||
if (Test-Path -LiteralPath $rtPy) {
|
||||
$null = Repair-NetxShippedVenv -ProgramRoot $ProgramRoot
|
||||
}
|
||||
|
||||
if ((Test-Path -LiteralPath $venvPy) -and -not $ForcePip) {
|
||||
if (Test-NetxVenvRunnable -VenvPython $venvPy) {
|
||||
return $venvPy
|
||||
}
|
||||
Write-Host "[WARN] Shipped .venv exists but Python cannot start (broken pyvenv.cfg or missing runtime)." -ForegroundColor Yellow
|
||||
if (Test-Path -LiteralPath $rtPy) {
|
||||
$null = Repair-NetxShippedVenv -ProgramRoot $ProgramRoot
|
||||
if (Test-NetxVenvRunnable -VenvPython $venvPy) {
|
||||
Write-Host "==> Repaired .venv to use bundled python/runtime" -ForegroundColor Green
|
||||
return $venvPy
|
||||
}
|
||||
}
|
||||
if (-not $ForcePip) {
|
||||
throw "venv_not_runnable: reinstall NetX Setup (ships python/runtime + .venv) or run repair as admin"
|
||||
}
|
||||
}
|
||||
if (-not (Test-Path $venvPy)) {
|
||||
$py = Get-NetxSystemPython
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue