mirror of
https://github.com/0xERR0R/blocky.git
synced 2026-10-12 02:01:13 +00:00
196 lines
6.8 KiB
Makefile
196 lines
6.8 KiB
Makefile
.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}'
|