Files
pyxis/sync_file_libdeps.py
torlando-agent[bot] dfc6a14f00 address greptile #38: fix standalone-exec test, drop dead var, clarify docstring, DRY hostname
- test_patch_nimble.py: the refactor made the script import its sibling
  _build_helpers; the standalone-exec test ran it with a temp PROJECT_DIR, so add
  the script's real directory to the shim's sys.path (CI pytest failure fix).
- sync_file_libdeps.py: remove the now-dead ENV_NAME binding.
- _build_helpers.py: reword the docstring (the "never literal env" line conflicted
  with the helper's own "tdeck" fallback) and note inline that "tdeck" is a
  never-hit default (PlatformIO always injects PIOENV).
- main.cpp: DRY the OTA hostname into OTA_HOSTNAME used by both setHostname() and
  the log line.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UWZuYkHBRqNb6BZHV8sTG5
2026-06-23 00:11:54 -04:00

71 lines
2.7 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 sys
import shutil
from pathlib import Path
sys.path.insert(0, env.get("PROJECT_DIR", "."))
from _build_helpers import env_libdeps_dir # per-env libdeps path; never hardcode the env
# (source_dir, libdep_subdir_name) — populated from env vars so the
# script doesn't bake any contributor's local checkout path into the
# committed source. Since microReticulum is now consumed as a pinned
# git URL in platformio.ini (not a file:// dep), this script no-ops
# for everyone by default. Set PYXIS_MICRORETICULUM_DIR to opt in to
# a local-override workflow (mirrors that source tree into
# .pio/libdeps/<env>/microReticulum on each build).
FILE_DEPS = []
_micro_reticulum_dir = os.environ.get("PYXIS_MICRORETICULUM_DIR", "").strip()
if _micro_reticulum_dir:
FILE_DEPS.append((_micro_reticulum_dir, "microReticulum"))
PROJECT_DIR = Path(env.get("PROJECT_DIR", "."))
LIBDEPS_BASE = Path(env_libdeps_dir(env))
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)