mirror of
https://github.com/torlando-tech/pyxis.git
synced 2026-07-20 02:21:16 +00:00
PIO copies a \`file://\` lib_dep into \`.pio/libdeps/<env>/<lib>\` once on first install and never re-syncs even when the source changes. That silently masks fixes — the build succeeds and the device flashes, but the firmware contains the OLD source tree from whenever PIO last fetched. Bit us hard on a microReticulum security fix that lived in \`~/repos/microReticulum/\` for an entire test session before anyone realized it had never reached the device. Every "this should be fixed now" run was reading stale code; only \`rm -rf .pio/libdeps/tdeck/microReticulum\` actually picked up the patch. Add \`sync_file_libdeps.py\` as a pre-build script that mirrors each registered file:// source tree into its libdeps cache by mtime. Skip if PIO hasn't done the first install yet (let it fetch normally). Skip git/build/__pycache__ and .pyc/.o/.a artifacts. Output one "SYNC: <lib>: refreshed N/M files" line per affected dep so the refresh is visible in the build log. Validated: touching ~/repos/microReticulum/src/Identity.cpp triggers \`SYNC: microReticulum: refreshed 1/186 files\` on next \`pio run\`. Steady-state build (no source changes) is silent. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
62 lines
2.1 KiB
Python
62 lines
2.1 KiB
Python
"""
|
|
PlatformIO pre-build: mirror file:// lib_deps from their source trees
|
|
into .pio/libdeps before each build.
|
|
|
|
PlatformIO copies a `file://...` lib_dep into `.pio/libdeps/<env>/<lib>`
|
|
once on first install and never re-syncs even when the source changes.
|
|
That silently masks fixes — `pio run` succeeds and the device flashes,
|
|
but the firmware contains the OLD version of the source. Bit us hard
|
|
on a microReticulum security fix that lived in source for a full test
|
|
session before anyone noticed it hadn't deployed.
|
|
|
|
For each registered file:// dep below, this script rsyncs the source
|
|
tree into the libdep cache, preserving timestamps so the linker sees
|
|
fresh source on every build.
|
|
"""
|
|
Import("env")
|
|
import os
|
|
import shutil
|
|
from pathlib import Path
|
|
|
|
# (source_dir, libdep_subdir_name)
|
|
FILE_DEPS = [
|
|
("~/repos/microReticulum", "microReticulum"),
|
|
]
|
|
|
|
PROJECT_DIR = Path(env.get("PROJECT_DIR", "."))
|
|
ENV_NAME = env.get("PIOENV", "tdeck")
|
|
LIBDEPS_BASE = PROJECT_DIR / ".pio" / "libdeps" / ENV_NAME
|
|
|
|
|
|
def mirror(src: Path, dst: Path):
|
|
if not src.exists():
|
|
print(f"SYNC: {src} missing, skipping")
|
|
return False
|
|
if not dst.exists():
|
|
# Let PIO do the first install; we only refresh after that.
|
|
print(f"SYNC: {dst} not yet installed, skipping (PIO will fetch)")
|
|
return False
|
|
src_files = 0
|
|
copied = 0
|
|
for root, dirs, files in os.walk(src):
|
|
# Skip git, build artifacts.
|
|
dirs[:] = [d for d in dirs if d not in (".git", ".pio", "__pycache__", "build")]
|
|
rel = Path(root).relative_to(src)
|
|
for fn in files:
|
|
if fn.endswith((".pyc", ".o", ".a", ".elf", ".bin")):
|
|
continue
|
|
sp = Path(root) / fn
|
|
dp = dst / rel / fn
|
|
src_files += 1
|
|
if not dp.exists() or sp.stat().st_mtime > dp.stat().st_mtime:
|
|
dp.parent.mkdir(parents=True, exist_ok=True)
|
|
shutil.copy2(sp, dp)
|
|
copied += 1
|
|
if copied > 0:
|
|
print(f"SYNC: {dst.name}: refreshed {copied}/{src_files} files from {src}")
|
|
return True
|
|
|
|
|
|
for src, name in FILE_DEPS:
|
|
mirror(Path(src), LIBDEPS_BASE / name)
|