LazyBoy2/Makefile

245 lines
6.0 KiB
Makefile
Raw Normal View History

2026-09-15 05:20:44 +00:00
# Local process control for LazyBoy.
2026-09-15 03:20:42 +00:00
# make start API :8787 + Vite :5173
# make stop
# make restart
.DEFAULT_GOAL := help
ROOT := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
RUNDIR := $(ROOT)/.run
2026-09-15 05:20:44 +00:00
BIN := $(ROOT)/target/debug/lazyboy
2026-09-15 03:20:42 +00:00
WEBDIR := $(ROOT)/web
PORT_API ?= 8787
PORT_WEB ?= 5173
PID_SERVE := $(RUNDIR)/serve.pid
PID_WEB := $(RUNDIR)/web.pid
LOG_SERVE := $(RUNDIR)/serve.log
LOG_WEB := $(RUNDIR)/web.log
2026-09-16 06:40:00 +00:00
.PHONY: help start stop restart status logs prepare-ui start-serve start-web stop-serve stop-web
2026-09-15 03:20:42 +00:00
# Shared POSIX helpers. Sourced by each recipe.
define CTL
alive() {
pidfile="$$1"
[ -f "$$pidfile" ] || return 1
pid=$$(cat "$$pidfile")
[ -n "$$pid" ] && kill -0 "$$pid" 2>/dev/null
}
kill_tree() {
pid="$$1"
[ -n "$$pid" ] || return 0
for child in $$(pgrep -P "$$pid" 2>/dev/null); do
kill_tree "$$child"
done
kill -TERM "$$pid" 2>/dev/null || true
}
kill_tree_hard() {
pid="$$1"
[ -n "$$pid" ] || return 0
for child in $$(pgrep -P "$$pid" 2>/dev/null); do
kill_tree_hard "$$child"
done
kill -KILL "$$pid" 2>/dev/null || true
}
free_port() {
port="$$1"
extra=$$(lsof -nP -tiTCP:"$$port" -sTCP:LISTEN 2>/dev/null || true)
[ -n "$$extra" ] || return 0
echo "freeing :$$port ($$extra)"
kill -TERM $$extra 2>/dev/null || true
sleep 0.2
extra=$$(lsof -nP -tiTCP:"$$port" -sTCP:LISTEN 2>/dev/null || true)
[ -n "$$extra" ] && kill -KILL $$extra 2>/dev/null || true
}
stop_one() {
name="$$1"
pidfile="$$2"
port="$$3"
if alive "$$pidfile"; then
pid=$$(cat "$$pidfile")
echo "stopping $$name pid=$$pid"
kill_tree "$$pid"
n=0
while [ $$n -lt 15 ] && kill -0 "$$pid" 2>/dev/null; do
sleep 0.2
n=$$((n + 1))
done
kill_tree_hard "$$pid"
elif [ -f "$$pidfile" ]; then
echo "$$name not running (stale pidfile)"
else
echo "$$name not running"
fi
rm -f "$$pidfile"
free_port "$$port"
}
wait_alive() {
pidfile="$$1"
name="$$2"
log="$$3"
i=0
while [ $$i -lt 15 ]; do
if alive "$$pidfile"; then
return 0
fi
sleep 0.1
i=$$((i + 1))
done
echo "$$name exited immediately. Last log:"
tail -n 40 "$$log" 2>/dev/null || true
rm -f "$$pidfile"
return 1
}
wait_listen() {
pidfile="$$1"
port="$$2"
name="$$3"
log="$$4"
i=0
while [ $$i -lt 50 ]; do
if lsof -nP -iTCP:"$$port" -sTCP:LISTEN >/dev/null 2>&1; then
return 0
fi
if [ -f "$$pidfile" ]; then
pid=$$(cat "$$pidfile")
if [ -n "$$pid" ] && ! kill -0 "$$pid" 2>/dev/null; then
echo "$$name died before listening on :$$port. Last log:"
tail -n 40 "$$log" 2>/dev/null || true
rm -f "$$pidfile"
return 1
fi
fi
sleep 0.2
i=$$((i + 1))
done
echo "$$name did not listen on :$$port. Last log:"
tail -n 40 "$$log" 2>/dev/null || true
return 1
}
status_one() {
name="$$1"
pidfile="$$2"
port="$$3"
if alive "$$pidfile"; then
pid=$$(cat "$$pidfile")
listen=no
lsof -nP -iTCP:"$$port" -sTCP:LISTEN >/dev/null 2>&1 && listen=yes
echo "$$name running pid=$$pid :$$port listen=$$listen"
elif [ -f "$$pidfile" ]; then
echo "$$name stopped (stale pidfile)"
else
echo "$$name stopped"
fi
}
load_env() {
if [ -f "$(ROOT)/.env" ]; then
set -a
. "$(ROOT)/.env"
set +a
fi
}
endef
export CTL
help:
@echo "make start Start API (:$(PORT_API)) and frontend (:$(PORT_WEB))"
@echo "make stop Stop both"
@echo "make restart Stop then start"
@echo "make status Show PIDs and ports"
@echo "make logs Tail both logs (Ctrl-C to leave)"
2026-09-16 06:40:00 +00:00
start: prepare-ui start-serve start-web
2026-09-15 03:20:42 +00:00
@echo
@echo "API http://127.0.0.1:$(PORT_API)"
@echo "UI http://127.0.0.1:$(PORT_WEB)"
2026-09-16 06:40:00 +00:00
@lan=$$(hostname -I 2>/dev/null | awk '{print $$1}'); \
if [ -n "$$lan" ]; then \
echo "Phone http://$$lan:$(PORT_API)"; \
fi
2026-09-15 03:20:42 +00:00
restart: stop
@$(MAKE) start
stop: stop-web stop-serve
@echo "stopped"
status:
@eval "$$CTL"; \
status_one serve "$(PID_SERVE)" "$(PORT_API)"; \
status_one web "$(PID_WEB)" "$(PORT_WEB)"
logs:
@mkdir -p "$(RUNDIR)"
@touch "$(LOG_SERVE)" "$(LOG_WEB)"
@echo "=== serve $(LOG_SERVE) ==="
@echo "=== web $(LOG_WEB) ==="
@tail -f "$(LOG_SERVE)" "$(LOG_WEB)"
2026-09-16 06:40:00 +00:00
prepare-ui:
@if [ ! -d "$(WEBDIR)/node_modules" ]; then \
echo "npm install…"; \
(cd "$(WEBDIR)" && npm install) || exit 1; \
fi
@if [ ! -f "$(WEBDIR)/dist/index.html" ]; then \
echo "building web UI (once, so :$(PORT_API) serves the app)…"; \
(cd "$(WEBDIR)" && npm run build) || exit 1; \
fi
2026-09-15 03:20:42 +00:00
start-serve:
@mkdir -p "$(RUNDIR)"
@eval "$$CTL"; \
if alive "$(PID_SERVE)"; then \
2026-09-16 06:40:00 +00:00
fmt=$$(cat "$$HOME/.lazyboy/certs/format" 2>/dev/null || true); \
if [ "$$fmt" = "2" ]; then \
echo "serve already running pid=$$(cat "$(PID_SERVE)")"; \
exit 0; \
fi; \
echo "TLS certs need reissue; restarting serve"; \
stop_one serve "$(PID_SERVE)" "$(PORT_API)"; \
2026-09-15 03:20:42 +00:00
fi; \
2026-09-15 05:20:44 +00:00
echo "building lazyboy…"; \
cargo build -p lazyboy || exit 1; \
2026-09-15 03:20:42 +00:00
load_env; \
2026-09-15 05:20:44 +00:00
LAZYBOY_WEB_PORT="$(PORT_API)" nohup "$(BIN)" serve > "$(LOG_SERVE)" 2>&1 & echo $$! > "$(PID_SERVE)"; \
2026-09-15 03:20:42 +00:00
wait_alive "$(PID_SERVE)" serve "$(LOG_SERVE)" || exit 1; \
wait_listen "$(PID_SERVE)" "$(PORT_API)" serve "$(LOG_SERVE)" || exit 1; \
echo "started serve pid=$$(cat "$(PID_SERVE)") :$(PORT_API) log=$(LOG_SERVE)"
start-web:
@mkdir -p "$(RUNDIR)"
@eval "$$CTL"; \
if alive "$(PID_WEB)"; then \
2026-09-16 06:40:00 +00:00
if lsof -nP -iTCP:"$(PORT_WEB)" -sTCP:LISTEN 2>/dev/null | grep -q '127.0.0.1:$(PORT_WEB)'; then \
echo "web is localhost-only; restarting so the phone can connect"; \
stop_one web "$(PID_WEB)" "$(PORT_WEB)"; \
else \
echo "web already running pid=$$(cat "$(PID_WEB)")"; \
exit 0; \
fi; \
2026-09-15 03:20:42 +00:00
fi; \
if [ ! -d "$(WEBDIR)/node_modules" ]; then \
echo "npm install…"; \
(cd "$(WEBDIR)" && npm install) || exit 1; \
fi; \
2026-09-16 06:40:00 +00:00
nohup npm --prefix "$(WEBDIR)" run dev -- --host 0.0.0.0 --port "$(PORT_WEB)" > "$(LOG_WEB)" 2>&1 & echo $$! > "$(PID_WEB)"; \
2026-09-15 03:20:42 +00:00
wait_alive "$(PID_WEB)" web "$(LOG_WEB)" || exit 1; \
wait_listen "$(PID_WEB)" "$(PORT_WEB)" web "$(LOG_WEB)" || exit 1; \
echo "started web pid=$$(cat "$(PID_WEB)") :$(PORT_WEB) log=$(LOG_WEB)"
stop-serve:
@eval "$$CTL"; stop_one serve "$(PID_SERVE)" "$(PORT_API)"
stop-web:
@eval "$$CTL"; stop_one web "$(PID_WEB)" "$(PORT_WEB)"