206 lines
7.1 KiB
Makefile
206 lines
7.1 KiB
Makefile
.PHONY: all build test test-unit test-integration lint coverage clean install help docker-up docker-down docker-test docker-test-integration start stop 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
|
|
|
|
# Auto-detect container runtime (Docker or Podman)
|
|
CONTAINER_RUNTIME := $(shell \
|
|
if command -v podman > /dev/null 2>&1; then \
|
|
echo "podman"; \
|
|
elif command -v docker > /dev/null 2>&1; then \
|
|
echo "docker"; \
|
|
else \
|
|
echo "none"; \
|
|
fi)
|
|
|
|
# Detect compose command
|
|
COMPOSE_CMD := $(shell \
|
|
if [ "$(CONTAINER_RUNTIME)" = "podman" ]; then \
|
|
echo "podman-compose"; \
|
|
elif command -v docker-compose > /dev/null 2>&1; then \
|
|
echo "docker-compose"; \
|
|
else \
|
|
echo "docker compose"; \
|
|
fi)
|
|
|
|
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"
|
|
|
|
start: docker-up ## Alias for docker-up (start PostgreSQL test database)
|
|
|
|
stop: docker-down ## Alias for docker-down (stop PostgreSQL test database)
|
|
|
|
docker-up: ## Start PostgreSQL test database
|
|
@echo "Starting PostgreSQL test database (using $(CONTAINER_RUNTIME))..."
|
|
@if [ "$(CONTAINER_RUNTIME)" = "none" ]; then \
|
|
echo "Error: Neither Docker nor Podman is installed"; \
|
|
exit 1; \
|
|
fi
|
|
@if [ "$(CONTAINER_RUNTIME)" = "podman" ]; then \
|
|
podman run -d --name relspec-test-postgres \
|
|
-e POSTGRES_USER=relspec \
|
|
-e POSTGRES_PASSWORD=relspec_test_password \
|
|
-e POSTGRES_DB=relspec_test \
|
|
-p 5433:5432 \
|
|
-v ./tests/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql:Z \
|
|
postgres:16-alpine 2>/dev/null || echo "Container already running"; \
|
|
else \
|
|
$(COMPOSE_CMD) 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 (using $(CONTAINER_RUNTIME))..."
|
|
@if [ "$(CONTAINER_RUNTIME)" = "podman" ]; then \
|
|
podman stop relspec-test-postgres 2>/dev/null || true; \
|
|
podman rm relspec-test-postgres 2>/dev/null || true; \
|
|
else \
|
|
$(COMPOSE_CMD) down; \
|
|
fi
|
|
@echo "PostgreSQL stopped"
|
|
|
|
docker-test: ## Run PostgreSQL integration tests with Docker/Podman
|
|
@if [ "$(CONTAINER_RUNTIME)" = "podman" ]; then \
|
|
./tests/postgres/run_tests_podman.sh; \
|
|
else \
|
|
./tests/postgres/run_tests.sh; \
|
|
fi
|
|
|
|
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}'
|