# go-ocds (ocdsgen) OCDS 1.1 types for Go, with extensions chosen per package. The module contains a generator and some ready-made profiles: cmd/ocdsgen/ CLI entry point (Cobra) internal/cli/ command definitions: generate, resolve, schema internal/generator/ fetch, resolve, merge and emit (no CLI code) profiles/core/ no extensions profiles/eu/ EU profile profiles/uk/ UK extension to the EU profile profiles/findTender/ UK gov Find A Tender service profile with extensions example/ a consumer module generating its own packages Every generated package is self-contained: it imports only the standard library, so a package's types depend only on its own extensions.json. ## Use a ready-made profile go get git.avsdev.uk/Go/go-ocds@v1.0.0 import "git.avsdev.uk/Go/go-ocds/profiles/uk" var r uk.Release ## Generate your own packages Give each package its own `extensions.json` and a directive: //go:generate go tool ocdsgen generate -c extensions.json -o ocds_gen.go -p tenders Pin the generator in your go.mod (Go 1.24+): go get -tool git.avsdev.uk/Go/go-ocds/cmd/ocdsgen@v1.0.0 On older Go, add a `tools.go` with a blank import of `git.avsdev.uk/Go/go-ocds/cmd/ocdsgen` behind `//go:build tools`, and use `go run git.avsdev.uk/Go/go-ocds/cmd/ocdsgen` in the directive (see example/). Then `go generate ./...` and commit the generated `ocds_gen.go` files. ## Commands ocdsgen generate [-c extensions.json] [-o ocds_gen.go] [-p name] [--check] ocdsgen resolve [-c extensions.json] [--json] ocdsgen schema [-c extensions.json] [--kind release|package] [-o file] Global flags: `--strict` fails on any warning, `-q/--quiet` hides notes and warnings, `--timeout` sets the per-request HTTP timeout. Run `ocdsgen --help` for details. - `generate` writes the Go types. `-p` defaults to the output directory's name. `-o -` writes to stdout. `--check` writes nothing and fails if the file is missing or stale, for CI: `ocdsgen generate --check --strict`. - `resolve` lists every extension the config pulls in, dependencies first, in the order their patches are applied. - `schema` writes the merged JSON Schema the types are generated from, for debugging a config or validating data with other tools. Paths in a config that aren't URLs are resolved relative to the config file, so a project can keep private or vendored extensions alongside it. ## Adding a profile to this module Create `profiles//` with `extensions.json` and a `generate.go` like the existing ones, run `go generate ./...`, and tag a release. ## Generator warnings - two extensions give the same field different types (the later one wins); - the same extension repo is included at two versions; - a definition is never referenced, which usually means an extension patches a type (e.g. `Lot`) whose defining extension (e.g. Lots) isn't in the config. ## Type mapping - `date-time` → `*time.Time`, - `integer` → `*int`, - `number` → `*float64`, - `boolean` → `*bool`, - `["string","integer"]` → `ID`, - objects without properties → `map[string]any`, - anything ambiguous → `json.RawMessage`. - All non-required fields are `omitempty`.