From 752c12b57943e8c096e13439dfce2f875bca04d7 Mon Sep 17 00:00:00 2001 From: Ednunp <29843396+Ednunp@users.noreply.github.com> Date: Thu, 28 May 2026 14:28:04 +0100 Subject: [PATCH] build-release.ps1: more robust Python detection Two Windows-specific gotchas the previous code didn't handle: 1) The 'python' / 'python3' commands on most Windows installs are Microsoft Store execution aliases. They appear on PATH, accept any invocation, exit with code 9009, and print a "go install from the Store" message instead of running the script. 2) The 'py' launcher accepts --version and returns the right thing (it knows about registered Pythons via the registry), but on some setups it refuses to run scripts and falls through to the Store alias too. Seen here: 'py --version' prints 3.11.9 but 'py sync-manual.py' prints the Store message and exits 9009. The new approach runs an actual sentinel script via -c with each candidate and only accepts the candidate when stdout matches the expected string. User-local install paths come first because they skip the Store-alias issue entirely. Falls through to 'py' and the PATH commands as backstops. Co-Authored-By: Claude Opus 4.7 --- build-release.ps1 | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/build-release.ps1 b/build-release.ps1 index ec7d1e9..9d463e2 100644 --- a/build-release.ps1 +++ b/build-release.ps1 @@ -46,14 +46,41 @@ $staging = Join-Path ([System.IO.Path]::GetTempPath()) ("remsound-release-" + [g $syncScript = Join-Path $repo 'sync-manual.py' if (Test-Path $syncScript) { Write-Host "Syncing MANUAL.md from readme.html..." -ForegroundColor Cyan - # Prefer the user-local Python 3.11 install; fall back to whichever 'python' resolves - # on PATH if that's not present. py.exe is the official Windows launcher and is the - # most reliable single command, so try it first. + # Look for a real Python interpreter — must actually RUN, not just exist. Windows ships + # "Microsoft Store" execution aliases for 'py' and 'python' that fail with exit 9009 and + # a "go install from the Store" message instead of running anything, so a plain + # Get-Command check isn't enough. Test each candidate with 'python --version' first and + # only treat a 0-exit result as a real install. Falls back to a couple of known user- + # local install paths if no PATH-resolved candidate works. + # Find a real Python interpreter. Tricky on Windows because: + # - The 'py' launcher passes --version queries but can refuse to run scripts when its + # registry-based interpreter lookup misses (seen on this dev box: 'py --version' + # prints 3.11.9 but 'py sync-manual.py' falls through to the Microsoft Store stub). + # - The 'python' command is by default an execution alias to the Microsoft Store install + # prompt — it accepts the call, exits with 9009, and prints "go install from the Store". + # So we run an actual one-line script via -c with each candidate and accept the candidate + # only if the script ran (output matches our expected sentinel). User-local Python install + # paths come first because they're the most reliable way to skip past the Store alias. + $candidates = @( + (Join-Path $env:LOCALAPPDATA 'Programs\Python\Python313\python.exe'), + (Join-Path $env:LOCALAPPDATA 'Programs\Python\Python312\python.exe'), + (Join-Path $env:LOCALAPPDATA 'Programs\Python\Python311\python.exe'), + 'python3.11', 'python3.12', 'python3.13', + 'py', 'python3', 'python' + ) $pythonCmd = $null - foreach ($candidate in @('py', 'python', 'python3')) { - if (Get-Command $candidate -ErrorAction SilentlyContinue) { $pythonCmd = $candidate; break } + foreach ($candidate in $candidates) { + if (-not $candidate) { continue } + try { + $sentinel = & $candidate -c "print('PYOK')" 2>&1 + if ($LASTEXITCODE -eq 0 -and ($sentinel -join '') -match 'PYOK') { + $pythonCmd = $candidate + break + } + } catch { continue } } - if (-not $pythonCmd) { throw "Python not found on PATH - cannot sync MANUAL.md. Install Python 3.x and re-run." } + if (-not $pythonCmd) { throw "Python not found - cannot sync MANUAL.md. Install Python 3.x and re-run." } + Write-Host "Using Python: $pythonCmd" -ForegroundColor DarkGray & $pythonCmd $syncScript if ($LASTEXITCODE -ne 0) { throw "sync-manual.py failed (exit $LASTEXITCODE)" }