.PHONY: build clean test vet staticcheck fmt install-tools all install uninstall version # Binary name BINARY=kportal # Version management using semver-gen # If semver-gen is available, use it; otherwise fallback to 0.1.0-dev VERSION?=$(shell which semver-gen > /dev/null 2>&1 && semver-gen generate -l 2>/dev/null | sed 's/SEMVER //' || echo "0.1.0-dev") # Build directory BUILD_DIR=. # Installation directories PREFIX?=/usr/local INSTALL_BIN_DIR=$(PREFIX)/bin # Detect user's local bin directory ifeq ($(shell uname), Darwin) # macOS - prefer Homebrew location if it exists, otherwise /usr/local USER_BIN_DIR=$(shell [ -d /opt/homebrew/bin ] && echo /opt/homebrew/bin || echo $(HOME)/.local/bin) else ifeq ($(shell uname), Linux) # Linux - use ~/.local/bin (typically in PATH) USER_BIN_DIR=$(HOME)/.local/bin else # Fallback USER_BIN_DIR=$(HOME)/bin endif # Go parameters GOCMD=go GOBUILD=$(GOCMD) build GOCLEAN=$(GOCMD) clean GOTEST=$(GOCMD) test GOGET=$(GOCMD) get GOVET=$(GOCMD) vet GOFMT=$(GOCMD) fmt # Build flags BUILD_FLAGS=-buildvcs=false LDFLAGS=-ldflags="-s -w -X main.version=$(VERSION)" all: fmt vet staticcheck test build build: @echo "Building $(BINARY)..." $(GOBUILD) $(BUILD_FLAGS) $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY) ./cmd/kportal @echo "Build complete: $(BUILD_DIR)/$(BINARY)" clean: @echo "Cleaning..." $(GOCLEAN) rm -f $(BUILD_DIR)/$(BINARY) @echo "Clean complete" test: @echo "Running tests..." $(GOTEST) -v -race -cover ./... @echo "Tests complete" test-short: @echo "Running short tests..." $(GOTEST) -short ./... @echo "Short tests complete" vet: @echo "Running go vet..." $(GOVET) ./... @echo "go vet passed" fmt: @echo "Formatting code..." $(GOFMT) ./... @echo "Format complete" staticcheck: @echo "Running staticcheck..." @which staticcheck > /dev/null || (echo "staticcheck not found. Run 'make install-tools' to install it" && exit 1) staticcheck ./... @echo "staticcheck passed" install-tools: @echo "Installing development tools..." $(GOGET) honnef.co/go/tools/cmd/staticcheck@latest $(GOGET) github.com/vektra/mockery/v2@latest @echo "Installing semver-gen for version management..." @which semver-gen > /dev/null 2>&1 || \ (curl -s https://api.github.com/repos/lukaszraczylo/semver-generator/releases/latest | \ grep "browser_download_url.*$(shell uname -s | tr '[:upper:]' '[:lower:]').*$(shell uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/')" | \ cut -d '"' -f 4 | \ xargs curl -L -o /tmp/semver-gen && \ chmod +x /tmp/semver-gen && \ mv /tmp/semver-gen $(USER_BIN_DIR)/semver-gen) @echo "Tools installed" run: build @echo "Running $(BINARY)..." ./$(BINARY) run-verbose: build @echo "Running $(BINARY) in verbose mode..." ./$(BINARY) -v version: @echo "Current version: $(VERSION)" @if which semver-gen > /dev/null 2>&1; then \ echo "Version generated by semver-gen"; \ else \ echo "semver-gen not installed (using fallback version)"; \ echo "Run 'make install-tools' to install semver-gen"; \ fi check: fmt vet staticcheck @echo "All checks passed" install: build @echo "Installing $(BINARY)..." @mkdir -p $(USER_BIN_DIR) @install -m 755 $(BUILD_DIR)/$(BINARY) $(USER_BIN_DIR)/$(BINARY) @echo "" @echo "✅ $(BINARY) successfully installed to $(USER_BIN_DIR)/$(BINARY)" @echo "" @echo "Verify installation:" @echo " $(USER_BIN_DIR)/$(BINARY) --help" @echo "" @if echo "$$PATH" | grep -q "$(USER_BIN_DIR)"; then \ echo "✅ $(USER_BIN_DIR) is in your PATH"; \ echo "You can now run: $(BINARY)"; \ else \ echo "⚠️ $(USER_BIN_DIR) is not in your PATH"; \ echo "Add it to your PATH by adding this to your shell config:"; \ echo " export PATH=\"$(USER_BIN_DIR):\$$PATH\""; \ fi @echo "" install-system: build @echo "Installing $(BINARY) system-wide..." @if [ "$$(id -u)" -ne 0 ]; then \ echo "System installation requires sudo privileges."; \ sudo install -m 755 $(BUILD_DIR)/$(BINARY) $(INSTALL_BIN_DIR)/$(BINARY); \ else \ install -m 755 $(BUILD_DIR)/$(BINARY) $(INSTALL_BIN_DIR)/$(BINARY); \ fi @echo "" @echo "✅ $(BINARY) successfully installed to $(INSTALL_BIN_DIR)/$(BINARY)" @echo "You can now run: $(BINARY)" @echo "" uninstall: @echo "Uninstalling $(BINARY)..." @if [ -f "$(USER_BIN_DIR)/$(BINARY)" ]; then \ rm -f $(USER_BIN_DIR)/$(BINARY); \ echo "✅ Removed $(USER_BIN_DIR)/$(BINARY)"; \ fi @if [ -f "$(INSTALL_BIN_DIR)/$(BINARY)" ]; then \ if [ "$$(id -u)" -ne 0 ]; then \ sudo rm -f $(INSTALL_BIN_DIR)/$(BINARY); \ else \ rm -f $(INSTALL_BIN_DIR)/$(BINARY); \ fi; \ echo "✅ Removed $(INSTALL_BIN_DIR)/$(BINARY)"; \ fi @echo "Uninstall complete" # Generate mocks mocks: @echo "Generating mocks..." mockery --name=K8sClientInterface --dir=internal/k8s --output=internal/mocks mockery --name=ResourceResolver --dir=internal/k8s --output=internal/mocks mockery --name=PortForwarder --dir=internal/k8s --output=internal/mocks @echo "Mocks generated" # Run integration tests test-integration: @echo "Running integration tests..." $(GOTEST) -v ./test/integration/... @echo "Integration tests complete" # Coverage report coverage: @echo "Generating coverage report..." $(GOTEST) -coverprofile=coverage.out ./... $(GOCMD) tool cover -html=coverage.out -o coverage.html @echo "Coverage report generated: coverage.html" # Show help help: @echo "kportal - Kubernetes Port Forwarding Tool" @echo "" @echo "Available targets:" @echo "" @echo "Build & Install:" @echo " build - Build the binary in current directory" @echo " install - Install to user bin directory ($(USER_BIN_DIR))" @echo " install-system - Install system-wide ($(INSTALL_BIN_DIR), requires sudo)" @echo " uninstall - Remove installed binary from all locations" @echo " clean - Remove build artifacts" @echo "" @echo "Testing:" @echo " test - Run all tests with race detection and coverage" @echo " test-short - Run short tests only" @echo " test-integration- Run integration tests" @echo " coverage - Generate coverage report" @echo "" @echo "Code Quality:" @echo " fmt - Format code with go fmt" @echo " vet - Run go vet" @echo " staticcheck - Run staticcheck" @echo " check - Run fmt, vet, and staticcheck" @echo " all - Run fmt, vet, staticcheck, test, and build" @echo "" @echo "Development:" @echo " run - Build and run the binary" @echo " run-verbose - Build and run with verbose logging" @echo " version - Display current version (from semver-gen or fallback)" @echo " install-tools - Install development tools (staticcheck, mockery, semver-gen)" @echo " mocks - Generate test mocks" @echo "" @echo "Variables:" @echo " VERSION - Set version (default: $(VERSION))" @echo " PREFIX - Installation prefix (default: $(PREFIX))" @echo "" @echo "Examples:" @echo " make build # Build binary" @echo " make install # Install for current user" @echo " sudo make install-system # Install system-wide" @echo " make VERSION=1.0.0 build # Build with custom version"