GO_DIR := go PY_DIR := python BINARY := latprobe PYTHON := python3.14 ARGS ?= SITES ?= $(PY_DIR)/sites.txt # hxprobe is a fully standalone project (own pyproject.toml, own uv-managed # venv/lockfile) — it imports nothing from python/latprobe, and could be # `cp -r`'d into its own repo as-is. HX_DIR := hxprobe .DEFAULT_GOAL := help # ── help ────────────────────────────────────────────────────────────────────── .PHONY: help help: ## Show this help @grep -E '^[a-zA-Z_-]+:.*##' $(MAKEFILE_LIST) \ | awk 'BEGIN {FS = ":.*##"}; {printf " \033[36m%-20s\033[0m %s\n", $$1, $$2}' \ | sort # ── umbrella targets (delegate to Go now; py-* will be added during Python port) ── .PHONY: all all: check build ## Run checks then build .PHONY: build build: go-build ## Build binary (delegates to go-build) .PHONY: test test: go-test py-test hx-test ## Run all tests (Go + Python + hxprobe) .PHONY: check check: go-check py-check hx-check ## Run fmt + vet + test gate (Go + Python + hxprobe) .PHONY: fmt fmt: go-fmt ## Format source code (delegates to go-fmt) .PHONY: vet vet: go-vet ## Run go vet (delegates to go-vet) .PHONY: clean clean: go-clean py-clean hx-clean ## Remove build and coverage artifacts # ── Go targets ──────────────────────────────────────────────────────────────── .PHONY: go-build go-build: ## go: build binary → go/latprobe go -C $(GO_DIR) build -o $(BINARY) . .PHONY: go-run go-run: ## go: build and run (pass flags via ARGS="…") go -C $(GO_DIR) run . $(ARGS) .PHONY: go-test go-test: ## go: run all tests go -C $(GO_DIR) test ./... .PHONY: go-test-verbose go-test-verbose: ## go: run all tests with per-case output go -C $(GO_DIR) test -v ./... .PHONY: go-test-race go-test-race: ## go: run tests with the race detector enabled go -C $(GO_DIR) test -race ./... .PHONY: go-check go-check: go-fmt go-vet go-test ## go: fmt + vet + test (pre-commit gate) .PHONY: go-cover go-cover: ## go: run tests with coverage → go/coverage.html go -C $(GO_DIR) test -coverprofile=coverage.out ./... go -C $(GO_DIR) tool cover -html=coverage.out -o coverage.html @echo "Coverage report: $(GO_DIR)/coverage.html" .PHONY: go-fmt go-fmt: ## go: format all Go source files with gofmt gofmt -w $(GO_DIR) .PHONY: go-vet go-vet: ## go: run go vet on all packages go -C $(GO_DIR) vet ./... .PHONY: go-tidy go-tidy: ## go: run go mod tidy go -C $(GO_DIR) mod tidy .PHONY: go-install go-install: ## go: install binary to $GOBIN / $GOPATH/bin go -C $(GO_DIR) install . .PHONY: go-lint go-lint: ## go: run golangci-lint (must be installed) @command -v golangci-lint >/dev/null 2>&1 || { \ echo "golangci-lint not installed — see https://golangci-lint.run/usage/install/"; \ exit 1; \ } cd $(GO_DIR) && golangci-lint run .PHONY: go-clean go-clean: ## go: remove binary and coverage artifacts rm -f $(GO_DIR)/$(BINARY) $(GO_DIR)/coverage.out $(GO_DIR)/coverage.html # ── Python targets ──────────────────────────────────────────────────────────── .PHONY: py-simple-run py-simple-run: ## py: run simple.py (pass config via SITES=path/to/sites.txt) $(PYTHON) $(PY_DIR)/simple.py $(SITES) .PHONY: py-phases-run py-phases-run: ## py: run phases.py (pass URLs via ARGS="url …" or SITES=path) $(PYTHON) $(PY_DIR)/phases.py $(if $(ARGS),$(ARGS),$(SITES)) .PHONY: py-run py-run: ## py: run the full latprobe package (pass flags via ARGS="…") cd $(PY_DIR) && $(PYTHON) -m latprobe $(ARGS) .PHONY: py-test py-test: ## py: run Python unit tests (local, hermetic) PYTHONPATH=$(PY_DIR) $(PYTHON) -m unittest discover -s $(PY_DIR)/tests -p 'test_[!i]*.py' -v $(ARGS) .PHONY: py-test-integration py-test-integration: ## py: run integration tests against live internet services (~30 s) PYTHONPATH=$(PY_DIR) $(PYTHON) -m unittest discover -s $(PY_DIR)/tests -p 'test_integration.py' -v $(ARGS) .PHONY: py-check py-check: py-test ## py: run Python test gate (hermetic only) .PHONY: py-clean py-clean: ## py: remove Python bytecode and __pycache__ dirs @find $(PY_DIR) -type d -name '__pycache__' -exec rm -rf {} + 2>/dev/null; \ find $(PY_DIR) -name '*.pyc' -delete 2>/dev/null; true # ── hxprobe (standalone httpx-based probe; own pyproject.toml/uv.lock, no # imports from python/latprobe — see hxprobe/pyproject.toml) ───────────────── .PHONY: hx-deps hx-deps: ## hx: sync hxprobe's uv-managed environment from its lockfile; idempotent cd $(HX_DIR) && uv sync .PHONY: hx-run hx-run: hx-deps ## hx: run hxprobe (pass flags via ARGS="…") cd $(HX_DIR) && uv run python -m hxprobe $(ARGS) .PHONY: hx-lint hx-lint: hx-deps ## hx: lint hxprobe with ruff cd $(HX_DIR) && uv run ruff check . .PHONY: hx-fmt hx-fmt: hx-deps ## hx: format hxprobe with ruff cd $(HX_DIR) && uv run ruff format . .PHONY: hx-test hx-test: hx-deps ## hx: run hxprobe unit tests (hermetic) cd $(HX_DIR) && uv run pytest tests -m "not integration" -v $(ARGS) .PHONY: hx-test-integration hx-test-integration: hx-deps ## hx: run hxprobe integration tests against live internet services (HTTP/2, redirects) cd $(HX_DIR) && uv run pytest tests -m integration -v $(ARGS) .PHONY: hx-check hx-check: hx-lint hx-test ## hx: run hxprobe test gate (lint + hermetic tests) .PHONY: hx-clean hx-clean: ## hx: remove hxprobe bytecode, caches, and egg-info @find $(HX_DIR) -type d -name '__pycache__' -exec rm -rf {} + 2>/dev/null; \ find $(HX_DIR) -name '*.pyc' -delete 2>/dev/null; \ rm -rf $(HX_DIR)/*.egg-info $(HX_DIR)/.pytest_cache $(HX_DIR)/.ruff_cache; true