.PHONY: help init setup build run test test-race lint lint-fix security clean include tools.versions # ── Variables ────────────────────────────────────────────────────────────────── BINARY_NAME := app BINARY_PATH := ./bin/$(BINARY_NAME) CMD_PATH := ./cmd/app # ── Default target ───────────────────────────────────────────────────────────── help: ## Show this help message @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \ awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-16s\033[0m %s\n", $$1, $$2}' | sort # ── First-time setup ─────────────────────────────────────────────────────────── init: ## First-time project init: fetch deps, configure git hooks go mod tidy $(MAKE) setup @echo "Done! Run 'make build' to verify." setup: ## Configure git to use .githooks directory git config core.hooksPath .githooks chmod +x .githooks/* @echo "Git hooks configured: .githooks/" # ── Development tools ────────────────────────────────────────────────────────── tools: ## Install tool binaries to GOPATH/bin (versions from tools.versions) @echo "Installing tools..." go install github.com/go-delve/delve/cmd/dlv@$(DELVE_VERSION) go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION) go install github.com/securego/gosec/v2/cmd/gosec@$(GOSEC_VERSION) go install golang.org/x/vuln/cmd/govulncheck@$(GOVULNCHECK_VERSION) # ── Build ────────────────────────────────────────────────────────────────────── build: ## Compile the binary to ./bin/ go build -o $(BINARY_PATH) $(CMD_PATH) # ── Run ──────────────────────────────────────────────────────────────────────── run: ## Run the application with default flags go run $(CMD_PATH)/main.go # ── Test ─────────────────────────────────────────────────────────────────────── test: ## Run all tests go test ./... -cover test-race: ## Run all tests with race detector go test ./... -race -cover test-verbose: ## Run all tests with verbose output go test ./... -race -cover -v # ── Lint & Security ──────────────────────────────────────────────────────────── lint: ## Run go vet + golangci-lint go vet ./... go run github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION) run ./... lint-fix: ## Apply go fix + golangci-lint auto-fix go fix ./... go run github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION) run --fix ./... security: ## Run gosec + govulncheck @echo "--- gosec ---" go run github.com/securego/gosec/v2/cmd/gosec@$(GOSEC_VERSION) -quiet ./... @echo "--- govulncheck ---" go run golang.org/x/vuln/cmd/govulncheck@$(GOVULNCHECK_VERSION) ./... # ── Release ──────────────────────────────────────────────────────────────────── release: ## List releases, or tag+push a new one (usage: make release VERSION=v0.1.0) ifdef VERSION @echo "$(VERSION)" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+$$' || \ (echo "VERSION must be semver: v0.1.0"; exit 1) @git diff --quiet && git diff --cached --quiet || \ (echo "Uncommitted changes — commit first"; exit 1) @git tag -l | grep -q "^$(VERSION)$$" && \ (echo "Tag $(VERSION) already exists"; exit 1) || true $(MAKE) test-race $(MAKE) lint $(MAKE) security git tag $(VERSION) git push origin $(VERSION) else @echo "Released versions:" @git tag -l --sort=-version:refname | grep -E '^v[0-9]' || echo " (none yet)" endif # ── Cleanup ──────────────────────────────────────────────────────────────────── clean: ## Remove build artifacts rm -rf ./bin