Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
195 lines (164 loc) · 6.8 KB
/
Copy pathMakefile
File metadata and controls
195 lines (164 loc) · 6.8 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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
.PHONY: all clean generate generate-check build test fuzz e2e-test e2e-test-coverage lint run fmt docker-build help check-tools
.DEFAULT_GOAL:=help
VERSION?=$(shell git describe --always --tags)
BUILD_TIME?=$(shell date --iso-8601=seconds)
DOC_PATH?="main"
DOCKER_IMAGE_NAME=spx01/blocky
BINARY_NAME:=blocky
BIN_OUT_DIR?=bin
GOARCH?=$(shell go env GOARCH)
GOARM?=$(shell go env GOARM)
GO_BUILD_FLAGS?=-v
GO_BUILD_LD_FLAGS:=\
-w \
-s \
-X github.com/0xERR0R/blocky/util.Version=${VERSION} \
-X github.com/0xERR0R/blocky/util.BuildTime=$(shell date -d "${BUILD_TIME}" '+%Y%m%d-%H%M%S') \
-X github.com/0xERR0R/blocky/util.Architecture=${GOARCH}${GOARM}
GO_BUILD_OUTPUT:=$(BIN_OUT_DIR)/$(BINARY_NAME)$(BINARY_SUFFIX)
# define version of golangci-lint here. If defined in tools.go, go mod perfoms automatically downgrade to older version which doesn't work with golang >=1.18
GOLANG_LINT_VERSION=v2.12.2
GINKGO_PROCS?=
# Fuzzing. Fuzz target seed corpora run as ordinary tests on every `make test`;
# this is the opt-in discovery mode that actively generates new inputs. `go test
# -fuzz` only fuzzes one target in one package per invocation, so `make fuzz`
# loops over every Fuzz* target in FUZZ_PKGS, time-boxing each at FUZZ_TIME.
FUZZ_TIME?=30s
FUZZ_PKGS?=./config ./util ./lists/parsers
# Parallelism for e2e tests. e2e specs are dominated by container startup and
# health-check waits rather than CPU, so oversubscribing beyond the core count
# improves wall-clock time. Defaults to -p (one process per core) for local
# runs; CI overrides this to oversubscribe the runner.
GINKGO_E2E_PROCS?=-p
export PATH=$(shell go env GOPATH)/bin:$(shell echo $$PATH)
# Tool check functions
define check_command
@which $(1) > /dev/null 2>&1 || { echo "Error: $(1) is required but not installed. $(2)"; exit 1; }
endef
define check_go_tool
@go list -f "{{.ImportPath}}" $(1) > /dev/null 2>&1 || { echo "Error: $(1) is required but not installed. Run: go install $(1)@latest"; exit 1; }
endef
check-go:
$(call check_command,go,"Please install Go from https://golang.org/doc/install")
check-docker:
$(call check_command,docker,"Please install Docker from https://docs.docker.com/get-docker/")
@docker buildx version > /dev/null 2>&1 || { echo "Error: docker buildx is required but not installed. See https://docs.docker.com/buildx/working-with-buildx/"; exit 1; }
all: build test lint ## Build binary (with tests)
clean: ## cleans output directory
rm -rf $(BIN_OUT_DIR)/*
serve_docs: check-docker ## serves online docs using Docker
docker run --rm -p 8000:8000 -v $(PWD):/docs squidfunk/mkdocs-material:latest
generate: check-go ## Go generate
ifdef GO_SKIP_GENERATE
$(info skipping go generate)
else
go tool mockery
go generate ./...
endif
generate-check: check-go ## Verify generated files (mocks, enums, config schema) are up to date
go tool mockery
go generate ./...
@git diff --exit-code || { echo "generated files are out of date; run 'make generate' and commit the result"; exit 1; }
build: check-go generate ## Build binary
go build $(GO_BUILD_FLAGS) -ldflags="$(GO_BUILD_LD_FLAGS)" -o $(GO_BUILD_OUTPUT)
ifdef BIN_USER
$(info setting owner of $(GO_BUILD_OUTPUT) to $(BIN_USER))
chown $(BIN_USER) $(GO_BUILD_OUTPUT)
endif
ifdef BIN_AUTOCAB
$(info setting cap_net_bind_service (permitted) on $(GO_BUILD_OUTPUT))
setcap 'cap_net_bind_service=+p' $(GO_BUILD_OUTPUT)
endif
test: check-go ## run tests
go tool ginkgo --label-filter="!e2e" --coverprofile=coverage.txt --covermode=atomic --cover -r ${GINKGO_PROCS}
go tool cover -html coverage.txt -o coverage.html
fuzz: check-go ## run each fuzz target for FUZZ_TIME (default 30s); e.g. make fuzz FUZZ_TIME=2m
@set -e; \
for pkg in $(FUZZ_PKGS); do \
for target in $$(go test -list '^Fuzz' $$pkg | grep '^Fuzz'); do \
echo "==> fuzzing $$target in $$pkg for $(FUZZ_TIME)"; \
go test -run '^$$' -fuzz "^$$target$$" -fuzztime $(FUZZ_TIME) $$pkg; \
done; \
done
e2e-test: check-go check-docker ## run e2e tests
docker buildx build \
--build-arg VERSION=blocky-e2e \
--build-arg BUILD_TIME=${BUILD_TIME} \
--build-arg GOPROXY \
--network=host \
-o type=docker \
-t blocky-e2e \
.
go tool ginkgo ${GINKGO_E2E_PROCS} --label-filter="e2e" --timeout 15m --flake-attempts 1 e2e
e2e-test-coverage: check-go check-docker ## run e2e tests with code coverage
@echo "Building coverage-instrumented Docker image..."
docker buildx build \
--build-arg VERSION=blocky-e2e-coverage \
--build-arg BUILD_TIME=${BUILD_TIME} \
--build-arg GOPROXY \
--build-arg OPTS="-cover" \
--network=host \
-o type=docker \
-t blocky-e2e-coverage \
.
@echo "Running e2e tests with coverage collection..."
@mkdir -p coverage/e2e
@rm -rf coverage/e2e/*
@chmod 777 coverage/e2e
BLOCKY_IMAGE=blocky-e2e-coverage GOCOVERDIR=$(PWD)/coverage/e2e \
go tool ginkgo ${GINKGO_E2E_PROCS} --label-filter="e2e" --timeout 15m --flake-attempts 1 e2e
@echo "Converting coverage data..."
go tool covdata textfmt -i=./coverage/e2e -o=coverage/e2e-coverage.out
@echo ""
@echo "Coverage report generated!"
@echo "===================="
@go tool cover -func=coverage/e2e-coverage.out | awk '\
BEGIN { print "\nCoverage by package:" } \
/^total:/ { total = $$3; next } \
/:/ { \
split($$1, parts, ":"); \
file = parts[1]; \
n = split(file, path, "/"); \
if (n > 1) { \
pkg = path[1]; \
for (i = 2; i < n; i++) pkg = pkg "/" path[i]; \
} else { \
pkg = "."; \
} \
gsub(/%/, "", $$3); \
sum[pkg] += $$3; \
count[pkg]++; \
} \
END { \
for (pkg in sum) { \
printf "%-60s %6.1f%%\n", pkg, sum[pkg]/count[pkg]; \
} \
print "------------------------------------------------------------"; \
printf "%-60s %s\n", "TOTAL", total; \
}' | sort
@echo ""
@echo "View full coverage report:"
@echo " - HTML: go tool cover -html=coverage/e2e-coverage.out"
@echo " - Text: go tool cover -func=coverage/e2e-coverage.out"
race: check-go ## run tests with race detector
go tool ginkgo --label-filter="!e2e" --race -r ${GINKGO_PROCS}
lint: check-go fmt ## run golangcli-lint checks
go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANG_LINT_VERSION) run --timeout 5m
run: build ## Build and run binary
./$(BIN_OUT_DIR)/$(BINARY_NAME)
fmt: check-go ## gofmt and goimports all go files
go tool gofumpt -l -w -extra .
find . -name '*.go' -exec go tool goimports -w {} +
docker-build: check-docker generate ## Build docker image
docker buildx build \
--build-arg VERSION=${VERSION} \
--build-arg BUILD_TIME=${BUILD_TIME} \
--build-arg GOPROXY \
--build-arg DOC_PATH=${DOC_PATH} \
--network=host \
-o type=docker \
-t ${DOCKER_IMAGE_NAME} \
.
check-tools: check-go check-docker ## Check if all required tools are installed
help: ## Shows help
@grep -E '^[0-9a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'