|
| 1 | +# Target vocabulary (build-server / start-server / wait-for-server / stop-server) |
| 2 | +# matches the commons TestServer orchestration. Recipes are single shell lines |
| 3 | +# for the 3.81 Make that ships with macOS. |
| 4 | + |
| 5 | +SHELL := bash |
| 6 | + |
| 7 | +# Port for the server (override: make run-server PORT=9090). |
| 8 | +PORT ?= 8095 |
| 9 | + |
| 10 | +PID_FILE := .server.pid |
| 11 | +LOG_FILE := .server.log |
| 12 | + |
| 13 | +# Bootstrap-then-delegate coordinates for `make test-server`. The commons |
| 14 | +# repository coordinates live in commons-configuration.json next to this |
| 15 | +# Makefile; COMMONS_BRANCH overrides the configured branch at invocation time. |
| 16 | +MAKEFILE_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) |
| 17 | +REPO_ROOT := $(abspath $(MAKEFILE_DIR)/..) |
| 18 | +COMMONS_CONFIGURATION := $(MAKEFILE_DIR)/commons-configuration.json |
| 19 | +COMMONS_BRANCH ?= |
| 20 | +CLONE_DIR ?= $(MAKEFILE_DIR)/.commons-clone |
| 21 | +CLONE_ORCH_DIR := $(CLONE_DIR)/esdk/test-server/orchestrator |
| 22 | + |
| 23 | +.PHONY: help build-server run-server start-server wait-for-server stop-server \ |
| 24 | + test test-server check-java clean |
| 25 | + |
| 26 | +help: ## Show this help |
| 27 | + @echo "ESDK TestServer (Node.js) — make targets" |
| 28 | + @grep -E '^[a-zA-Z0-9_-]+:.*## ' "$(lastword $(MAKEFILE_LIST))" \ |
| 29 | + | sort | awk 'BEGIN{FS=":.*## "}{printf " %-18s %s\n", $$1, $$2}' |
| 30 | + @echo "" |
| 31 | + @echo " PORT=$(PORT)" |
| 32 | + |
| 33 | +build-server: ## Install repo deps (if needed), build the modules, compile the server |
| 34 | + @if [ ! -d "$(REPO_ROOT)/node_modules" ]; then cd "$(REPO_ROOT)" && npm ci --unsafe-perm; fi |
| 35 | + cd "$(REPO_ROOT)" && npm run build-node |
| 36 | + cd "$(MAKEFILE_DIR)" && npx tsc -p tsconfig.json |
| 37 | + |
| 38 | +run-server: build-server ## Run the server in the FOREGROUND on PORT (Ctrl-C to stop) |
| 39 | + node "$(MAKEFILE_DIR)/build/src/main.js" $(PORT) |
| 40 | + |
| 41 | +start-server: build-server ## Start the server in the BACKGROUND on PORT (writes .server.pid) |
| 42 | + @node "$(MAKEFILE_DIR)/build/src/main.js" $(PORT) >"$(LOG_FILE)" 2>&1 & echo $$! >"$(PID_FILE)"; \ |
| 43 | + echo "started esdk-test-server (pid $$(cat $(PID_FILE))) on port $(PORT)" |
| 44 | + |
| 45 | +wait-for-server: ## Block until the server accepts connections on PORT (120s timeout) |
| 46 | + @for i in $$(seq 1 120); do \ |
| 47 | + if node -e 'const s=require("net").connect($(PORT),"127.0.0.1");s.on("connect",()=>{s.end();process.exit(0)});s.on("error",()=>process.exit(1))'; then \ |
| 48 | + echo "server ready on $(PORT)"; exit 0; \ |
| 49 | + fi; \ |
| 50 | + sleep 1; \ |
| 51 | + done; \ |
| 52 | + echo "timed out waiting for port $(PORT)"; [ -f "$(LOG_FILE)" ] && tail -n 40 "$(LOG_FILE)"; exit 1 |
| 53 | + |
| 54 | +stop-server: ## Stop the background server and free PORT |
| 55 | + @if [ -f "$(PID_FILE)" ]; then kill "$$(cat $(PID_FILE))" 2>/dev/null || true; rm -f "$(PID_FILE)"; fi; \ |
| 56 | + pids=$$(lsof -ti tcp:$(PORT) 2>/dev/null || true); \ |
| 57 | + if [ -n "$$pids" ]; then kill $$pids 2>/dev/null || true; fi; \ |
| 58 | + echo "stopped server on port $(PORT)" |
| 59 | + |
| 60 | +test: build-server ## Run the server's unit/protocol tests (no AWS credentials) |
| 61 | + cd "$(MAKEFILE_DIR)" && npm test |
| 62 | + |
| 63 | +check-java: ## Verify JAVA_HOME points at a JDK 21+ (the commons orchestrator needs it) |
| 64 | + @if [ -z "$$JAVA_HOME" ] || [ ! -x "$$JAVA_HOME/bin/java" ]; then \ |
| 65 | + echo "ERROR: JAVA_HOME must point at a JDK 21+ for the commons orchestrator." >&2; exit 1; \ |
| 66 | + fi; \ |
| 67 | + v=$$("$$JAVA_HOME/bin/java" -version 2>&1 | grep -i version | head -1 | sed -E 's/.*version .?([0-9]+).*/\1/'); \ |
| 68 | + if [ -z "$$v" ] || [ "$$v" -lt 21 ] 2>/dev/null; then \ |
| 69 | + echo "ERROR: JDK 21+ required, JAVA_HOME has major version '$$v'." >&2; exit 1; \ |
| 70 | + fi |
| 71 | + |
| 72 | +# Bootstrap-then-delegate (the single orchestrated entry point): parse the |
| 73 | +# commons coordinates, clone commons at the branch head, and run the |
| 74 | +# orchestrator core in the clone with this working tree as the live JavaScript |
| 75 | +# library + server source. The core builds and launches every configured |
| 76 | +# Language_Server, runs the full Tests matrix, and tears down; its exit code |
| 77 | +# propagates. Needs AWS credentials and a JDK 21+. |
| 78 | +test-server: check-java ## Run the complete cross-language TestServer via the commons orchestrator; COMMONS_BRANCH=<b> overrides |
| 79 | + @set -eo pipefail; \ |
| 80 | + if ! coords=$$(python3 -c 'import json,sys; c=json.load(open(sys.argv[1]))["commonsRepository"]; print(c["url"]); print(c["branch"])' "$(COMMONS_CONFIGURATION)" 2>/dev/null); then \ |
| 81 | + echo "ERROR: missing or unparseable $(COMMONS_CONFIGURATION); halting before any clone." >&2; exit 1; \ |
| 82 | + fi; \ |
| 83 | + { read -r url; read -r branch; } <<< "$$coords"; \ |
| 84 | + if [ -n "$(strip $(COMMONS_BRANCH))" ]; then branch="$(strip $(COMMONS_BRANCH))"; reason="invocation-override"; else reason="configuration-entry"; fi; \ |
| 85 | + echo "==> Cloning commons at '$$branch' ($$reason) into $(CLONE_DIR)"; \ |
| 86 | + rm -rf "$(CLONE_DIR)"; \ |
| 87 | + if ! git clone --depth 1 --single-branch --branch "$$branch" "$$url" "$(CLONE_DIR)"; then \ |
| 88 | + echo "ERROR: failed to clone $$url at branch $$branch; no Tests will run." >&2; exit 1; \ |
| 89 | + fi; \ |
| 90 | + if [ ! -d "$(CLONE_ORCH_DIR)" ]; then \ |
| 91 | + echo "ERROR: branch $$branch of $$url has no orchestrator at esdk/test-server/orchestrator." >&2; exit 1; \ |
| 92 | + fi; \ |
| 93 | + echo "==> Delegating: context=language:javascript languageRepoRoot=$(REPO_ROOT)"; \ |
| 94 | + cd "$(CLONE_ORCH_DIR)" && ./gradlew --console=plain run \ |
| 95 | + --args="context=language:javascript languageRepoRoot=$(REPO_ROOT) commonsOrigin.url=$$url commonsOrigin.branch=$$branch commonsOrigin.reason=$$reason" |
| 96 | + |
| 97 | +clean: ## Remove build output, server scratch files, and the commons clone |
| 98 | + rm -rf "$(MAKEFILE_DIR)/build" "$(PID_FILE)" "$(LOG_FILE)" "$(CLONE_DIR)" |
0 commit comments