.PHONY: help init setup build test test-race test-verbose lint lint-fix security docs release clean include tools.versions # ── Variables ────────────────────────────────────────────────────────────────── MODULE := $(shell go list -m) VERSION ?= $(shell git describe --tags 2>/dev/null || echo dev) COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown) BUILT_AT := $(shell date -u +%Y-%m-%dT%H:%M:%SZ) LDFLAGS := -ldflags "\ -X $(MODULE)/internal/buildinfo.Version=$(VERSION) \ -X $(MODULE)/internal/buildinfo.Commit=$(COMMIT) \ -X $(MODULE)/internal/buildinfo.BuildTime=$(BUILT_AT)" CMDS := $(shell find cmd -mindepth 1 -maxdepth 1 -type d 2>/dev/null) BINS := $(patsubst cmd/%,bin/%,$(CMDS)) # ── Default target ───────────────────────────────────────────────────────────── help: ## Show this help message @grep -E '^[a-zA-Z_-]+:.*?## .*$$' Makefile | \ 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 env -w GOPRIVATE=gitea.djmil.dev 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) go install golang.org/x/pkgsite/cmd/pkgsite@$(PKGSITE_VERSION) # ── Build ────────────────────────────────────────────────────────────────────── build: $(BINS) ## Compile all cmd/* binaries to ./bin/ (stamped with version, commit, build time) bin/%: cmd/% @mkdir -p bin go build $(LDFLAGS) -o $@ ./$< # ── 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) ./... # ── Docs ─────────────────────────────────────────────────────────────────────── docs: ## Serve package documentation locally via pkgsite (http://localhost:8080) go run golang.org/x/pkgsite/cmd/pkgsite@$(PKGSITE_VERSION) -open . # ── 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 @MSG=$$(mktemp); \ LAST=$$(git describe --tags --abbrev=0 2>/dev/null); \ echo "$(VERSION)" > $$MSG; \ echo "" >> $$MSG; \ if [ -n "$$LAST" ]; then \ echo "Changes since $$LAST:" >> $$MSG; \ git log $$LAST..HEAD --oneline >> $$MSG; \ else \ git log --oneline >> $$MSG; \ fi; \ git tag -a -e -F $$MSG $(VERSION); \ rm -f $$MSG 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