Makefile¶
:material-github: View on GitHub · 206 lines · live source, included at build time
# Makefile for SafeHeaders-Go
# Single source of truth for the list of Go modules. Keep alphabetized.
MODULES := cgltf-go cjson-go dr-wav-go jsmn-go linenoise-go miniz-go stb-image-go stb-truetype-go tinyxml2-go
.PHONY: help test test-race test-coverage lint fmt vet bench clean install-tools \
security fuzz examples all pre-commit ci deps update-deps testdata \
build-examples info
# Default target
help:
@echo "SafeHeaders-Go - Development Makefile"
@echo ""
@echo "Available targets:"
@echo " make test - Run all tests"
@echo " make test-race - Run tests with race detector"
@echo " make test-coverage - Run tests with coverage report"
@echo " make lint - Run golangci-lint"
@echo " make fmt - Format all Go code"
@echo " make vet - Run go vet"
@echo " make bench - Run benchmarks"
@echo " make security - Run security scanners (gosec, govulncheck)"
@echo " make fuzz - Run fuzz tests (requires -fuzz flag)"
@echo " make examples - Run all examples"
@echo " make clean - Clean build artifacts and caches"
@echo " make install-tools - Install development tools"
@echo " make all - Run fmt, vet, lint, test"
@echo ""
# Run all tests
test:
@echo "Running tests for all modules..."
@for dir in $(MODULES); do \
echo "Testing $$dir..."; \
(cd $$dir && go test -v ./...) || exit 1; \
done
@echo "✅ All tests passed!"
# Run tests with race detector
test-race:
@echo "Running tests with race detector..."
@for dir in $(MODULES); do \
echo "Testing $$dir (with -race)..."; \
(cd $$dir && go test -race -v ./...) || exit 1; \
done
@echo "✅ All race tests passed!"
# Run tests with coverage
test-coverage:
@echo "Running tests with coverage..."
@for dir in $(MODULES); do \
echo "Testing $$dir (with coverage)..."; \
(cd $$dir && go test -coverprofile=coverage.out -covermode=atomic ./...) || exit 1; \
(cd $$dir && go tool cover -func=coverage.out | grep total | awk '{print "Coverage: " $$3}'); \
done
@echo "✅ Coverage reports generated!"
# Run linter
lint:
@echo "Running golangci-lint..."
@for dir in $(MODULES); do \
echo "Linting $$dir..."; \
(cd $$dir && golangci-lint run --config ../.golangci.yml) || exit 1; \
done
@echo "✅ Linting passed!"
# Format all code
fmt:
@echo "Formatting Go code..."
@go fmt ./...
@echo "✅ Code formatted!"
# Run go vet
vet:
@echo "Running go vet..."
@for dir in $(MODULES); do \
(cd $$dir && go vet ./...) || exit 1; \
done
@echo "✅ go vet passed!"
# Run benchmarks
bench:
@echo "Running benchmarks..."
@for dir in jsmn-go stb-image-go stb-truetype-go; do \
echo "Benchmarking $$dir..."; \
(cd $$dir && go test -bench=. -benchmem -benchtime=3s ./...) || true; \
done
@echo "✅ Benchmarks complete!"
# Run security scanners
security:
@echo "Running security scanners..."
@echo "Running gosec..."
@gosec -fmt=text ./... || true
@echo ""
@echo "Running govulncheck..."
@for dir in $(MODULES); do \
echo "Checking $$dir..."; \
(cd $$dir && govulncheck ./...) || true; \
done
@echo "✅ Security scans complete!"
# Fuzz smoke test: run one fuzzer per fuzz-tested module for FUZZTIME each.
# Override duration with `make fuzz FUZZTIME=2m`. Fails if any fuzzer finds a crash.
FUZZTIME ?= 15s
fuzz:
@echo "Running fuzz smoke tests ($(FUZZTIME) each)..."
@(cd jsmn-go && go test -run='^$$' -fuzz='^FuzzParse$$' -fuzztime=$(FUZZTIME) .) || exit 1
@(cd tinyxml2-go && go test -run='^$$' -fuzz='^FuzzParse$$' -fuzztime=$(FUZZTIME) .) || exit 1
@(cd dr-wav-go && go test -run='^$$' -fuzz='^FuzzParse$$' -fuzztime=$(FUZZTIME) .) || exit 1
@(cd miniz-go && go test -run='^$$' -fuzz='^FuzzExtract$$' -fuzztime=$(FUZZTIME) .) || exit 1
@(cd cgltf-go && go test -run='^$$' -fuzz='^FuzzParse$$' -fuzztime=$(FUZZTIME) .) || exit 1
@(cd cjson-go && go test -run='^$$' -fuzz='^FuzzUnmarshal$$' -fuzztime=$(FUZZTIME) .) || exit 1
@(cd stb-truetype-go && go test -run='^$$' -fuzz='^FuzzLoadFont$$' -fuzztime=$(FUZZTIME) .) || exit 1
@echo "✅ Fuzz smoke tests passed!"
# Build every example module (they are standalone modules with replace
# directives) and run the non-interactive demos. GOWORK=off so each example is
# resolved exactly as an end user who cloned only that directory would see it.
examples:
@echo "Building all examples..."
@for ex in examples/json-parser examples/jsmn-demo examples/production-usage examples/linenoise-repl; do \
echo "Building $$ex..."; \
(cd $$ex && GOWORK=off go build ./...) || exit 1; \
(cd $$ex && GOWORK=off go vet ./...) || exit 1; \
done
@echo "Running non-interactive demos..."
@(cd examples/json-parser && GOWORK=off go run .) || exit 1
@(cd examples/jsmn-demo && GOWORK=off go run .) || exit 1
@echo "✅ Examples build and run successfully!"
# Clean build artifacts
clean:
@echo "Cleaning build artifacts..."
@find . -name "coverage.out" -delete
@find . -name "*.test" -delete
@go clean -cache -testcache -modcache
@echo "✅ Clean complete!"
# Install development tools
install-tools:
@echo "Installing development tools..."
@go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.2.2
@go install github.com/securego/gosec/v2/cmd/gosec@v2.21.4
@go install golang.org/x/vuln/cmd/govulncheck@v1.1.4
@go install golang.org/x/tools/cmd/benchstat@latest
@echo "✅ Tools installed!"
# Run all checks (fmt, vet, lint, test)
all: fmt vet lint test
@echo "✅ All checks passed!"
# Quick check before committing
pre-commit: fmt vet test-race
@echo "✅ Pre-commit checks passed!"
# CI simulation (what runs in GitHub Actions)
ci: lint test-race test-coverage security
@echo "✅ CI simulation complete!"
# Install module dependencies
deps:
@echo "Downloading module dependencies..."
@for dir in $(MODULES); do \
(cd $$dir && go mod download) || exit 1; \
done
@echo "✅ Dependencies downloaded!"
# Update module dependencies
update-deps:
@echo "Updating module dependencies..."
@for dir in $(MODULES); do \
echo "Updating $$dir..."; \
(cd $$dir && go get -u ./... && go mod tidy) || exit 1; \
done
@echo "✅ Dependencies updated!"
# Generate test data
testdata:
@echo "Generating test data..."
@bash scripts/generate-testdata.sh
@echo "✅ Test data generated!"
# Build all examples
build-examples:
@echo "Building examples..."
@mkdir -p bin
@(cd examples/json-parser && go build -o ../../bin/json-parser main.go)
@(cd examples/production-usage && go build -o ../../bin/production-server main.go)
@echo "✅ Examples built in bin/ directory!"
# Show module information
info:
@echo "SafeHeaders-Go Module Information"
@echo "=================================="
@echo ""
@echo "Go Version:"
@go version
@echo ""
@echo "Modules:"
@for dir in $(MODULES); do \
echo " - $$dir"; \
done
@echo ""
@echo "Workspace:"
@cat go.work