mirror of
https://github.com/Colorado-Mesh/meshcore-bot-firmware.git
synced 2026-08-11 16:20:29 +00:00
build: enable bot on all companion_radio_(usb|ble) envs
Upstream MeshCore only added ${cmesh_bot_production.build_flags} to
Heltec V3 and RAK 4631 companion envs. Every other companion build
target (~129 envs across 64 boards) compiled without CMESH_BOT_ENABLED,
so the bot code was stripped at preprocessing and the firmware behaved
like stock MeshCore (no replies on #bot).
Caught when a tester reported the Heltec V4 build wouldn't respond to
commands. The fix isn't board-specific -- it applies to every variant
in the release matrix.
Adds scripts/enable-bot-on-companion-envs.py: scans
vendor/MeshCore/variants/*/platformio.ini, finds every
*_companion_radio_(usb|ble) env, injects ${cmesh_bot_production.build_flags}
into its build_flags block (idempotent). Hooks into apply-patches.sh
so every local / CI build picks it up.
Choosing a script over a vendor patch keeps us robust to upstream
adding new boards: we don't have to maintain a per-variant patch.
This commit is contained in:
102
scripts/enable-bot-on-companion-envs.py
Executable file
102
scripts/enable-bot-on-companion-envs.py
Executable file
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Inject ${cmesh_bot_production.build_flags} into every
|
||||
*_companion_radio_(usb|ble) env across vendor/MeshCore/variants/.
|
||||
|
||||
Run after scripts/apply-patches.sh. Idempotent: skips envs that already
|
||||
include the flag.
|
||||
|
||||
Upstream MeshCore only includes cmesh_bot_production in Heltec V3 and
|
||||
RAK 4631 variants. For our release matrix (133 companion envs) we want
|
||||
the bot enabled everywhere, and we don't want to maintain a patch
|
||||
that has to be kept in sync with every new upstream board.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1] / "vendor" / "MeshCore" / "variants"
|
||||
ENV_HEADER = re.compile(r"^\[env:[A-Za-z0-9_-]+_companion_radio_(?:usb|ble)\]\s*$")
|
||||
NEW_SECTION = re.compile(r"^\[")
|
||||
INJECT_LINE = " ${cmesh_bot_production.build_flags}"
|
||||
|
||||
|
||||
def process_file(path: Path) -> int:
|
||||
lines = path.read_text().splitlines()
|
||||
out: list[str] = []
|
||||
i = 0
|
||||
injected = 0
|
||||
while i < len(lines):
|
||||
line = lines[i]
|
||||
if ENV_HEADER.match(line):
|
||||
# Collect this env block until the next [section] header (or EOF).
|
||||
j = i + 1
|
||||
while j < len(lines) and not NEW_SECTION.match(lines[j]):
|
||||
j += 1
|
||||
block = lines[i:j]
|
||||
|
||||
if "${cmesh_bot_production.build_flags}" in "\n".join(block):
|
||||
out.extend(block)
|
||||
else:
|
||||
# Find the last indented continuation line of the build_flags block
|
||||
# so we can append the injection after it.
|
||||
in_flags = False
|
||||
last_flag_idx = -1
|
||||
for k, ln in enumerate(block):
|
||||
stripped = ln.lstrip()
|
||||
if stripped.startswith("build_flags"):
|
||||
in_flags = True
|
||||
last_flag_idx = k
|
||||
elif in_flags:
|
||||
# A continuation line of build_flags must be indented
|
||||
# with whitespace; comments and blanks don't count.
|
||||
if (ln.startswith(" ") or ln.startswith("\t")) and not stripped.startswith(";"):
|
||||
last_flag_idx = k
|
||||
elif ln.startswith(" ") or ln.startswith("\t"):
|
||||
# An indented comment - stays inside the block but doesn't
|
||||
# change the insertion point.
|
||||
pass
|
||||
else:
|
||||
# Hit a non-indented line (likely build_src_filter or lib_deps).
|
||||
in_flags = False
|
||||
if last_flag_idx >= 0:
|
||||
block = block[: last_flag_idx + 1] + [INJECT_LINE] + block[last_flag_idx + 1 :]
|
||||
injected += 1
|
||||
out.extend(block)
|
||||
i = j
|
||||
continue
|
||||
out.append(line)
|
||||
i += 1
|
||||
|
||||
if injected > 0:
|
||||
path.write_text("\n".join(out) + "\n")
|
||||
return injected
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if not ROOT.is_dir():
|
||||
print(f"variants dir not found: {ROOT}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
total = 0
|
||||
files_touched = 0
|
||||
for ini in sorted(ROOT.rglob("platformio.ini")):
|
||||
n = process_file(ini)
|
||||
if n:
|
||||
print(f" + {ini.relative_to(ROOT.parent.parent.parent)}: injected into {n} env(s)")
|
||||
files_touched += 1
|
||||
total += n
|
||||
|
||||
if total == 0:
|
||||
print("All companion_radio_(usb|ble) envs already include cmesh_bot_production.build_flags.")
|
||||
else:
|
||||
print(
|
||||
f"Injected cmesh_bot_production.build_flags into {total} env(s) "
|
||||
f"across {files_touched} variant file(s)."
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user