-
Notifications
You must be signed in to change notification settings - Fork 80
Expand file tree
/
Copy pathMakefile
More file actions
161 lines (140 loc) · 5.99 KB
/
Copy pathMakefile
File metadata and controls
161 lines (140 loc) · 5.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
.PHONY: all dev stop db migrate indexer grpc-api go-api sdk-build test lint lint-openapi help
# Load environment variables from .env if it exists
ifneq (,$(wildcard .env))
include .env
export
endif
# Default target
all: dev
help: ## Show this help message
@echo ""
@echo "Trident — Soroban Event Indexer for Stellar"
@echo ""
@echo "Usage: make <target>"
@echo ""
@echo "Targets:"
@echo " dev Start the full development stack (DB + migrate + all services)"
@echo " stop Stop all Docker containers"
@echo " db Start only Postgres and Redis via Docker Compose"
@echo " migrate Apply database migrations (requires sqlx-cli or psql)"
@echo " indexer Run the Rust indexer with dev env vars"
@echo " grpc-api Run the Rust gRPC API with dev env vars"
@echo " go-api Run the Go REST API"
@echo " sdk-build Build the TypeScript and React SDKs"
@echo " test Run all unit tests (integration tests require TEST_DATABASE_URL)"
@echo " lint Run all linters (cargo fmt, clippy, go vet, tsc)"
@echo " lint-openapi Run Spectral linter on OpenAPI spec"
@echo " deploy Deploy all services to Fly.io (requires flyctl)"
@echo " help Show this help message"
@echo ""
dev: db migrate
@echo "Starting indexer, grpc-api, and go-api..."
@trap 'kill 0' INT TERM EXIT; \
cargo run --bin trident-indexer 2>&1 | sed -e 's/^/[indexer] /' & \
cargo run --bin trident-api 2>&1 | sed -e 's/^/[grpc-api] /' & \
cd services/api && go run main.go 2>&1 | sed -e 's/^/[go-api] /' & \
wait
stop:
docker compose -f docker/docker-compose.dev.yml down
db:
docker compose -f docker/docker-compose.dev.yml up -d
@echo "Waiting for PostgreSQL to be healthy..."
@until docker exec $$(docker compose -f docker/docker-compose.dev.yml ps -q postgres) pg_isready -U trident -d trident >/dev/null 2>&1; do \
sleep 1; \
done
@echo "PostgreSQL is healthy!"
migrate:
@echo "Applying database migrations..."
@if command -v sqlx >/dev/null 2>&1; then \
sqlx db create --database-url "$(DATABASE_URL)" || true; \
sqlx migrate run --database-url "$(DATABASE_URL)" --source database/migrations; \
else \
echo "sqlx-cli not found, attempting raw psql migrations..."; \
psql "$(DATABASE_URL)" -f database/schema.sql; \
for f in database/migrations/*.sql; do \
echo "Applying $$f..."; \
psql "$(DATABASE_URL)" -f "$$f"; \
done; \
fi
indexer:
cargo run --bin trident-indexer
grpc-api:
cargo run --bin trident-api
go-api:
cd services/api && go run main.go
sdk-build:
cd sdk/typescript && npm install && npm run build
cd sdk/react && npm install && npm run build
test:
cargo test --all
cd services/api && go test ./...
cd sdk/typescript && npm install && npm run test
cd sdk/react && npm install && npm run test
deploy: ## Deploy all services to Fly.io in dependency order (requires flyctl)
@echo "Deploying gRPC API..."
fly deploy -c fly/grpc-api.toml --remote-only
@echo "Deploying Indexer..."
fly deploy -c fly/indexer.toml --remote-only
@echo "Deploying Go REST API..."
fly deploy -c fly/api.toml --remote-only
@echo "All services deployed."
lint:
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cd services/api && go vet ./...
@if command -v golangci-lint >/dev/null 2>&1; then \
cd services/api && golangci-lint run; \
fi
cd sdk/typescript && npm install && npm run lint
cd sdk/react && npm install && npm run lint
lint-openapi: ## Lint the OpenAPI specification
@if command -v spectral >/dev/null 2>&1; then \
spectral lint api/openapi.yaml --ruleset spectral:oas; \
else \
echo "spectral CLI not found. Install with: npm install -g @stoplight/spectral-cli"; \
exit 1; \
fi
# Coverage (issue #325). Mirrors the `coverage` job in .github/workflows/ci.yml
# so a local run and CI report the same numbers from the same tools.
#
# cargo-llvm-cov, not tarpaulin: llvm-cov uses the compiler's own
# instrumentation, so it reports the regions rustc actually sees.
coverage: coverage-rust coverage-go coverage-sdk ## Collect coverage for Rust, Go, and the SDKs
coverage-rust: ## Rust workspace coverage (HTML + lcov in target/llvm-cov)
@command -v cargo-llvm-cov >/dev/null 2>&1 || { \
echo "cargo-llvm-cov not found. Install with: cargo install cargo-llvm-cov"; \
exit 1; \
}
cargo llvm-cov --workspace --html --lcov --output-path lcov.info -- --test-threads=1
@echo "HTML report: target/llvm-cov/html/index.html"
coverage-go: ## Go API coverage (HTML in services/api/coverage.html)
cd services/api && go test ./... -coverprofile=coverage.out
cd services/api && go tool cover -html=coverage.out -o coverage.html
cd services/api && go tool cover -func=coverage.out | tail -1
coverage-sdk: ## TypeScript and Python SDK coverage
cd sdk/typescript && npm run test -- --coverage || \
echo "note: install @vitest/coverage-v8 for TypeScript coverage"
cd sdk/python && pytest -q --cov --cov-report=term --cov-fail-under=0
# Enforce the floors CI enforces. Runs the measurement itself rather than
# depending on a profile a previous target may or may not have produced —
# the previous version read services/api/coverage.out without generating it,
# so a clean tree failed on a missing file rather than on coverage.
#
# Floors are set from measured baselines, not aspiration; see the `coverage`
# job in .github/workflows/ci.yml for the rationale and current numbers.
coverage-check: ## Enforce coverage floors on MVP-critical packages
@set -e; \
cd services/api; \
echo "Checking Go critical-package coverage floors..."; \
fail=0; \
for spec in "handlers:43" "middleware:66" "cursor:90" "validation:95"; do \
pkg=$${spec%%:*}; floor=$${spec##*:}; \
actual=$$(go test ./$$pkg -coverprofile=cov-$$pkg.out 2>/dev/null \
| grep -oE 'coverage: [0-9.]+%' | grep -oE '[0-9.]+' || echo 0); \
if awk -v a="$$actual" -v f="$$floor" 'BEGIN { exit !(a + 0 < f + 0) }'; then \
echo " FAIL $$pkg: $$actual% is below the $$floor% floor"; fail=1; \
else \
echo " ok $$pkg: $$actual% (floor $$floor%)"; \
fi; \
done; \
exit $$fail