-
Notifications
You must be signed in to change notification settings - Fork 317
Expand file tree
/
Copy pathMakefile
More file actions
272 lines (235 loc) · 10.3 KB
/
Copy pathMakefile
File metadata and controls
272 lines (235 loc) · 10.3 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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
.PHONY: help setup setup-symlinks install build build-desktop build-desktop-local build-android build-ios clean run dev dev-desktop dev-ios dev-android dev-android-init doctor doctor-q up down nuke status thunderbot-pull thunderbot-push thunderbot-customize
# Color definitions
BLUE := \033[0;34m
GREEN := \033[0;32m
YELLOW := \033[0;33m
NC := \033[0m # No Color
# Container compose tool (auto-detect podman-compose, fallback to docker compose)
COMPOSE ?= $(shell command -v podman-compose > /dev/null 2>&1 && podman info > /dev/null 2>&1 && echo podman-compose || echo docker compose)
# Isolate Docker volumes/networks per clone so sibling working trees (e.g. ~/code/thunderbolt
# and ~/code/some-test-dir/thunderbolt) don't share Postgres data. Defaults to "<parent>-<repo>";
# override with `COMPOSE_PROJECT_NAME=foo make up` if you want a fixed name.
# Sanitize each segment so paths with spaces or other special characters (e.g. "~/My Projects/thunderbolt")
# produce a valid Docker Compose project name.
COMPOSE_PROJECT_NAME ?= $(shell basename "$$(cd .. && pwd)" | sed 's/[^a-zA-Z0-9._-]/-/g')-$(shell basename "$$(pwd)" | sed 's/[^a-zA-Z0-9._-]/-/g')
export COMPOSE_PROJECT_NAME
# Default target
help:
@echo "Available commands:"
@echo ""
@echo " Setup:"
@echo " make setup - Install frontend + backend dependencies and agent symlinks"
@echo " make doctor - Verify dev tools, env files, and mobile SDKs"
@echo " make doctor-q - Quiet doctor (only prints issues)"
@echo ""
@echo " Containers:"
@echo " make up - Start Postgres + PowerSync containers"
@echo " make down - Stop containers (keeps volumes)"
@echo " make nuke - Wipe all container data and re-init"
@echo " make status - Show container status"
@echo ""
@echo " Dev:"
@echo " make dev - Backend (:8000) + web frontend (:1420)"
@echo " make dev-desktop - Backend + Tauri desktop shell"
@echo " make dev-ios - Backend + Tauri on first booted iOS simulator"
@echo " make dev-android - Backend + Tauri on Android emulator (re-inits gen/android)"
@echo ""
@echo " Build:"
@echo " make build - Vite production build (web)"
@echo " make build-desktop - Tauri desktop release (signed, for CI)"
@echo " make build-desktop-local - Tauri desktop release (no updater signing)"
@echo " make build-ios - Tauri iOS release (needs Apple signing certs)"
@echo " make build-android - Tauri Android release"
@echo " make clean - Remove dist, target, node_modules"
@echo ""
@echo " Quality:"
@echo " make format - Format frontend, backend, Rust"
@echo " make format-check - Check formatting"
@echo ""
@echo " Misc:"
@echo " make thunderbot-pull - Pull latest skills from thunderbot"
@echo " make thunderbot-push - Push skill changes back to thunderbot"
@echo " make thunderbot-customize - Fork a thunderbot command (FILE=name.md)"
@echo " make setup-symlinks - Create Claude Code agent symlinks"
# Create agent symlinks for Claude Code
setup-symlinks:
@mkdir -p .claude/commands .claude/agents
@for f in .thunderbot/thunder*.md; do ln -sf "../../$$f" ".claude/commands/$$(basename $$f)"; done
@ln -sfn ../../.thunderbot/thunderbot .claude/commands/thunderbot
@ln -sf ../../.thunderbot/thunderbot.md .claude/agents/thunderbot.md
@echo "$(GREEN)✓ Agent symlinks configured$(NC)"
# Setup project - install frontend and backend dependencies
setup: setup-symlinks
@echo "$(BLUE)→ Installing frontend dependencies...$(NC)"
bun install
@echo "$(BLUE)→ Installing backend dependencies...$(NC)"
cd backend && bun install
@echo "$(BLUE)→ Installing Playwright browsers (for `make e2e` tests)...$(NC)"
bunx playwright install
@echo "$(GREEN)✓ Setup complete!$(NC)"
# Install dependencies
install:
bun install
# Build frontend
build:
bun run build
# Build desktop app
build-desktop:
bun install
bun tauri build
# Build desktop app with specific target
build-desktop-target:
bun install
bun tauri build --target $(TARGET)
# Build desktop app with bundles and target
build-desktop-full:
bun install
bun tauri build --bundles $(BUNDLES) --target $(TARGET)
# Build Android app
build-android:
bun install
bun tauri android build
# Build iOS app
build-ios:
bun install
bun tauri ios build --export-method app-store-connect
# Clean build artifacts
clean:
- rm -rf dist src-tauri/target node_modules
- (cd src-tauri && cargo clean)
# Linting
lint:
bun run lint
lint-fix:
bun run lint:fix
# Formatting
format:
@echo "$(BLUE)→ Formatting frontend code...$(NC)"
bun run format
@echo "$(BLUE)→ Formatting backend code...$(NC)"
cd backend && bun run format
@echo "$(BLUE)→ Formatting Rust code...$(NC)"
@if command -v cargo > /dev/null 2>&1; then bun run format:rust; else echo "$(YELLOW)⚠ cargo not found, skipping Rust formatting$(NC)"; fi
@echo "$(GREEN)✓ Formatting complete!$(NC)"
format-check:
@echo "$(BLUE)→ Checking frontend formatting...$(NC)"
bun run format-check
@echo "$(BLUE)→ Checking backend formatting...$(NC)"
cd backend && bun run format-check
@echo "$(BLUE)→ Checking Rust formatting...$(NC)"
@if command -v cargo > /dev/null 2>&1; then bun run format:rust-check; else echo "$(YELLOW)⚠ cargo not found, skipping Rust format check$(NC)"; fi
@echo "$(GREEN)✓ Format check complete!$(NC)"
# Type checking
type-check:
bun run type-check
# Run tests
test:
@echo "$(BLUE)→ Running frontend tests...$(NC)"
@bun run test
@echo "$(BLUE)→ Running backend tests...$(NC)"
@bun run test:backend
# Run all checks
check:
bun run check
# Start development servers (backend and frontend)
run:
@echo "$(BLUE)→ Starting backend and frontend development servers...$(NC)"
@echo "$(YELLOW) Backend will run on http://localhost:8000$(NC)"
@echo "$(YELLOW) Frontend will run on http://localhost:1420$(NC)"
@echo "$(YELLOW) Press Ctrl+C to stop both servers$(NC)"
@echo ""
@# Kill any existing processes on the ports first
@-lsof -ti:8000 | xargs kill -9 2>/dev/null || true
@-lsof -ti:1420 | xargs kill -9 2>/dev/null || true
@# Start backend in background and frontend in foreground
cd backend && bun run dev & \
BACKEND_PID=$$!; \
echo "$(GREEN)✓ Backend started (PID: $$BACKEND_PID)$(NC)"; \
sleep 2; \
bun run dev || (kill $$BACKEND_PID 2>/dev/null && exit 1)
# Alias for run
dev: run
# Tauri desktop dev — starts backend (only — Tauri brings its own Vite) + opens the Tauri shell.
# Avoids the :1420 collision you'd get from running `make run` + `bun tauri:dev:desktop` together.
dev-desktop:
@echo "$(BLUE)→ Starting backend + Tauri desktop dev...$(NC)"
@-lsof -ti:8000 | xargs kill -9 2>/dev/null || true
@cd backend && bun run dev & \
BACKEND_PID=$$!; \
trap "kill $$BACKEND_PID 2>/dev/null" EXIT; \
echo "$(GREEN)✓ Backend started (PID: $$BACKEND_PID)$(NC)"; \
sleep 2; \
bun tauri:dev:desktop
# Tauri iOS dev on simulator. Targets the first booted simulator by NAME to avoid
# Wi-Fi-paired iPhones being auto-selected by `tauri ios dev`. NB: `tauri ios dev`
# matches devices by name, not UDID — passing a UDID fails to match (logs
# "Could not find an iOS Simulator matching {t}") and degrades to opening Xcode
# without hosting the dev options socket, which then breaks the build phase.
dev-ios:
@echo "$(BLUE)→ Starting backend + Tauri iOS simulator dev...$(NC)"
@-lsof -ti:8000 | xargs kill -9 2>/dev/null || true
@SIM_NAME=$$(xcrun simctl list devices booted 2>/dev/null | grep -m1 'Booted' | sed -E 's/^ *//; s/ *\(.*//'); \
if [ -z "$$SIM_NAME" ]; then \
echo "$(YELLOW)⚠ No booted simulator. Boot one first: open -a Simulator$(NC)"; \
exit 1; \
fi; \
echo "$(GREEN)✓ Targeting simulator $$SIM_NAME$(NC)"; \
cd backend && bun run dev & \
BACKEND_PID=$$!; \
trap "kill $$BACKEND_PID 2>/dev/null" EXIT; \
sleep 2; \
bun tauri ios dev --config src-tauri/tauri.dev.conf.json "$$SIM_NAME"
# Tauri Android dev. Re-runs init with the dev config first so the package paths match
# the .dev identifier (the chart's gen/android is committed for the prod identifier).
dev-android-init:
@echo "$(BLUE)→ Re-initializing Android project for dev identifier...$(NC)"
@rm -rf src-tauri/gen/android
@bun tauri android init --config src-tauri/tauri.dev.conf.json
dev-android: dev-android-init
@echo "$(BLUE)→ Starting backend + Tauri Android dev...$(NC)"
@-lsof -ti:8000 | xargs kill -9 2>/dev/null || true
@cd backend && bun run dev & \
BACKEND_PID=$$!; \
trap "kill $$BACKEND_PID 2>/dev/null" EXIT; \
sleep 2; \
bun tauri:dev:android
# Desktop release build that skips updater signing (for local artifact testing).
# Real releases use the CI flow which provides TAURI_SIGNING_PRIVATE_KEY.
build-desktop-local:
@echo "$(BLUE)→ Building desktop app (no updater bundle)...$(NC)"
@bun install
@bun tauri build --bundles app dmg
@echo "$(GREEN)✓ Built. App: src-tauri/target/release/bundle/macos/Thunderbolt.app$(NC)"
# Environment doctor (use `make doctor-q` for quiet mode — only shows issues)
doctor:
@bash scripts/thunderdoctor.sh
doctor-q:
@bash scripts/thunderdoctor.sh --quiet
# Container management
up:
@echo "$(BLUE)→ Starting containers...$(NC)"
$(COMPOSE) -f powersync-service/docker-compose.yml up -d
@echo "$(GREEN)✓ Containers started!$(NC)"
down:
@echo "$(BLUE)→ Stopping containers...$(NC)"
$(COMPOSE) -f powersync-service/docker-compose.yml down
@echo "$(GREEN)✓ Containers stopped!$(NC)"
nuke:
@bash scripts/docker-nuke.sh
status:
@bash scripts/docker-status.sh
# Thunderbot skill sync
thunderbot-pull:
@echo "$(BLUE)→ Pulling latest skills from thunderbot...$(NC)"
git subtree pull --prefix=.thunderbot thunderbot main --squash
@$(MAKE) setup-symlinks
@echo "$(GREEN)✓ Skills updated!$(NC)"
thunderbot-push:
@echo "$(BLUE)→ Pushing skill changes to thunderbot...$(NC)"
git subtree push --prefix=.thunderbot thunderbot main
@echo "$(GREEN)✓ Skills pushed!$(NC)"
thunderbot-customize:
@if [ -z "$(FILE)" ]; then echo "Usage: make thunderbot-customize FILE=thunderfix.md"; exit 1; fi
@if [ ! -L ".claude/commands/$(FILE)" ]; then echo "$(YELLOW).claude/commands/$(FILE) is not a symlink — already customized or doesn't exist$(NC)"; exit 1; fi
@rm ".claude/commands/$(FILE)" && cp ".thunderbot/$(FILE)" ".claude/commands/$(FILE)"
@echo "$(GREEN)✓ .claude/commands/$(FILE) is now a local copy — edit freely$(NC)"