textmachine/backend/Makefile

60 lines
2.8 KiB
Makefile

# Backend battery as one command. `make battery` IS the manual battery every session used to retype;
# it is the entry point CI will call, so what runs locally and what runs there cannot drift.
#
# Run from backend/. Toolchain and linter are PINNED here (never "latest"): the linter's findings are a
# gate, and a gate that changes under you on someone else's machine is not a gate.
GO ?= go
GO_MIN_VERSION := 1.26.4
GOLANGCI_LINT ?= golangci-lint
GOLANGCI_VERSION := 2.12.2
# backend/bin/ is already gitignored, so the vet tool leaves no untracked file behind.
TMVET := bin/tmvet
.PHONY: build vet fmt lint test battery battery-stand tools-check
build: tools-check
$(GO) build ./...
# `-vettool` REPLACES the standard vet suite rather than adding to it (measured: a copylocks finding
# that plain `go vet` reports disappears under -vettool), so both passes have to run. Both tag sets too:
# the paid `live` tests compile only under -tags live and would otherwise rot unseen.
vet:
$(GO) vet ./...
$(GO) vet -tags live ./...
$(GO) build -o $(TMVET) ./cmd/tmvet
$(GO) vet -vettool=$(TMVET) ./...
$(GO) vet -tags live -vettool=$(TMVET) ./...
# `gofmt -l` exits 0 even when it names files, so the emptiness of its output is the assertion.
fmt:
@test -z "$$(gofmt -l .)" || { echo "gofmt: not formatted:"; gofmt -l .; exit 1; }
tools-check:
@$(GO) version | grep -qE 'go1\.(2[6-9]|[3-9][0-9])' || { \
echo "Go $(GO_MIN_VERSION)+ required (go.mod floor); got: $$($(GO) version)"; exit 1; }
@$(GOLANGCI_LINT) --version 2>/dev/null | grep -q " $(GOLANGCI_VERSION) " || { \
echo "golangci-lint $(GOLANGCI_VERSION) required (findings are version-dependent)."; \
echo "install: https://github.com/golangci/golangci-lint/releases/tag/v$(GOLANGCI_VERSION)"; exit 1; }
lint: tools-check
$(GOLANGCI_LINT) run --timeout=15m ./...
# -race needs cgo (a C toolchain). If it is missing this fails loudly — dropping -race would turn a
# missing toolchain into a green run that proved less than it claims.
test:
$(GO) test ./... -race -count=1
# The hermetic battery: everything that is green on a bare clone. It ends by NAMING the tests that did
# not run, because a skip is invisible in `ok` lines and a silent skip reads as coverage.
battery: build vet fmt lint test
@echo "--- did NOT run (no stand data; see battery-stand) ---"
@$(GO) test ./... -count=1 -v > .skips.log 2>&1 || { echo "the skip-harvest pass FAILED:"; \
grep -E '^(---|\s+---) FAIL|^FAIL' .skips.log; rm -f .skips.log; exit 1; }
@grep -- '--- SKIP' .skips.log || echo "(none)"
@rm -f .skips.log
# The stand battery: adds the corpus-gated tests. With the flags set, MISSING data fails instead of
# skipping, so "the corpus is here" is asserted rather than assumed.
battery-stand: build vet fmt lint
TM_MINER_PARITY=1 TM_CHECKER_LABELS=1 $(GO) test ./... -race -count=1