# 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` | `[]`| | `object` | `map[string]any`| | `$ref` | `*` | ### 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.