Files
HaloKeymind/scripts/build_esp32_partition_migration.sh
T

165 lines
5.2 KiB
Bash
Executable File

#!/bin/sh
# Interactive front end for the verified ESP32 in-place migration recipe.
set -eu
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
recipe=$script_dir/build_esp32_partition_migration.py
usage() {
cat <<'EOF'
Usage: scripts/build_esp32_partition_migration.sh [options]
With no arguments, choose one ESP32 board/role or the complete configured
set from a menu. The complete set creates one ZIP per board/role plus a release ZIP.
--board KEY Build one board (repeatable)
--role ROLE Build every repeater, room-server, or sensor board
--all Build all configured repeater, room-server and sensor roles
--version VERSION Firmware version (required without the menu)
--radio-preset NAME Radio preset (required without the menu)
--profile NAME default or cascade (default: cascade)
--jobs N PlatformIO workers within each serial build
--output-root PATH Release output folder
--dry-run Print commands without building
--list-boards Show configured board/role keys
--help Show this help
Boards with unrelated source layout plans are not offered. A name appearing
in an old firmware release is not proof that OTA migration is safe on that
hardware. The bridge checks the live layout, and no release ZIP is published
unless every selected package passes the recipe's checks.
EOF
}
if ! command -v python3 >/dev/null 2>&1; then
echo "python3 is required" >&2
exit 1
fi
version=
radio_preset=
profile=cascade
jobs=
output_root=
boards=
role=
all=0
dry_run=0
interactive=1
while [ "$#" -gt 0 ]; do
interactive=0
case "$1" in
--board|--role|--version|--radio-preset|--profile|--jobs|--output-root)
if [ "$#" -lt 2 ]; then
echo "Missing value for $1" >&2
exit 2
fi
case "$1" in
--board) boards="${boards}${boards:+ }$2" ;;
--role) role=$2 ;;
--version) version=$2 ;;
--radio-preset) radio_preset=$2 ;;
--profile) profile=$2 ;;
--jobs) jobs=$2 ;;
--output-root) output_root=$2 ;;
esac
shift 2 ;;
--all) all=1; shift ;;
--dry-run) dry_run=1; shift ;;
--list-boards) exec python3 -B "$recipe" --list-boards ;;
--help|-h) usage; exit 0 ;;
*) echo "Unknown option: $1" >&2; usage >&2; exit 2 ;;
esac
done
board_keys=$(python3 -B "$recipe" --list-boards)
if [ -z "$board_keys" ]; then
echo "No boards are configured" >&2
exit 1
fi
if [ "$interactive" -eq 1 ]; then
echo "ESP32 in-place partition migration"
echo "Repeater, room-server and sensor recipes are listed."
index=1
for board in $board_keys; do
echo " $index) $board"
index=$((index + 1))
done
echo " a) Build all configured board/role recipes and create a release ZIP"
echo " r) Build all repeaters"
echo " m) Build all room servers"
echo " s) Build all sensors"
echo " q) Quit"
printf 'Choose: '
IFS= read -r choice
case "$choice" in
a|A|all) all=1 ;;
r|R) role=repeater ;;
m|M) role=room-server ;;
s|S) role=sensor ;;
q|Q|quit) exit 0 ;;
*)
index=1
for board in $board_keys; do
if [ "$choice" = "$index" ]; then
boards=$board
break
fi
index=$((index + 1))
done
if [ -z "$boards" ]; then
echo "Invalid selection" >&2
exit 2
fi ;;
esac
printf 'Firmware version: '
IFS= read -r version
printf 'Radio preset [usa-cascadia]: '
IFS= read -r radio_preset
radio_preset=${radio_preset:-usa-cascadia}
printf 'Profile [cascade]: '
IFS= read -r selected_profile
profile=${selected_profile:-cascade}
fi
if { [ "$all" -eq 1 ] && { [ -n "$boards" ] || [ -n "$role" ]; }; } \
|| { [ -n "$boards" ] && [ -n "$role" ]; }; then
echo "Choose only one of --all, --board, or --role" >&2
exit 2
fi
if [ -z "$version" ] || [ -z "$radio_preset" ]; then
echo "Firmware version and radio preset are required" >&2
exit 2
fi
if [ "$profile" != default ] && [ "$profile" != cascade ]; then
echo "Profile must be default or cascade" >&2
exit 2
fi
if [ -n "$role" ] && [ "$role" != repeater ] \
&& [ "$role" != room-server ] && [ "$role" != sensor ]; then
echo "Role must be repeater, room-server, or sensor" >&2
exit 2
fi
set -- "$recipe" --version "$version" --radio-preset "$radio_preset" --profile "$profile"
if [ -n "$boards" ]; then
for board in $boards; do
found=0
for known in $board_keys; do
if [ "$board" = "$known" ]; then found=1; break; fi
done
if [ "$found" -ne 1 ]; then
echo "Board/role is not configured for this recipe: $board" >&2
exit 2
fi
set -- "$@" --board "$board"
done
fi
if [ -n "$role" ]; then set -- "$@" --role "$role"; fi
if [ -n "$jobs" ]; then set -- "$@" --jobs "$jobs"; fi
if [ -n "$output_root" ]; then set -- "$@" --output-root "$output_root"; fi
if [ "$dry_run" -eq 1 ]; then set -- "$@" --dry-run; fi
exec python3 -B "$@"