version: '3' vars: # Engine-specific names to avoid overriding the root Taskfile's FIND_FREE_PORT_* # vars (Task merges included-file vars into the global scope). # Paths are relative to the engine/ include dir. ENGINE_FIND_FREE_PORT_SH: "bash ../scripts/find-free-port.sh" ENGINE_FIND_FREE_PORT_PS: "powershell -NoProfile -File ../scripts/find-free-port.ps1" tasks: install: desc: "Install engine dependencies" run: once cmds: - uv python install 3.13.8 - uv sync sources: - uv.lock - pyproject.toml status: - test -d .venv prepare: desc: "Set up engine .env from template" deps: [install] cmds: - uv run scripts/setup_env.py sources: - scripts/setup_env.py generates: - .env.local run: desc: "Run engine server" deps: [prepare] ignore_error: true dir: src vars: # When PORT is provided (e.g. from dev:all), use it directly. # With ENGINE_PORT_PROBE=false (Docker), use the fixed STIRLING_ENGINE_PORT # (default 5001) without probing. Otherwise probe for a free port from 5001. PORT: sh: | if [ -n "{{.PORT}}" ]; then echo "{{.PORT}}" elif [ -f /.dockerenv ] || [ "${ENGINE_PORT_PROBE:-true}" = "false" ]; then # Never probe in a container: the port is fixed and the probe script # isn't shipped in the image. /.dockerenv auto-detects Docker; the # ENGINE_PORT_PROBE=false flag forces fixed-port mode anywhere else. # The probe is a dev-only convenience for avoiding local port clashes. echo "${STIRLING_ENGINE_PORT:-5001}" elif [ "{{OS}}" = "windows" ]; then {{.ENGINE_FIND_FREE_PORT_PS}} 5001 else {{.ENGINE_FIND_FREE_PORT_SH}} 5001 fi env: PYTHONUNBUFFERED: "1" cmds: - uv run uvicorn stirling.api.app:app --host 0.0.0.0 --port {{.PORT}} --workers "${STIRLING_ENGINE_WORKERS:-4}" dev: desc: "Start engine dev server with hot reload" deps: [prepare] ignore_error: true dir: src vars: # When PORT is provided (e.g. from dev:all), use it directly. # With ENGINE_PORT_PROBE=false (Docker), use the fixed STIRLING_ENGINE_PORT # (default 5001) without probing. Otherwise probe for a free port from 5001. PORT: sh: | if [ -n "{{.PORT}}" ]; then echo "{{.PORT}}" elif [ -f /.dockerenv ] || [ "${ENGINE_PORT_PROBE:-true}" = "false" ]; then # Never probe in a container: the port is fixed and the probe script # isn't shipped in the image. /.dockerenv auto-detects Docker; the # ENGINE_PORT_PROBE=false flag forces fixed-port mode anywhere else. # The probe is a dev-only convenience for avoiding local port clashes. echo "${STIRLING_ENGINE_PORT:-5001}" elif [ "{{OS}}" = "windows" ]; then {{.ENGINE_FIND_FREE_PORT_PS}} 5001 else {{.ENGINE_FIND_FREE_PORT_SH}} 5001 fi env: PYTHONUNBUFFERED: "1" cmds: - uv run uvicorn stirling.api.app:app --host 0.0.0.0 --port {{.PORT}} --reload lint: desc: "Run linting" deps: [install] cmds: - uv run ruff check . lint:fix: desc: "Auto-fix lint issues" deps: [install] cmds: - uv run ruff check . --fix format: desc: "Auto-fix code formatting" deps: [install] cmds: - uv run ruff format . format:check: desc: "Check code formatting" deps: [install] cmds: - uv run ruff format . --diff typecheck: desc: "Run type checking" deps: [install] cmds: - uv run pyright . --warnings test: desc: "Run tests" deps: [prepare] cmds: - uv run pytest tests fix: desc: "Auto-fix lint + format" cmds: - task: format # Can auto-fix some things that `lint:fix` can't like line length violations - task: lint:fix - task: format # Ensure that after lint fixing that the code is still formatted correctly check: desc: "Full engine quality gate" cmds: - task: typecheck - task: lint - task: format:check - task: test tool-models: desc: "Generate tool_models.py from Java OpenAPI spec (SwaggerDoc.json)" deps: [install, ":backend:swagger"] cmds: - uv run python scripts/generate_tool_models.py --spec ../SwaggerDoc.json --output src/stirling/models/tool_models.py sources: - ../SwaggerDoc.json - scripts/generate_tool_models.py generates: - src/stirling/models/tool_models.py clean: desc: "Clean build artifacts" cmds: - task: '{{if eq .OS "Windows_NT"}}clean-windows{{else}}clean-unix{{end}}' clean-unix: internal: true desc: "Clean build artifacts" cmds: - rm -rf .venv data logs output # On Windows, use PowerShell as bash failed to delete some dependencies clean-windows: internal: true desc: "Clean build artifacts" ignore_error: true cmds: - powershell rm -Recurse -Force -ErrorAction SilentlyContinue .venv - powershell rm -Recurse -Force -ErrorAction SilentlyContinue data - powershell rm -Recurse -Force -ErrorAction SilentlyContinue logs - powershell rm -Recurse -Force -ErrorAction SilentlyContinue output