# Go Jdenticon Makefile # Provides convenient commands for building, testing, and profiling .PHONY: help build test bench clean memory-test memory-profile load-test analyze-memory # Default target help: @echo "Go Jdenticon - Available Commands:" @echo "" @echo "Building:" @echo " make build Build all binaries (CLI + tools)" @echo " make jdenticon-cli Build CLI only" @echo " make version-info Show version information" @echo " make clean Clean build artifacts" @echo "" @echo "Testing:" @echo " make test Run all tests" @echo " make test-race Run tests with race detection" @echo " make test-coverage Run tests with coverage report" @echo " make bench Run all benchmarks" @echo "" @echo "Memory Leak Validation (Task 26):" @echo " make memory-test Run memory leak validation tests" @echo " make memory-bench Run memory leak benchmarks with profiling" @echo " make load-test Run sustained load test (5 minutes)" @echo " make load-test-long Run extended load test (30 minutes)" @echo " make memory-profile Interactive memory profiling session" @echo " make analyze-memory Analyze latest memory profiles" @echo "" @echo "Advanced Profiling:" @echo " make profile-heap Generate heap profile" @echo " make profile-cpu Generate CPU profile" @echo " make profile-web Start web UI for profile analysis" @echo " make profile-continuous Run continuous profiling for 1 hour" @echo "" @echo "Examples:" @echo " make memory-test # Quick memory leak validation" @echo " make load-test # 5-minute sustained load test" @echo " make profile-web # Web UI for profile analysis" # Go parameters GOCMD=go GOBUILD=$(GOCMD) build GOCLEAN=$(GOCMD) clean GOTEST=$(GOCMD) test GOGET=$(GOCMD) get GOMOD=$(GOCMD) mod # Version information VERSION ?= $(shell git describe --tags --exact-match 2>/dev/null || git describe --tags 2>/dev/null || echo "dev") COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown") BUILD_DATE ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ") # Build flags for version injection LDFLAGS=-ldflags "-X gitea.dockr.co/kev/go-jdenticon/cmd/jdenticon.Version=$(VERSION) \ -X gitea.dockr.co/kev/go-jdenticon/cmd/jdenticon.Commit=$(COMMIT) \ -X gitea.dockr.co/kev/go-jdenticon/cmd/jdenticon.BuildDate=$(BUILD_DATE)" # Build targets CLI_BINARY=jdenticon-cli LOAD_TEST_BINARY=cmd/memory-load-test/memory-load-test # Build all binaries build: $(CLI_BINARY) $(LOAD_TEST_BINARY) @echo "Building Go Jdenticon..." $(GOBUILD) -v ./... $(CLI_BINARY): @echo "Building jdenticon CLI with version $(VERSION)..." $(GOBUILD) $(LDFLAGS) -o $(CLI_BINARY) ./cmd/jdenticon $(LOAD_TEST_BINARY): @echo "Building memory load test binary..." $(GOBUILD) -o $(LOAD_TEST_BINARY) ./cmd/memory-load-test # Show version information that will be injected version-info: @echo "Version Information:" @echo " Version: $(VERSION)" @echo " Commit: $(COMMIT)" @echo " Build Date: $(BUILD_DATE)" # Build specifically with version information (alias for jdenticon-cli) jdenticon: $(CLI_BINARY) # Clean build artifacts clean: @echo "Cleaning build artifacts..." $(GOCLEAN) rm -f $(CLI_BINARY) rm -f $(LOAD_TEST_BINARY) rm -f *.prof rm -f cpu.prof mem.prof heap.prof clean-profiles: @echo "Cleaning all profile data..." rm -rf profiles/ # Testing test: @echo "Running all tests..." $(GOTEST) -v ./... test-race: @echo "Running tests with race detection..." $(GOTEST) -race -v ./... test-coverage: @echo "Running tests with coverage..." $(GOTEST) -coverprofile=coverage.out -v ./... $(GOCMD) tool cover -html=coverage.out -o coverage.html @echo "Coverage report: coverage.html" bench: @echo "Running all benchmarks..." $(GOTEST) -bench=. -benchmem ./... # Memory leak validation (Task 26) memory-test: @echo "Running memory leak validation tests..." $(GOTEST) -v -run TestMemoryLeak ./jdenticon memory-bench: @echo "Running memory leak benchmarks with profiling..." mkdir -p profiles $(eval TIMESTAMP := $(shell date +%Y%m%d_%H%M%S)) $(eval MEM_PROF := profiles/memory-bench-$(TIMESTAMP).prof) $(eval CPU_PROF := profiles/cpu-bench-$(TIMESTAMP).prof) $(GOTEST) -bench=BenchmarkMemoryLeak \ -benchtime=5m \ -memprofile=$(MEM_PROF) \ -memprofilerate=1 \ -cpuprofile=$(CPU_PROF) \ -benchmem \ ./jdenticon @echo "Profiles saved in profiles/ directory" @ln -sf $(shell basename $(MEM_PROF)) profiles/mem-latest.prof @ln -sf $(shell basename $(CPU_PROF)) profiles/cpu-latest.prof @echo "Created symlinks for latest profiles (mem-latest.prof, cpu-latest.prof)" load-test: $(LOAD_TEST_BINARY) @echo "Running 5-minute sustained load test..." ./$(LOAD_TEST_BINARY) -duration=5m -workers=4 -cache-size=1000 load-test-long: $(LOAD_TEST_BINARY) @echo "Running 30-minute extended load test..." ./$(LOAD_TEST_BINARY) -duration=30m -workers=8 -cache-size=500 memory-profile: @echo "Starting interactive memory profiling session..." ./scripts/memory-profile.sh benchmark --duration=10m analyze-memory: @echo "Analyzing latest memory profiles..." @if [ -f profiles/mem-latest.prof ]; then \ echo "Opening memory profile analysis..."; \ $(GOCMD) tool pprof profiles/mem-latest.prof; \ else \ echo "No memory profile found. Run 'make memory-bench' first."; \ fi # Advanced profiling commands profile-heap: @echo "Generating heap profile (30 seconds)..." mkdir -p profiles $(GOTEST) -bench=BenchmarkMemoryLeakSustainedLoad \ -benchtime=30s \ -memprofile=profiles/heap-$$(date +%Y%m%d_%H%M%S).prof \ -memprofilerate=1 \ ./jdenticon profile-cpu: @echo "Generating CPU profile (30 seconds)..." mkdir -p profiles $(GOTEST) -bench=BenchmarkMemoryLeakSustainedLoad \ -benchtime=30s \ -cpuprofile=profiles/cpu-$$(date +%Y%m%d_%H%M%S).prof \ ./jdenticon profile-web: @echo "Starting web UI for profile analysis..." @if [ -f profiles/mem-latest.prof ]; then \ echo "Opening http://localhost:8080 for profile analysis..."; \ $(GOCMD) tool pprof -http=:8080 profiles/mem-latest.prof; \ else \ echo "No memory profile found. Run 'make memory-bench' first."; \ fi profile-continuous: $(LOAD_TEST_BINARY) @echo "Running continuous profiling for 1 hour..." ./scripts/memory-profile.sh continuous --duration=1h --workers=6 # Development helpers deps: @echo "Downloading dependencies..." $(GOMOD) download $(GOMOD) tidy verify: @echo "Verifying dependencies..." $(GOMOD) verify fmt: @echo "Formatting code..." $(GOCMD) fmt ./... vet: @echo "Running go vet..." $(GOCMD) vet ./... lint: @echo "Running golangci-lint..." @if command -v golangci-lint >/dev/null 2>&1; then \ golangci-lint run; \ else \ echo "golangci-lint not installed. Install with: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest"; \ fi # Task 26 validation workflow task-26: memory-test memory-bench load-test @echo "" @echo "=== Task 26: Memory Leak Validation Complete ===" @echo "✅ Memory leak tests passed" @echo "✅ Memory benchmarks completed with profiling" @echo "✅ Sustained load test completed" @echo "" @echo "Next steps:" @echo " make analyze-memory # Analyze memory profiles" @echo " make profile-web # Web UI for detailed analysis" @echo " make load-test-long # Extended validation (30 min)" @echo "" @if [ -d profiles ]; then \ echo "Profile files available in profiles/ directory:"; \ ls -la profiles/; \ fi # Quick validation for CI ci-memory-check: @echo "Quick memory validation for CI..." $(GOTEST) -timeout=10m -run TestMemoryLeak ./jdenticon $(GOTEST) -bench=BenchmarkMemoryLeakSustainedLoad -benchtime=1m ./jdenticon