Skip to content

Commit 1f2d6f0

Browse files
committed
Add CLAUDE.md development documentation
Added comprehensive development guide for working with the sqlc codebase, focusing on testing workflows and common development tasks. Documentation includes: - Quick start guide for running tests - Test types (unit, integration, end-to-end) - Database setup with Docker Compose - Makefile targets and CI/CD information - Development workflow and git practices - Common issues and solutions - Code structure overview This guide serves as a reference for Claude Code sessions and new contributors to quickly understand how to run tests and contribute to the project. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 92e5a24 commit 1f2d6f0

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 <[email protected]>"
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)