.PHONY: all build test test-unit test-integration lint coverage clean install help docker-up docker-down docker-test docker-test-integration release release-version # Binary name BINARY_NAME=relspec # Build directory BUILD_DIR=build # Go parameters GOCMD=go GOBUILD=$(GOCMD) build GOTEST=$(GOCMD) test GOGET=$(GOCMD) get GOMOD=$(GOCMD) mod GOCLEAN=$(GOCMD) clean all: lint test build ## Run linting, tests, and build build: ## Build the binary @echo "Building $(BINARY_NAME)..." @mkdir -p $(BUILD_DIR) $(GOBUILD) -o $(BUILD_DIR)/$(BINARY_NAME) ./cmd/relspec @echo "Build complete: $(BUILD_DIR)/$(BINARY_NAME)" test: test-unit ## Run all unit tests (alias for test-unit) test-unit: ## Run unit tests (excludes integration tests) @echo "Running unit tests..." $(GOTEST) -v -race -coverprofile=coverage.out -covermode=atomic $$(go list ./... | grep -v '/tests/integration' | grep -v '/tests/assets' | grep -v '/pkg/readers/pgsql') test-integration: ## Run integration tests (requires RELSPEC_TEST_PG_CONN environment variable) @echo "Running integration tests..." @if [ -z "$$RELSPEC_TEST_PG_CONN" ]; then \ echo "Error: RELSPEC_TEST_PG_CONN environment variable is not set"; \ echo "Example: export RELSPEC_TEST_PG_CONN='postgres://relspec:relspec_test_password@localhost:5432/relspec_test'"; \ exit 1; \ fi @echo "Running PostgreSQL reader tests..." $(GOTEST) -v -count=1 ./pkg/readers/pgsql/ @echo "Running general integration tests..." $(GOTEST) -v -count=1 ./tests/integration/ coverage: test ## Run tests with coverage report @echo "Generating coverage report..." $(GOCMD) tool cover -html=coverage.out -o coverage.html @echo "Coverage report generated: coverage.html" lint: ## Run linter @echo "Running linter..." @if command -v golangci-lint > /dev/null; then \ golangci-lint run --config=.golangci.json; \ else \ echo "golangci-lint not installed. Install with: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest"; \ exit 1; \ fi lintfix: ## Run linter @echo "Running linter..." @if command -v golangci-lint > /dev/null; then \ golangci-lint run --config=.golangci.json --fix; \ else \ echo "golangci-lint not installed. Install with: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest"; \ exit 1; \ fi clean: ## Clean build artifacts @echo "Cleaning..." $(GOCLEAN) rm -rf $(BUILD_DIR) rm -f coverage.out coverage.html @echo "Clean complete" install: ## Install the binary to $GOPATH/bin @echo "Installing $(BINARY_NAME)..." $(GOCMD) install ./cmd/relspec @echo "Install complete" deps: ## Download dependencies @echo "Downloading dependencies..." $(GOMOD) download $(GOMOD) tidy @echo "Dependencies updated" docker-up: ## Start PostgreSQL test database @echo "Starting PostgreSQL test database..." @if command -v docker-compose > /dev/null 2>&1; then \ docker-compose up -d postgres; \ else \ docker compose up -d postgres; \ fi @echo "Waiting for PostgreSQL to be ready..." @sleep 3 @echo "PostgreSQL is running on port 5433" @echo "Connection: postgres://relspec:relspec_test_password@localhost:5433/relspec_test" docker-down: ## Stop PostgreSQL test database @echo "Stopping PostgreSQL test database..." @if command -v docker-compose > /dev/null 2>&1; then \ docker-compose down; \ else \ docker compose down; \ fi @echo "PostgreSQL stopped" docker-test: ## Run PostgreSQL integration tests with Docker @./tests/postgres/run_tests.sh docker-test-integration: docker-up ## Start DB and run integration tests @echo "Running integration tests..." @sleep 2 @RELSPEC_TEST_PG_CONN="postgres://relspec:relspec_test_password@localhost:5433/relspec_test" \ $(GOTEST) -v ./pkg/readers/pgsql/ -count=1 || (make docker-down && exit 1) @make docker-down release: ## Create and push a new release tag (auto-increments patch version) @echo "Creating new release..." @latest_tag=$$(git describe --tags --abbrev=0 2>/dev/null || echo ""); \ if [ -z "$$latest_tag" ]; then \ version="v1.0.0"; \ echo "No existing tags found. Creating first release: $$version"; \ commit_logs=$$(git log --pretty=format:"- %s" --no-merges); \ else \ echo "Latest tag: $$latest_tag"; \ version_number=$${latest_tag#v}; \ IFS='.' read -r major minor patch <<< "$$version_number"; \ patch=$$((patch + 1)); \ version="v$$major.$$minor.$$patch"; \ echo "Creating new release: $$version"; \ commit_logs=$$(git log "$${latest_tag}..HEAD" --pretty=format:"- %s" --no-merges); \ fi; \ if [ -z "$$commit_logs" ]; then \ tag_message="Release $$version"; \ else \ tag_message="Release $$version\n\n$$commit_logs"; \ fi; \ git tag -a "$$version" -m "$$tag_message"; \ git push origin "$$version"; \ echo "Tag $$version created and pushed to remote repository." release-version: ## Create and push a release with specific version (use: make release-version VERSION=v1.2.3) @if [ -z "$(VERSION)" ]; then \ echo "Error: VERSION is required. Usage: make release-version VERSION=v1.2.3"; \ exit 1; \ fi @version="$(VERSION)"; \ if ! echo "$$version" | grep -q "^v"; then \ version="v$$version"; \ fi; \ echo "Creating release: $$version"; \ latest_tag=$$(git describe --tags --abbrev=0 2>/dev/null || echo ""); \ if [ -z "$$latest_tag" ]; then \ commit_logs=$$(git log --pretty=format:"- %s" --no-merges); \ else \ commit_logs=$$(git log "$${latest_tag}..HEAD" --pretty=format:"- %s" --no-merges); \ fi; \ if [ -z "$$commit_logs" ]; then \ tag_message="Release $$version"; \ else \ tag_message="Release $$version\n\n$$commit_logs"; \ fi; \ git tag -a "$$version" -m "$$tag_message"; \ git push origin "$$version"; \ echo "Tag $$version created and pushed to remote repository." help: ## Display this help screen @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'