Skip to content

Instantly share code, notes, and snippets.

@Luxter77
Created January 21, 2026 16:14
Show Gist options
  • Select an option

  • Save Luxter77/8c8d771cd1dd463d1245e320c23a49e7 to your computer and use it in GitHub Desktop.

Select an option

Save Luxter77/8c8d771cd1dd463d1245e320c23a49e7 to your computer and use it in GitHub Desktop.
micropython build+upload code buildtask
param([switch]$Upload, [switch]$Clean)
$ErrorActionPreference = "Stop"
$src = ".\src"
$dest = ".\mirror"
$port = "COM5"
# --- CLEAN STEP (Delete .mpy files from device) ---
if ($Clean) {
Write-Host "`n" -NoNewline
Write-Host "╔════════════════════════════════════════╗" -ForegroundColor Magenta
Write-Host "║ Cleaning .mpy files from device ║" -ForegroundColor Magenta
Write-Host "╚════════════════════════════════════════╝" -ForegroundColor Magenta
$mpyFiles = mpremote connect $port ls -r : | Select-String '\.mpy$'
if ($mpyFiles.Count -gt 0) {
$mpyFiles | ForEach-Object {
$file = $_.Line -split '\s+' | Select-Object -Last 1
Write-Host " ✓ Removing $file"
mpremote connect $port rm ":/$file"
}
Write-Host " Cleanup Complete`n" -ForegroundColor Green
} else {
Write-Host " No .mpy files found to remove`n" -ForegroundColor Gray
}
if (-not $Upload) { exit 0 }
}
# --- BUILD STEP ---
Write-Host "╔════════════════════════════════════════╗" -ForegroundColor Cyan
Write-Host "║ Building Mirror ║" -ForegroundColor Cyan
Write-Host "╚════════════════════════════════════════╝" -ForegroundColor Cyan
if (Test-Path $dest) { Remove-Item -Recurse -Force $dest }
New-Item -ItemType Directory -Path $dest | Out-Null
# Store mpy-cross errors and traceback for later display
$mpyErrorTrace = ""
try {
Get-ChildItem -Path $src -Recurse | ForEach-Object {
$relativePath = $_.FullName.Substring((Get-Item $src).FullName.Length)
$destPath = "$dest$relativePath"
if ($_.PSIsContainer) {
if (-not (Test-Path $destPath)) { New-Item -ItemType Directory -Path $destPath | Out-Null }
} else {
# Keep boot.py and main.py as TEXT
if ($_.Name -eq "boot.py" -or $_.Name -eq "main.py") {
Copy-Item -Path $_.FullName -Destination $destPath -Force
}
elseif ($_.Extension -eq ".py") {
# Compile everything else to .mpy
$mpyDest = $destPath -replace "\.py$", ".mpy"
Write-Host " ⟳ Compiling $($_.Name)..."
# Execute inside a script block to relax error preference locally
# This prevents stderr from triggering an immediate Stop exception
$mpyOutput = & {
$ErrorActionPreference = "Continue"
mpy-cross -march=xtensawin -O2 $_.FullName -o $mpyDest
} 2>&1
if ($LASTEXITCODE -ne 0) {
$mpyErrorTrace += "Command: mpy-cross -march=xtensawin -O2 $($_.FullName) -o $mpyDest`n"
$mpyErrorTrace += ($mpyOutput | Out-String)
$mpyErrorTrace += "`n"
Write-Host " Failed to compile $($_.Name)" -ForegroundColor Red
throw "Failed to compile $($_.FullName)"
}
}
else {
# Copy assets (json, txt, etc.)
Copy-Item -Path $_.FullName -Destination $destPath -Force
}
}
}
} catch {
Write-Host "`n" -NoNewline
Write-Host "╔════════════════════════════════════════╗" -ForegroundColor Red
Write-Host "║ Error During Build ║" -ForegroundColor Red
Write-Host "╚════════════════════════════════════════╝" -ForegroundColor Red
Write-Host " $_" -ForegroundColor Red
if ($mpyErrorTrace) {
$mpyErrorTrace | Write-Host -ForegroundColor Red
}
exit 1
}
# --- UPLOAD STEP (Using mpremote) ---
if ($Upload) {
Write-Host "`n" -NoNewline
Write-Host "╔════════════════════════════════════════╗" -ForegroundColor Yellow
# Dynamically pad the string to match the box width (40 chars)
$uploadMsg = " Uploading to $port".PadRight(40)
Write-Host "║$uploadMsg║" -ForegroundColor Yellow
Write-Host "╚════════════════════════════════════════╝" -ForegroundColor Yellow
try {
# We iterate over the immediate children of 'mirror' and copy them to root ':'
# This prevents creating a parent '/mirror' folder on the device.
Get-ChildItem -Path $dest | ForEach-Object {
$localItem = $_.FullName
$remoteItem = ":" # Colon represents root on device
Write-Host " ↑ Uploading $($_.Name)..."
# 'cp -r' handles both files and folders recursively
# Relax error preference strictly for execution to capture exit code manually
& {
$ErrorActionPreference = "Continue"
mpremote connect $port cp -r $localItem $remoteItem
}
if ($LASTEXITCODE -ne 0) {
throw "Failed to upload $($_.Name)"
}
}
# Optional: Soft Reset the device to load new code
Write-Host "`n" -NoNewline
Write-Host "╔════════════════════════════════════════╗" -ForegroundColor Magenta
Write-Host "║ Resetting Device ║" -ForegroundColor Magenta
Write-Host "╚════════════════════════════════════════╝" -ForegroundColor Magenta
& {
$ErrorActionPreference = "Continue"
mpremote connect $port reset
}
if ($LASTEXITCODE -ne 0) {
throw "Failed to reset device"
}
Write-Host "`n" -NoNewline
Write-Host "╔════════════════════════════════════════╗" -ForegroundColor Green
Write-Host "║ Upload Complete ✓ ║" -ForegroundColor Green
Write-Host "╚════════════════════════════════════════╝`n" -ForegroundColor Green
} catch {
Write-Host "`n" -NoNewline
Write-Host "╔════════════════════════════════════════╗" -ForegroundColor Red
Write-Host "║ Error During Upload ║" -ForegroundColor Red
Write-Host "╚════════════════════════════════════════╝" -ForegroundColor Red
Write-Host " $_" -ForegroundColor Red
exit 1
}
}
{
"version": "2.0.0",
"tasks": [
{
"label": "Build mpy",
"type": "shell",
"command": "powershell",
"args": [
"-ExecutionPolicy",
"Bypass",
"-File",
"${workspaceFolder}/build.ps1"
],
"problemMatcher": [],
"group": "build"
},
{
"label": "Build & Upload",
"type": "shell",
"command": "powershell",
"args": [
"-ExecutionPolicy",
"Bypass",
"-File",
"${workspaceFolder}/build.ps1",
"-Upload"
],
"problemMatcher": [],
"group": "build"
},
{
"label": "Clean board",
"type": "shell",
"command": "powershell",
"args": [
"-ExecutionPolicy",
"Bypass",
"-File",
"${workspaceFolder}/build.ps1",
"-Clean"
],
"problemMatcher": [],
"group": "build"
},
{
"label": "Clean & Upload",
"type": "shell",
"command": "powershell",
"args": [
"-ExecutionPolicy",
"Bypass",
"-File",
"${workspaceFolder}/build.ps1",
"-Clean",
"-Upload"
],
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment