go-forge/docs/wiki/Code-Generation.md
Snider f5f796cd16 docs: wiki documentation for go-forge
Seven pages covering Home, Architecture, Services, Code Generation,
Configuration, Error Handling, and Development.

Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 17:14:01 +00:00

125 lines
3.6 KiB
Markdown

# Code Generation
All Go types in the `types/` package are generated from the Forgejo Swagger 2.0 specification. This page explains how the pipeline works and how to regenerate types.
## Pipeline
```
testdata/swagger.v1.json
|
v
cmd/forgegen/parser.go (parse spec, extract types, detect CRUD pairs)
|
v
cmd/forgegen/generator.go (group types by domain, emit Go source)
|
v
types/*.go (229 types across 36 files)
```
## Regenerating Types
```bash
go generate ./types/...
```
This runs the `//go:generate` directive in `types/generate.go`:
```go
//go:generate go run ../cmd/forgegen/ -spec ../testdata/swagger.v1.json -out .
```
You can also run the generator directly:
```bash
go run ./cmd/forgegen/ -spec testdata/swagger.v1.json -out types/
```
## Upgrading Forgejo Version
1. Download the new `swagger.v1.json` from your Forgejo instance at `/swagger.json`.
2. Replace `testdata/swagger.v1.json` with the new file.
3. Regenerate types:
```bash
go generate ./types/...
```
4. Verify compilation:
```bash
go build ./...
```
5. Run tests:
```bash
go test ./...
```
6. Review the diff for new, changed, or removed types.
## How It Works
### Parser (`cmd/forgegen/parser.go`)
- **`LoadSpec`** — reads and parses the JSON spec file.
- **`ExtractTypes`** — converts all `definitions` into `GoType` structs with fields, JSON tags, and Go type mappings.
- **`DetectCRUDPairs`** — finds matching `Create*Option`/`Edit*Option` pairs (e.g. `CreateRepoOption` + `EditRepoOption` = base `Repo`).
Type mapping rules:
| Swagger Type | Go Type |
|--------------------|----------------|
| `string` | `string` |
| `string` + `date-time` | `time.Time` |
| `string` + `binary` | `[]byte` |
| `integer` + `int64` | `int64` |
| `integer` + `int32` | `int32` |
| `boolean` | `bool` |
| `number` + `float` | `float32` |
| `number` | `float64` |
| `array` | `[]<item type>`|
| `object` | `map[string]any`|
| `$ref` | `*<TypeName>` |
### Generator (`cmd/forgegen/generator.go`)
- **`classifyType`** — assigns each type to a domain file (e.g. `Repository` -> `repo.go`, `Issue` -> `issue.go`).
- **`Generate`** — groups types by file, sorts alphabetically, and writes each file.
- **`writeFile`** — uses `text/template` to emit valid Go with `package types`, conditional `import "time"`, and `// Code generated` headers.
### Type Grouping
Types are grouped by prefix matching against a domain map:
| Prefix/Name | File |
|------------------|-----------------|
| `Repository`, `Repo` | `repo.go` |
| `Issue` | `issue.go` |
| `PullRequest`, `Pull` | `pr.go` |
| `User` | `user.go` |
| `Organization`, `Org` | `org.go` |
| `Team` | `team.go` |
| `Branch` | `branch.go` |
| `Release` | `release.go` |
| `Hook` | `hook.go` |
| `Commit`, `Git` | `commit.go`/`git.go` |
| `Package` | `package.go` |
| `Action`, `Secret`, `Variable` | `action.go` |
| `Notification` | `notification.go` |
| `Wiki` | `wiki.go` |
| (unmatched) | `misc.go` |
## Generated File Format
Each file follows this structure:
```go
// Code generated by forgegen from swagger.v1.json — DO NOT EDIT.
package types
import "time" // only if time.Time fields are present
// TypeName — description from swagger spec.
type TypeName struct {
FieldName GoType `json:"field_name,omitempty"`
}
```
Fields marked as `required` in the spec omit the `,omitempty` JSON tag option.