diff --git a/.gitignore b/.gitignore index 6e10c13..32bc854 100644 --- a/.gitignore +++ b/.gitignore @@ -32,7 +32,6 @@ __pycache__/ .coverage htmlcov/ .hypothesis/ -.vscode/ .idea/ *.swp *.swo diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..bd4bcbe --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "ms-python.python", + "ms-python.vscode-pylance", + "ms-python.black-formatter" + ], + "unwantedRecommendations": [] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..f0d2a8e --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Run WimPyAmp (venv)", + "type": "python", + "request": "launch", + "program": "${workspaceFolder}/run_wimpyamp.py", + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "." + } + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..cdf2a6c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "python.analysis.extraPaths": ["${workspaceFolder}"], + "terminal.integrated.defaultProfile.windows": "PowerShell" +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..b2e9c6e --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,41 @@ +// Windows-specific tasks (PowerShell). On macOS/Linux use the Makefile. +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Setup (winscripts)", + "type": "process", + "command": "powershell", + "args": ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "${workspaceFolder}\\winscripts\\setup.ps1"], + "group": "build", + "problemMatcher": [], + "detail": "Windows-only (PowerShell)." + }, + { + "label": "Run WimPyAmp", + "type": "process", + "command": "powershell", + "args": ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "${workspaceFolder}\\winscripts\\run.ps1"], + "group": "none", + "presentation": { "panel": "dedicated" }, + "problemMatcher": [], + "detail": "Windows-only (PowerShell)." + }, + { + "label": "Lint (ruff)", + "type": "process", + "command": "${workspaceFolder}\\venv\\Scripts\\python", + "args": ["-m", "ruff", "check", "."], + "problemMatcher": [], + "detail": "Windows path to venv shown." + }, + { + "label": "Test (pytest)", + "type": "process", + "command": "${workspaceFolder}\\venv\\Scripts\\python", + "args": ["-m", "pytest", "tests", "-v"], + "problemMatcher": [], + "detail": "Windows path to venv shown." + } + ] +} diff --git a/docs/WINDOWS_VSCODE_SETUP.md b/docs/WINDOWS_VSCODE_SETUP.md new file mode 100644 index 0000000..87e78e1 --- /dev/null +++ b/docs/WINDOWS_VSCODE_SETUP.md @@ -0,0 +1,120 @@ +# Windows 11 — VS Code + venv Setup (Windows helper scripts + VS Code) + +This file shows how to set up and run WimPyAmp on Windows 11 using a local virtual environment and the helper scripts and VS Code task/launch files included in the repository. + +Quick manual setup (PowerShell): + +```powershell +python -m venv venv +Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process +venv\Scripts\python -m pip install --upgrade pip +venv\Scripts\python -m pip install -r requirements.txt +$env:PYTHONPATH='.'; venv\Scripts\python run_wimpyamp.py +``` + +Quick manual setup (cmd.exe): + +```cmd +python -m venv venv +venv\Scripts\python -m pip install --upgrade pip +venv\Scripts\python -m pip install -r requirements.txt +set PYTHONPATH=. && venv\Scripts\python run_wimpyamp.py +``` + +Use the provided helper scripts and VS Code tasks (recommended) + +The repository includes Windows helper scripts in `winscripts/` and VS Code task/launch files in `.vscode/` so contributors can run common workflows without remembering platform-specific commands. + +Run setup (create venv and install dependencies) from PowerShell: + +```powershell +powershell -NoProfile -ExecutionPolicy Bypass -File .\winscripts\setup.ps1 +``` + +Start the application (sets `PYTHONPATH` automatically): + +```powershell +powershell -NoProfile -ExecutionPolicy Bypass -File .\winscripts\run.ps1 +``` + +Or use VS Code tasks: Command Palette → `Tasks: Run Task` → choose `Setup (winscripts)` or `Run WimPyAmp`. + +VS Code notes + +- Interpreter: choose the workspace venv via `Python: Select Interpreter` (recommended path: `${workspaceFolder}\\venv\\Scripts\\python.exe`). Avoid committing machine-specific interpreter paths in `.vscode/settings.json`. +- Debug: use the `.vscode/launch.json` configuration named "Run WimPyAmp (venv)" (Run view / F5). +- Tasks: run `.vscode/tasks.json` entries: `Setup (winscripts)`, `Run WimPyAmp`, `Lint (ruff)`, `Test (pytest)`. +- Extensions: install recommended extensions from `.vscode/extensions.json` (we recommend `ms-python.python`, `ms-python.vscode-pylance`, and `ms-python.black-formatter`). + +Makefile target equivalents (PowerShell) + +```powershell +# setup +python -m venv venv +venv\Scripts\python -m pip install --upgrade pip +venv\Scripts\python -m pip install -r requirements.txt + +# run / start +$env:PYTHONPATH='.'; venv\Scripts\python run_wimpyamp.py + +# install (dependencies only) +venv\Scripts\python -m pip install -r requirements.txt + +# clean +Remove-Item -Recurse -Force venv + +# lint +venv\Scripts\python -m pip install ruff +venv\Scripts\python -m ruff check . + +# format-check +venv\Scripts\python -m pip install black +venv\Scripts\python -m black --check . + +# format +venv\Scripts\python -m black . + +# type-check +venv\Scripts\python -m pip install mypy +venv\Scripts\python -m mypy src/ + +# test +venv\Scripts\python -m pip install pytest +venv\Scripts\python -m pytest tests/ -v + +# dist (pyinstaller) +venv\Scripts\python -m pip install pyinstaller +venv\Scripts\pyinstaller WimPyAmp.spec + +# Windows helper script: `winscripts/dist.ps1` +The repository includes a Windows packaging helper script `winscripts/dist.ps1` that +invokes PyInstaller using the project venv and the existing `WimPyAmp.spec`, then +collects the build artifacts and creates a dated ZIP in `dist/`. + +Run it from PowerShell (recommended): + +```powershell +powershell -NoProfile -ExecutionPolicy Bypass -File .\winscripts\dist.ps1 +``` + +Optional parameters: +- `-VenvPath` : path to the virtual environment (default `. +venv`) +- `-SpecFile` : spec file to use (default `WimPyAmp.spec`) +- `-DistDir` : output directory for collected artifacts (default `. +dist`) + +The script will install PyInstaller into the venv if it's missing, run the spec-based +build, then create an archive like `dist\wimpyamp-YYYYMMDD.zip`. + +# bump version (bump2version inside venv) +venv\Scripts\bump2version patch +venv\Scripts\bump2version minor +venv\Scripts\bump2version major +``` + +Notes + +- The Makefile contains macOS-specific packaging steps (codesign/hdiutil). On Windows, a `pyinstaller` build plus zipping (`Compress-Archive`) is a practical alternative. +- If you prefer to use the Makefile unchanged, run it under WSL where the Unix paths (`venv/bin/...`) match the Makefile. +- Commit `.vscode/launch.json`, `.vscode/tasks.json`, and `.vscode/extensions.json` to share developer workflows; keep `.vscode/settings.json` portable. diff --git a/winscripts/dist.ps1 b/winscripts/dist.ps1 new file mode 100644 index 0000000..4f054d8 --- /dev/null +++ b/winscripts/dist.ps1 @@ -0,0 +1,76 @@ +param( + [string]$VenvPath = ".\venv", + [string]$SpecFile = "WimPyAmp.spec", + [string]$DistDir = ".\dist" +) + +# resolve paths +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition +# project root is parent of the winscripts folder +$projectRoot = Resolve-Path (Join-Path $scriptDir "..") +Push-Location $projectRoot +try { + # resolve venv and spec relative to the project root + $venvFull = Resolve-Path -LiteralPath (Join-Path $projectRoot $VenvPath) -ErrorAction SilentlyContinue + if (-not $venvFull) { + Write-Error "Virtualenv not found at $VenvPath relative to project root $projectRoot" + exit 1 + } + $python = Join-Path $venvFull "Scripts\python.exe" + if (-not (Test-Path $python)) { + Write-Error "Python not found at $python. Create/activate venv and install dependencies including pyinstaller." + exit 1 + } + + $specFull = Resolve-Path -LiteralPath (Join-Path $projectRoot $SpecFile) -ErrorAction SilentlyContinue + if (-not $specFull) { + Write-Error "Spec file not found: $SpecFile (checked under project root)" + exit 1 + } + + # clean previous build outputs + if (Test-Path ".\build") { Remove-Item .\build -Recurse -Force } + if (Test-Path ".\dist") { Remove-Item .\dist -Recurse -Force } + if (Test-Path $DistDir) { Remove-Item $DistDir -Recurse -Force } + + # ensure pyinstaller is available in the venv + & $python -m pip show pyinstaller > $null 2>&1 + if ($LASTEXITCODE -ne 0) { + Write-Output "PyInstaller not found in venv. Installing..." + & $python -m pip install --upgrade pip + & $python -m pip install pyinstaller + if ($LASTEXITCODE -ne 0) { Write-Error "Failed to install PyInstaller"; exit $LASTEXITCODE } + } + + # run pyinstaller using the spec + & $python -m PyInstaller --noconfirm --clean $specFull + if ($LASTEXITCODE -ne 0) { Write-Error "PyInstaller failed"; exit $LASTEXITCODE } + + # move artifacts to DistDir + New-Item -ItemType Directory -Force -Path $DistDir | Out-Null + Get-ChildItem -Path .\dist -File | ForEach-Object { Copy-Item $_.FullName -Destination $DistDir -Force } + + # create dated archive of contents (with retry to avoid transient file locks) + $baseName = Split-Path -Leaf $projectRoot + $ts = Get-Date -Format yyyyMMdd + $archive = Join-Path $DistDir ("$baseName-$ts.zip") + $maxAttempts = 5 + $attempt = 0 + while ($true) { + try { + Compress-Archive -Path (Join-Path $DistDir '*') -DestinationPath $archive -Force + Write-Output "Created $archive" + break + } catch { + $attempt++ + if ($attempt -ge $maxAttempts) { + Write-Error "Failed to create archive after $attempt attempts: $_" + exit 1 + } + Write-Output "Compress-Archive failed (attempt $attempt), retrying in 2s..." + Start-Sleep -Seconds 2 + } + } +} finally { + Pop-Location +} diff --git a/winscripts/run.ps1 b/winscripts/run.ps1 new file mode 100644 index 0000000..18a5369 --- /dev/null +++ b/winscripts/run.ps1 @@ -0,0 +1,10 @@ +#!/usr/bin/env pwsh +Set-StrictMode -Version Latest +Push-Location -LiteralPath (Join-Path $PSScriptRoot "..") +try { + Write-Host "Starting WimPyAmp using venv\Scripts\python..." + $env:PYTHONPATH = '.' + .\venv\Scripts\python run_wimpyamp.py +} finally { + Pop-Location +} diff --git a/winscripts/setup.ps1 b/winscripts/setup.ps1 new file mode 100644 index 0000000..5720ec7 --- /dev/null +++ b/winscripts/setup.ps1 @@ -0,0 +1,7 @@ +#!/usr/bin/env pwsh +Set-StrictMode -Version Latest +Write-Host "Creating virtual environment 'venv' and installing dependencies..." +python -m venv venv +venv\Scripts\python -m pip install --upgrade pip +venv\Scripts\python -m pip install -r requirements.txt +Write-Host "Setup complete."