docs: Add justfile for build automation

This commit is contained in:
2026-02-19 23:10:55 -08:00
parent 66f09c3468
commit 6d51234f21
4 changed files with 183 additions and 5 deletions

177
justfile Normal file
View File

@@ -0,0 +1,177 @@
# Klubhaus Doorbell - justfile
# Run with: just <recipe>
# Set BOARD: just BOARD=esp32-32e-4 compile
# Default recipe - show help
default:
@just --list
# Set default BOARD
BOARD := "esp32-32e-4"
# Helper to source board config
# just passes args as positional, so we source in each recipe
# Compile firmware
compile:
#!/usr/bin/env bash
set -e
source ./boards/{{BOARD}}/board-config.sh
# Only regenerate compile_commands.json if needed (board changed or first run)
NEED_GEN=false
if [ ! -f compile_commands.json ]; then
NEED_GEN=true
elif [ ! -f .board-last ] || [ "$(cat .board-last)" != "{{BOARD}}" ]; then
NEED_GEN=true
fi
if [ "$NEED_GEN" = "true" ]; then
rm -rf /tmp/arduino-build
arduino-cli compile --only-compilation-database --fqbn "$FQBN" --libraries ./libraries $LIBS --build-property "compiler.cpp.extra_flags=$OPTS" --build-path /tmp/arduino-build ./boards/{{BOARD}}
cp /tmp/arduino-build/compile_commands.json .
echo "{{BOARD}}" > .board-last
echo "[OK] Generated compile_commands.json for {{BOARD}}"
else
echo "[SKIP] compile_commands.json already up to date for {{BOARD}}"
fi
arduino-cli compile --fqbn "$FQBN" --libraries ./libraries $LIBS --build-property "compiler.cpp.extra_flags=$OPTS" --warnings default ./boards/{{BOARD}}
# Upload firmware
upload: kill
#!/usr/bin/env bash
set -e
source ./boards/{{BOARD}}/board-config.sh
arduino-cli upload --fqbn "$FQBN" --port "$PORT" ./boards/{{BOARD}}
# Kill processes using serial port
kill:
#!/usr/bin/env bash
set +e
source ./boards/{{BOARD}}/board-config.sh
PORT="${PORT:-$PORT}"
echo "Killing processes on $PORT..."
fuser -k "$PORT" 2>/dev/null || true
for pid in $(pgrep -f "monitor-agent.py.*{{BOARD}}" 2>/dev/null || true); do
echo "Killing monitor-agent.py (PID: $pid)..."
kill "$pid" 2>/dev/null || true
done
rm -f "/tmp/doorbell-{{BOARD}}.lock" 2>/dev/null || true
sleep 1
echo "[OK] Killed processes for {{BOARD}}"
# Monitor raw serial
monitor-raw: kill
#!/usr/bin/env bash
source ./boards/{{BOARD}}/board-config.sh
PORT="${PORT:-$PORT}"
TARGET="$(readlink -f "$PORT" 2>/dev/null || echo "$PORT")"
arduino-cli monitor -p "$TARGET" --config baudrate=115200
# Show tio command
monitor-tio: kill
#!/usr/bin/env bash
source ./boards/{{BOARD}}/board-config.sh
PORT="${PORT:-$PORT}"
TARGET="$(readlink -f "$PORT" 2>/dev/null || echo "$PORT")"
echo "Run: tio --map INLCRNL $TARGET -e"
# Monitor with JSON logging
monitor: kill
#!/usr/bin/env bash
python3 ./scripts/monitor-agent.py "{{BOARD}}" &
# Tail colored logs
watch:
#!/usr/bin/env bash
tail -f "/tmp/doorbell-{{BOARD}}.jsonl" | while read -r line; do
ts=$(echo "$line" | python3 -c "import sys,json; print(json.load(sys.stdin)['ts'])" 2>/dev/null)
txt=$(echo "$line" | python3 -c "import sys,json; print(json.load(sys.stdin)['line'])" 2>/dev/null)
if [[ "$txt" == *"[STATE]"* ]]; then
echo -e "\033[1;35m[$ts]\033[0m $txt"
elif [[ "$txt" == *"[ADMIN]"* ]]; then
echo -e "\033[1;36m[$ts]\033[0m $txt"
elif [[ "$txt" == *"[TOUCH]"* ]]; then
echo -e "\033[1;33m[$ts]\033[0m $txt"
elif [[ "$txt" == *"ALERT"* ]]; then
echo -e "\033[1;31m[$ts]\033[0m $txt"
else
echo "[$ts] $txt"
fi
done
# Send command to device
cmd command:
#!/usr/bin/env bash
echo -n "{{command}}" > "/tmp/doorbell-{{BOARD}}-cmd.fifo"
echo "[SENT] {{command}}"
# Show device state
state:
@cat "/tmp/doorbell-{{BOARD}}-state.json"
# Detect connected board
detect:
#!/usr/bin/env bash
bash ./scripts/detect-device.sh
# Install shared libraries
install-libs-shared:
#!/usr/bin/env bash
./scripts/install-shared.sh
# Install all libraries
install: install-libs-shared
#!/usr/bin/env bash
./boards/{{BOARD}}/install.sh
# Clean build artifacts
clean:
#!/usr/bin/env bash
rm -rf vendor/
rm -rf boards/esp32-32e/build
rm -rf boards/esp32-32e-4/build
rm -rf boards/esp32-s3-lcd-43/build
echo "[OK] Build artifacts cleaned"
# Clean Arduino cache
arduino-clean:
#!/usr/bin/env bash
echo "Checking ~/.arduino15..."
du -sh ~/.arduino15/staging 2>/dev/null || echo "No staging folder"
du -sh ~/.arduino15/packages 2>/dev/null || echo "No packages folder"
read -p "Delete staging + packages folders? [y/N] " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
rm -rf ~/.arduino15/staging
rm -rf ~/.arduino15/packages
echo "[OK] Arduino staging + packages cleared"
else
echo "Aborted"
fi
# Format code
format:
#!/usr/bin/env bash
clang-format -i --style=file \
boards/esp32-32e/*.cpp \
boards/esp32-32e/*.h \
boards/esp32-32e/*.ino \
boards/esp32-32e-4/*.cpp \
boards/esp32-32e-4/*.h \
boards/esp32-32e-4/*.ino \
boards/esp32-s3-lcd-43/*.cpp \
boards/esp32-s3-lcd-43/*.h \
boards/esp32-s3-lcd-43/*.ino \
libraries/KlubhausCore/src/*.cpp \
libraries/KlubhausCore/src/*.h \
libraries/KlubhausCore/*.properties
# Generate crush config
gen-crush-config:
#!/usr/bin/env bash
set -e
source ./boards/{{BOARD}}/board-config.sh
printf '{\n "lsp": {\n "arduino": {\n "command": "arduino-language-server",\n "args": ["-fqbn", "%s"]\n },\n "cpp": {\n "command": "clangd"\n }\n }\n}\n' "$FQBN" > .crush.json
echo "[OK] Generated .crush.json with FQBN: $FQBN"