1+ .PHONY : lint lint-check format test lint-test test-coverage-compare db-export db-import db-sync
2+
3+ # Load environment variables from .env file if it exists
4+ -include .env
5+ export
6+
7+ # Load Kamal configuration if it exists
8+ ifneq (,$(wildcard .kamal/secrets) )
9+ include .kamal/secrets
10+ endif
11+
12+ # Coverage threshold - tests will fail if coverage drops below this percentage
13+ # Can be overridden with: COVERAGE_THRESHOLD=25 make test
14+ COVERAGE_THRESHOLD ?= 50
15+
16+ # Run both linting and formatting checks (without modifying files)
17+ lint :
18+ @echo " Checking code with ruff..."
19+ ruff check app/ tests/ scripts/
20+
21+ # Format code in-place
22+ format :
23+ @echo " Formatting code with ruff..."
24+ ruff format app/ tests/ scripts/
25+ ruff check --fix app/ tests/ scripts/
26+
27+ # Check formatting only (for CI)
28+ lint-check :
29+ @echo " Checking formatting with ruff..."
30+ ruff format --check app/ tests/ scripts/
31+ ruff check app/ tests/ scripts/
32+
33+ # Run just the tests with coverage threshold
34+ test :
35+ @echo " Running tests with coverage threshold of $( COVERAGE_THRESHOLD) %..."
36+ pytest --cov=app --cov-report=term-missing --cov-report=html --cov-fail-under=$(COVERAGE_THRESHOLD )
37+
38+ # Run just the tests without coverage threshold (for debugging)
39+ test-no-coverage :
40+ @echo " Running tests without coverage threshold..."
41+ pytest --full-trace
42+
43+ # Run tests and compare coverage against previous run (fails if coverage drops)
44+ test-coverage-compare :
45+ @echo " Running tests with coverage comparison..."
46+ @if [ -n " $$ BASELINE_COVERAGE" ]; then \
47+ echo " Baseline coverage: $$ BASELINE_COVERAGE%" ; \
48+ pytest --cov=app --cov-report=term-missing --cov-report=html --cov-report=xml; \
49+ CURRENT_COVERAGE=$$(grep -o 'line-rate="[^"]*"' coverage.xml | head -1 | sed 's/line-rate="\([^"]*\ ) " /\1/' | awk '{printf " %.0f" , $$ 1 * 100}'); \
50+ echo " Current coverage: $$ CURRENT_COVERAGE%" ; \
51+ if [ -n " $$ CURRENT_COVERAGE" ]; then \
52+ if [ $$ CURRENT_COVERAGE -lt $$ BASELINE_COVERAGE ]; then \
53+ echo " FAIL: Coverage dropped from $$ BASELINE_COVERAGE% to $$ CURRENT_COVERAGE%" ; \
54+ exit 1; \
55+ else \
56+ echo " SUCCESS: Coverage maintained or improved" ; \
57+ fi ; \
58+ else \
59+ echo " ERROR: Could not parse current coverage value" ; \
60+ exit 1; \
61+ fi ; \
62+ else \
63+ echo " No baseline coverage set. Use: BASELINE_COVERAGE=22 make test-coverage-compare" ; \
64+ echo " Or run: make test-coverage-baseline" ; \
65+ exit 1; \
66+ fi
67+
68+ # Create a baseline coverage file for comparison
69+ test-coverage-baseline :
70+ @echo " Creating baseline coverage file..."
71+ pytest --cov=app --cov-report=term-missing --cov-report=html --cov-report=xml
72+ BASELINE_COVERAGE=$$(grep -o 'line-rate="[^"]*"' coverage.xml | head -1 | sed 's/line-rate="\([^"]*\ ) " /\1/' | awk '{printf " %.0f" , $$ 1 * 100}'); \
73+ echo " Baseline coverage: $$ BASELINE_COVERAGE%" ; \
74+ echo " To use this baseline, run: BASELINE_COVERAGE=$$ BASELINE_COVERAGE make test-coverage-compare"
75+
76+ # Run linting and then tests (for CI)
77+ lint-test : lint-check test
78+
79+ # Database export/import tasks
80+ # ─────────────────────────────────────────────────────────────────────────
81+
82+ # Export local database to SQL dump file
83+ db-export :
84+ @echo " Exporting local ParadeDB database..."
85+ @if [ -z " $$ POSTGRES_PASSWORD" ]; then \
86+ echo " ERROR: POSTGRES_PASSWORD environment variable is not set." ; \
87+ echo " Please set it in a .env file or run: POSTGRES_PASSWORD=yourpass make db-export" ; \
88+ exit 1; \
89+ fi
90+ @echo " Checking if ParadeDB container is running..."
91+ @if ! docker ps | grep -q btaa-ogm-api-paradedb; then \
92+ echo " ERROR: ParadeDB container (btaa-ogm-api-paradedb) is not running." ; \
93+ echo " Start it with: docker-compose up -d paradedb" ; \
94+ exit 1; \
95+ fi
96+ @echo " Container is running. Starting export..."
97+ @mkdir -p tmp
98+ @docker exec btaa-ogm-api-paradedb pg_dump \
99+ -U postgres \
100+ -d btaa_ogm_api \
101+ --no-owner \
102+ --no-acl \
103+ --clean \
104+ --if-exists \
105+ | gzip > tmp/btaa_ogm_api_export.sql.gz
106+ @echo " Export complete: tmp/btaa_ogm_api_export.sql.gz"
107+ @ls -lh tmp/btaa_ogm_api_export.sql.gz
108+
109+ # Import database dump to remote server via Kamal
110+ db-import :
111+ @echo " Importing database to remote PostgreSQL..."
112+ @if [ ! -f tmp/btaa_ogm_api_export.sql.gz ]; then \
113+ echo " ERROR: Export file not found. Run 'make db-export' first." ; \
114+ exit 1; \
115+ fi
116+ @if [ -z " $$ KAMAL_SSH_USER" ] || [ -z " $$ KAMAL_HOST" ]; then \
117+ echo " ERROR: KAMAL_SSH_USER and KAMAL_HOST environment variables must be set." ; \
118+ echo " Please source your .kamal/secrets file or set these variables." ; \
119+ exit 1; \
120+ fi
121+ @echo " Checking remote container status..."
122+ @ssh $$ KAMAL_SSH_USER@$$ KAMAL_HOST ' docker ps | grep btaa-data-api-paradedb' || \
123+ (echo " ERROR: Remote paradedb container is not running. Check Kamal deployment." && exit 1)
124+ @echo " Remote container is running. Starting import..."
125+ @echo " ⚠️ WARNING: This will drop and recreate all database objects!"
126+ @echo " Press Ctrl+C within 5 seconds to cancel..."
127+ @sleep 5
128+ @echo " Copying dump file to remote server..."
129+ @scp tmp/btaa_ogm_api_export.sql.gz $$ KAMAL_SSH_USER@$$ KAMAL_HOST:/tmp/
130+ @echo " Importing database..."
131+ @ssh $$ KAMAL_SSH_USER@$$ KAMAL_HOST ' \
132+ gunzip -c /tmp/btaa_ogm_api_export.sql.gz | \
133+ docker exec -i btaa-data-api-paradedb psql \
134+ -U postgres \
135+ -d btaa_ogm_api && \
136+ rm /tmp/btaa_ogm_api_export.sql.gz'
137+ @echo " ✓ Import complete!"
138+
139+ # Export and import in one command
140+ db-sync : db-export db-import
141+ @echo " Database sync complete!"
0 commit comments