-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
150 lines (133 loc) · 6.29 KB
/
Copy pathMakefile
File metadata and controls
150 lines (133 loc) · 6.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
BINARY := pgfathom
PKG := github.com/lvcas-dotcom/pgfathom
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo none)
DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
# Recursive on purpose: demo-svg overrides VERSION for its own build, and an
# immediate assignment here would have expanded VERSION before that override
# exists.
LDFLAGS = -s -w \
-X '$(PKG)/internal/buildinfo.Version=$(VERSION)' \
-X '$(PKG)/internal/buildinfo.Commit=$(COMMIT)' \
-X '$(PKG)/internal/buildinfo.Date=$(DATE)'
# CGO_ENABLED=0 is a requirement rather than a tuning choice: cross-compiling
# has to stay trivial.
export CGO_ENABLED := 0
.PHONY: demo-svg build test test-integration corpus benchmark lint fmt cover crosscheck release-check image-check clean help
## build: compile the binary into ./bin
build:
@mkdir -p bin
go build -trimpath -ldflags "$(LDFLAGS)" -o bin/$(BINARY) ./cmd/$(BINARY)
## test: unit suite; no Docker, no network
test:
go test ./...
## test-integration: starts real PostgreSQL through testcontainers
test-integration:
go test -tags=integration -timeout=20m ./...
## corpus: fetch and verify the benchmark schemas (the only step that uses the network)
corpus:
go test -tags=benchmark -timeout=15m -v -run TestFetchCorpus ./internal/bench/...
## benchmark: measure recall against the corpus and write docs/benchmark
benchmark:
go test -tags=benchmark -timeout=90m -v -run TestCorpus ./internal/bench/...
## lint: golangci-lint under every build tag
lint:
golangci-lint run
golangci-lint run --build-tags integration
golangci-lint run --build-tags benchmark
## fmt: format and vet
fmt:
go fmt ./...
go vet ./...
## cover: unit test coverage
cover:
go test -coverprofile=coverage.out ./...
go tool cover -func=coverage.out | tail -1
## crosscheck: prove cross-compilation works without cgo
crosscheck:
@for target in linux/amd64 linux/arm64 darwin/arm64 windows/amd64; do \
os=$${target%/*}; arch=$${target#*/}; \
echo " $$os/$$arch"; \
GOOS=$$os GOARCH=$$arch go build -trimpath -o /dev/null ./cmd/$(BINARY) || exit 1; \
done
@echo "cross-compile ok"
## release-check: prove the release path produces a correctly stamped binary
#
# The stamp comes from two configurations that have to agree on three variable
# names — this one and goreleaser's. The comparison is for equality rather than
# for the string "unknown", because the binary never says "unknown": buildinfo
# falls back to what the toolchain recorded and answers a pseudo-version of the
# commit. That is a good default for `go install`, and it is exactly what would
# hide a broken ldflag and publish a binary whose version is not the tag's.
release-check:
goreleaser check
goreleaser build --snapshot --clean --single-target --output dist/pgfathom-check
@want=$$(sed -n 's/.*"version":"\([^"]*\)".*/\1/p' dist/metadata.json); \
got=$$(./dist/pgfathom-check version | head -1 | awk '{print $$2}'); \
if [ "$$got" != "$$want" ]; then \
echo "FAILED: the release would stamp $$want and the binary answers $$got"; \
exit 1; \
fi; \
echo "stamp ok: $$got"
# The newest CHANGELOG entry has to come out whole. Extraction breaks silently
# when the heading changes shape, and the release is too late to find that out.
@v=$$(sed -n 's/^## \[\([0-9][^]]*\)\].*/\1/p' CHANGELOG.md | head -1); \
./scripts/release-notes.sh "v$$v" > /dev/null; \
echo "release notes ok: $$v"
# `--release-notes` is loaded by goreleaser's changelog pipe, so disabling that
# pipe drops the flag on the floor: the notes never load, the release body comes
# out as the footer alone, and nothing fails. v0.1.2 shipped that way.
@if grep -q -- "--release-notes" .github/workflows/release.yml && \
sed -n "/^changelog:/,/^[a-z]/p" .goreleaser.yaml | grep -qE "^[[:space:]]+disable:[[:space:]]*true"; then \
echo "FAILED: the workflow passes --release-notes and .goreleaser.yaml disables the changelog stage that loads it"; \
exit 1; \
fi; \
echo "release notes wiring ok"
## image-check: prove the image builds for both platforms
#
# Reproduces the context goreleaser assembles — one binary per platform, in
# subdirectories — and builds without publishing. This is the check that was
# missing: the Dockerfile was written for the old flat context format, and the
# error surfaced only during the first release, in the step after everything
# else had passed.
image-check:
@ctx=$$(mktemp -d); \
trap 'rm -rf "$$ctx"' EXIT; \
for p in amd64 arm64; do \
mkdir -p "$$ctx/linux/$$p"; \
GOOS=linux GOARCH=$$p go build -trimpath -o "$$ctx/linux/$$p/$(BINARY)" ./cmd/$(BINARY) || exit 1; \
done; \
cp Dockerfile "$$ctx/"; \
docker buildx build --platform linux/amd64,linux/arm64 --output=type=cacheonly "$$ctx"
@echo "image ok"
## demo-svg: re-record the README image from a real run
#
# The image is generated rather than screenshotted so it can be regenerated when
# the report format changes — see docs/RELEASING.md. It needs Docker.
#
# It builds at the latest tag rather than at the working tree's version, because
# the tool stamps its own version into the report and a recording that says
# v0.1.2-16-g837ec2a-dirty tells the reader about the maintainer's checkout
# instead of about their database.
demo-svg: VERSION = $(shell git describe --tags --abbrev=0 2>/dev/null || echo dev)
demo-svg: build
@ctr=pgfathom-demo-svg; \
docker rm -f $$ctr >/dev/null 2>&1 || true; \
docker run -d --name $$ctr -e POSTGRES_PASSWORD=demo -e POSTGRES_DB=loja -p 55440:5432 \
-v "$$PWD/demo/schema.sql:/docker-entrypoint-initdb.d/schema.sql:ro" postgres:16-alpine >/dev/null; \
for i in $$(seq 40); do \
docker exec $$ctr psql -U postgres -d loja -c 'SELECT 1 FROM nota_fiscal LIMIT 1' >/dev/null 2>&1 && break; \
sleep 1; \
done; \
COLORTERM=truecolor PGFATHOM_DSN='postgres://postgres:demo@localhost:55440/loja?sslmode=disable' \
./bin/$(BINARY) discover --schema public --full --color always 2>/dev/null > /tmp/pgfathom-demo.ansi; \
docker rm -f $$ctr >/dev/null; \
go run scripts/termsvg.go < /tmp/pgfathom-demo.ansi > assets/demo.svg; \
echo "assets/demo.svg regenerated; the plain text below goes in the README"; \
sed 's/\x1b\[[0-9;]*m//g' /tmp/pgfathom-demo.ansi
## clean: remove build artifacts
clean:
rm -rf bin dist coverage.out
## help: list the targets
help:
@grep -E '^## ' $(MAKEFILE_LIST) | sed 's/## //'