PORT := 8002 PIDFILE := var/api.pid LOGFILE := var/api-8002.log UVICORN := .venv/bin/uvicorn HEALTH_URL := http://127.0.0.1:$(PORT)/health .DEFAULT_GOAL := help .PHONY: help start stop restart status showlogs help: ## List available targets @grep -E '^[a-zA-Z_-]+:.*?## ' $(MAKEFILE_LIST) | \ awk 'BEGIN {FS = ":.*?## "}; {printf " %-12s %s\n", $$1, $$2}' start: ## Start the API server in the background on port 8002 @mkdir -p var @if [ -f $(PIDFILE) ] && kill -0 $$(cat $(PIDFILE)) 2>/dev/null; then \ echo "Already running (PID $$(cat $(PIDFILE)))"; \ else \ setsid sh -c 'echo $$$$ > $(PIDFILE); exec $(UVICORN) repo_scoping.web_api.app:app --host 127.0.0.1 --port $(PORT)' \ >> $(LOGFILE) 2>&1 & \ PID=""; \ for i in $$(seq 1 50); do \ if [ -f $(PIDFILE) ]; then PID=$$(cat $(PIDFILE)); fi; \ if [ -n "$$PID" ] && ! kill -0 $$PID 2>/dev/null; then break; fi; \ if [ -n "$$PID" ] && curl -fsS $(HEALTH_URL) >/dev/null 2>&1; then \ echo "Started (PID $$PID) — http://127.0.0.1:$(PORT)/ui"; \ exit 0; \ fi; \ sleep 0.1; \ done; \ rm -f $(PIDFILE); \ echo "Failed to start API server on http://127.0.0.1:$(PORT)/ui"; \ echo "Recent log output:"; \ tail -40 $(LOGFILE) 2>/dev/null || true; \ exit 1; \ fi stop: ## Stop the API server @PIDS=""; \ if [ -f $(PIDFILE) ]; then \ FILE_PID=$$(cat $(PIDFILE)); \ if kill -0 $$FILE_PID 2>/dev/null; then \ PIDS="$$FILE_PID"; \ fi; \ rm -f $(PIDFILE); \ fi; \ FOUND=$$(ss -tlnp 2>/dev/null | awk '/127\.0\.0\.1:$(PORT)/{match($$0,/pid=([0-9]+)/,m); if(m[1]) print m[1]}'); \ for p in $$FOUND; do \ case " $$PIDS " in *" $$p "*) ;; *) PIDS="$$PIDS $$p" ;; esac; \ done; \ PIDS=$$(echo $$PIDS | tr -s ' ' | sed 's/^ //;s/ $$//'); \ if [ -z "$$PIDS" ]; then \ echo "Not running"; \ else \ for p in $$PIDS; do kill $$p 2>/dev/null && echo "Stopped PID $$p"; done; \ fi restart: stop start ## Restart the API server status: ## Show whether the API server is running and its resource usage @PID=""; \ if [ -f $(PIDFILE) ]; then \ CANDIDATE=$$(cat $(PIDFILE)); \ kill -0 $$CANDIDATE 2>/dev/null && PID=$$CANDIDATE; \ fi; \ if [ -z "$$PID" ]; then \ FOUND=$$(ss -tlnp 2>/dev/null | awk '/127\.0\.0\.1:$(PORT)/{match($$0,/pid=([0-9]+)/,m); if(m[1]) print m[1]}' | head -1); \ [ -n "$$FOUND" ] && PID=$$FOUND; \ fi; \ if [ -z "$$PID" ]; then \ echo "Status: stopped"; \ echo "URL: http://127.0.0.1:$(PORT)/ui"; \ echo "Log: $(LOGFILE)"; \ else \ START=$$(ps -o lstart= -p $$PID 2>/dev/null | sed 's/^ *//'); \ CPU=$$(ps -o %cpu= -p $$PID 2>/dev/null | tr -d ' '); \ MEM=$$(ps -o %mem= -p $$PID 2>/dev/null | tr -d ' '); \ RSS=$$(ps -o rss= -p $$PID 2>/dev/null | tr -d ' '); \ RSS_MB=$$(( $${RSS:-0} / 1024 )); \ echo "Status: running"; \ echo "PID: $$PID"; \ echo "Since: $$START"; \ echo "CPU: $${CPU}%"; \ echo "Memory: $${MEM}% ($$RSS_MB MB RSS)"; \ echo "URL: http://127.0.0.1:$(PORT)/ui"; \ echo "Log: $(LOGFILE)"; \ fi showlogs: ## Tail the API server log @tail -f $(LOGFILE)