Skip to content

Commit b807fe9

Browse files
authored
Add CLAUDE.md development documentation (#4148)
1 parent 92e5a24 commit b807fe9

File tree

1 file changed

+308
-0
lines changed

1 file changed

+308
-0
lines changed

‎CLAUDE.md‎

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
# Claude Code Development Guide for sqlc
2+
3+
This document provides essential information for working with the sqlc codebase, including testing, development workflow, and code structure.
4+
5+
## Quick Start
6+
7+
### Prerequisites
8+
9+
- **Go 1.25.0+** - Required for building and testing
10+
- **Docker & Docker Compose** - Required for integration tests with databases
11+
- **Git** - For version control
12+
13+
### Running Tests
14+
15+
#### Basic Unit Tests (No Database Required)
16+
17+
```bash
18+
# Simplest approach - runs all unit tests
19+
go test ./...
20+
21+
# Using make
22+
make test
23+
```
24+
25+
#### Full Test Suite with Integration Tests
26+
27+
```bash
28+
# Step 1: Start database containers
29+
docker compose up -d
30+
31+
# Step 2: Run all tests including examples
32+
go test --tags=examples -timeout 20m ./...
33+
34+
# Or use make for the full CI suite
35+
make test-ci
36+
```
37+
38+
#### Running Specific Tests
39+
40+
```bash
41+
# Test a specific package
42+
go test ./internal/config
43+
go test ./internal/compiler
44+
45+
# Run with verbose output
46+
go test -v ./internal/config
47+
48+
# Run a specific test function
49+
go test -v ./internal/config -run TestConfig
50+
51+
# Run with race detector (recommended for concurrency changes)
52+
go test -race ./internal/config
53+
```
54+
55+
## Test Types
56+
57+
### 1. Unit Tests
58+
59+
- **Location:** Throughout the codebase as `*_test.go` files
60+
- **Run without:** Database or external dependencies
61+
- **Examples:**
62+
- `/internal/config/config_test.go` - Configuration parsing
63+
- `/internal/compiler/selector_test.go` - Compiler logic
64+
- `/internal/metadata/metadata_test.go` - Query metadata parsing
65+
66+
### 2. End-to-End Tests
67+
68+
- **Location:** `/internal/endtoend/`
69+
- **Requirements:** `--tags=examples` flag and running databases
70+
- **Tests:**
71+
- `TestExamples` - Main end-to-end tests
72+
- `TestReplay` - Replay tests
73+
- `TestFormat` - Code formatting tests
74+
- `TestJsonSchema` - JSON schema validation
75+
- `TestExamplesVet` - Static analysis tests
76+
77+
### 3. Example Tests
78+
79+
- **Location:** `/examples/` directory
80+
- **Requirements:** Tagged with "examples", requires live databases
81+
- **Databases:** PostgreSQL, MySQL, SQLite examples
82+
83+
## Database Services
84+
85+
The `docker-compose.yml` provides test databases:
86+
87+
- **PostgreSQL 16** - Port 5432
88+
- User: `postgres`
89+
- Password: `mysecretpassword`
90+
- Database: `postgres`
91+
92+
- **MySQL 9** - Port 3306
93+
- User: `root`
94+
- Password: `mysecretpassword`
95+
- Database: `dinotest`
96+
97+
### Managing Databases
98+
99+
```bash
100+
# Start databases
101+
make start
102+
# or
103+
docker compose up -d
104+
105+
# Stop databases
106+
docker compose down
107+
108+
# View logs
109+
docker compose logs -f
110+
```
111+
112+
## Makefile Targets
113+
114+
```bash
115+
make test # Basic unit tests only
116+
make test-examples # Tests with examples tag
117+
make build-endtoend # Build end-to-end test data
118+
make test-ci # Full CI suite (examples + endtoend + vet)
119+
make vet # Run go vet
120+
make start # Start database containers
121+
```
122+
123+
## CI/CD Configuration
124+
125+
### GitHub Actions Workflow
126+
127+
- **File:** `.github/workflows/ci.yml`
128+
- **Go Version:** 1.25.0
129+
- **Test Command:** `gotestsum --junitfile junit.xml -- --tags=examples -timeout 20m ./...`
130+
- **Additional Checks:** `govulncheck` for vulnerability scanning
131+
132+
### Running Tests Like CI Locally
133+
134+
```bash
135+
# Install CI tools (optional)
136+
go install gotest.tools/gotestsum@latest
137+
138+
# Run tests with same timeout as CI
139+
go test --tags=examples -timeout 20m ./...
140+
141+
# Or use the CI make target
142+
make test-ci
143+
```
144+
145+
## Development Workflow
146+
147+
### Building Development Versions
148+
149+
```bash
150+
# Build main sqlc binary for development
151+
go build -o ~/go/bin/sqlc-dev ./cmd/sqlc
152+
153+
# Build JSON plugin (required for some tests)
154+
go build -o ~/go/bin/sqlc-gen-json ./cmd/sqlc-gen-json
155+
```
156+
157+
### Environment Variables for Tests
158+
159+
You can customize database connections:
160+
161+
**PostgreSQL:**
162+
```bash
163+
PG_HOST=127.0.0.1
164+
PG_PORT=5432
165+
PG_USER=postgres
166+
PG_PASSWORD=mysecretpassword
167+
PG_DATABASE=dinotest
168+
```
169+
170+
**MySQL:**
171+
```bash
172+
MYSQL_HOST=127.0.0.1
173+
MYSQL_PORT=3306
174+
MYSQL_USER=root
175+
MYSQL_ROOT_PASSWORD=mysecretpassword
176+
MYSQL_DATABASE=dinotest
177+
```
178+
179+
**Example:**
180+
```bash
181+
POSTGRESQL_SERVER_URI="postgres://postgres:mysecretpassword@localhost:5432/postgres" \
182+
go test -v ./...
183+
```
184+
185+
## Code Structure
186+
187+
### Key Directories
188+
189+
- `/cmd/` - Main binaries (sqlc, sqlc-gen-json)
190+
- `/internal/cmd/` - Command implementations (vet, generate, etc.)
191+
- `/internal/engine/` - Database engine implementations
192+
- `/postgresql/` - PostgreSQL parser and converter
193+
- `/dolphin/` - MySQL parser (uses TiDB parser)
194+
- `/sqlite/` - SQLite parser
195+
- `/internal/compiler/` - Query compilation logic
196+
- `/internal/codegen/` - Code generation for different languages
197+
- `/internal/config/` - Configuration file parsing
198+
- `/internal/endtoend/` - End-to-end tests
199+
- `/examples/` - Example projects for testing
200+
201+
### Important Files
202+
203+
- `/Makefile` - Build and test targets
204+
- `/docker-compose.yml` - Database services for testing
205+
- `/.github/workflows/ci.yml` - CI configuration
206+
- `/docs/guides/development.md` - Developer documentation
207+
208+
## Common Issues & Solutions
209+
210+
### Network Connectivity Issues
211+
212+
If you see errors about `storage.googleapis.com`, the Go proxy may be unreachable. Tests may still pass for packages that don't require network dependencies.
213+
214+
### Test Timeouts
215+
216+
End-to-end tests can take a while. Use longer timeouts:
217+
```bash
218+
go test -timeout 20m --tags=examples ./...
219+
```
220+
221+
### Race Conditions
222+
223+
Always run tests with the race detector when working on concurrent code:
224+
```bash
225+
go test -race ./...
226+
```
227+
228+
### Database Connection Failures
229+
230+
Ensure Docker containers are running:
231+
```bash
232+
docker compose ps
233+
docker compose up -d
234+
```
235+
236+
## Tips for Contributors
237+
238+
1. **Run tests before committing:** `make test-ci`
239+
2. **Check for race conditions:** Use `-race` flag when testing concurrent code
240+
3. **Use specific package tests:** Faster iteration during development
241+
4. **Start databases early:** `docker compose up -d` before running integration tests
242+
5. **Read existing tests:** Good examples in `/internal/engine/postgresql/*_test.go`
243+
244+
## Git Workflow
245+
246+
### Branch Naming
247+
248+
- Feature branches should start with `claude/` for Claude Code work
249+
- Branch names should be descriptive and end with the session ID
250+
251+
### Committing Changes
252+
253+
```bash
254+
# Stage changes
255+
git add <files>
256+
257+
# Commit with descriptive message
258+
git commit -m "Brief description
259+
260+
Detailed explanation of changes.
261+
262+
🤖 Generated with [Claude Code](https://claude.com/claude-code)
263+
264+
Co-Authored-By: Claude <noreply@anthropic.com>"
265+
266+
# Push to remote
267+
git push -u origin <branch-name>
268+
```
269+
270+
### Rebasing
271+
272+
```bash
273+
# Update main
274+
git checkout main
275+
git pull origin main
276+
277+
# Rebase feature branch
278+
git checkout <feature-branch>
279+
git rebase main
280+
281+
# Force push rebased branch
282+
git push --force-with-lease origin <feature-branch>
283+
```
284+
285+
## Resources
286+
287+
- **Main Documentation:** `/docs/`
288+
- **Development Guide:** `/docs/guides/development.md`
289+
- **CI Configuration:** `/.github/workflows/ci.yml`
290+
- **Docker Compose:** `/docker-compose.yml`
291+
292+
## Recent Fixes & Improvements
293+
294+
### Fixed Issues
295+
296+
1. **Typo in create_function_stmt.go** - Fixed "Undertand" → "Understand"
297+
2. **Race condition in vet.go** - Fixed Client initialization using `sync.Once`
298+
3. **Nil pointer dereference in parse.go** - Fixed unsafe type assertion in primary key parsing
299+
300+
These fixes demonstrate common patterns:
301+
- Using `sync.Once` for thread-safe lazy initialization
302+
- Using comma-ok idiom for safe type assertions: `if val, ok := x.(Type); ok { ... }`
303+
- Adding proper nil checks and defensive programming
304+
305+
---
306+
307+
**Last Updated:** 2025-10-21
308+
**Maintainer:** Claude Code

0 commit comments

Comments
 (0)