# eeco — build and release entry points. # Default target builds a single local binary; `release` cross-builds # the published matrix via scripts/build.sh. VERSION ?= $(shell git describe --tags --dirty --always 2>/dev/null || echo dev) COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown) BUILD_DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ) # Windows host builds need the .exe suffix so the Makefile recipes # (which invoke ./eeco directly) work under Git Bash. ifeq ($(OS),Windows_NT) EXE := .exe else EXE := endif LDFLAGS = -s -w -X main.version=$(VERSION) -X main.commit=$(COMMIT) -X main.buildDate=$(BUILD_DATE) # golangci-lint version for `make lint`, pinned here as the single # source of truth — CI runs the same `make lint`, so local and CI # stay byte-identical. GOLANGCI_LINT_VERSION ?= v2.12.2 .PHONY: all build release checksums packaging verify cover cover-check gates bench clean sync-guide lint manpage all: build # sync-guide refreshes the in-binary user manual mirror at # internal/guide/usage.md from the canonical docs/USAGE.md. CI keeps # the two byte-identical via a drift gate (TestUsageMirrorsDocs) — run # this target whenever docs/USAGE.md changes. sync-guide: cp docs/USAGE.md internal/guide/usage.md build: go build -trimpath -ldflags '$(LDFLAGS)' -o eeco$(EXE) ./cmd/eeco release: manpage VERSION='$(VERSION)' COMMIT='$(COMMIT)' BUILD_DATE='$(BUILD_DATE)' ./scripts/build.sh # manpage renders dist/eeco.1 from docs/USAGE.md via go-md2man. Run as a # prerequisite of `release` so the man page is bundled into the # darwin/linux archives and shipped as a standalone release asset. manpage: ./scripts/gen-manpage.sh checksums: cd dist && shasum -a 256 eeco_$(VERSION)_*.tar.gz eeco_$(VERSION)_*.zip > SHA256SUMS packaging: VERSION='$(VERSION)' ./scripts/gen-packaging.sh verify: go build ./... go vet ./... go test ./... # cover writes a coverage profile to coverage.out for the codecov # upload in CI (and local inspection via `go tool cover`). cover: go test -coverprofile=coverage.out -covermode=atomic ./... # cover-check enforces the coverage ratchet: total statement coverage must # stay at or above the floor in scripts/check-coverage.sh (a regression # guard, not a target). Depends on `cover` so coverage.out is fresh; CI # gates on this and the codecov step reuses the same coverage.out. cover-check: cover bash scripts/check-coverage.sh # lint runs the golangci-lint quality bar (errcheck, gosec, govet, # staticcheck, unused) configured in .golangci.yml. Pinned via go run # so no separate install step is needed. lint: go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION) run ./... gates: build ./eeco$(EXE) run comment-hygiene ./eeco$(EXE) run leak-guard ./eeco$(EXE) run version-sync bench: build mkdir -p dist go test -tags=bench -bench=. -benchtime=1x -timeout=300s -run=^$$ ./internal/workflow/... rm -rf dist/bench-fixture clean: rm -rf dist eeco eeco.exe