Skip to content
anetos gen reference

anetos gen reference

anetos gen writes the typed columns of your models. It is part of the anetos developer tool (module anetos.dev/anetos/cli). See Generate typed columns for a walkthrough.

Installing and running

CommandDoes
go get -tool anetos.dev/anetos/cli/cmd/anetos@latestAdds the tool to your module’s go.mod
go tool anetos gen [packages]Generates for the packages (default ./..., relative to the current directory)
go tool anetos gen -check [packages]Writes nothing; exits with status 1 and lists the out-of-date files
go tool anetos versionPrints the tool’s version
//go:generate go tool anetos genRuns it from go generate ./...

Package patterns are the ones go build takes. Exit status: 0 on success, 1 on errors (or out-of-date files with -check), 2 for bad usage.

Which structs are models

A named, non-generic struct type declared at package level (in a non-test file) is a model when it:

RuleExample
Embeds db.Model, db.Timestamps or db.SoftDeletes, directly or through embedded structstype Post struct { db.Model; … }
Has a TableName() string method (value or pointer receiver)func (Setting) TableName() string
Has //anetos:model in its doc commenta plain struct

Models, and the structs of their package they embed, must be in files without build constraints (no //go:build line, no _linux.go-style name), so the generated file is the same on every platform. //anetos:skip in the doc comment excludes a struct. Any other //anetos: directive is an error. Structs that scan themselves (sql.Scanner, driver.Valuer, time.Time) are values, not models.

What is generated

One file per package, models_gen.go, starting with // Code generated by anetos gen. DO NOT EDIT. For each model Name in source order:

// illustrative
// NameCols are the columns of [Name].
var NameCols = struct {
	Field db.Column[FieldType]
	…
}{
	Field: db.Col[FieldType]("column"),
	…
}
FieldGenerated
Title stringTitle db.Column[string], column title
AuthorID int64 \db:“author”``AuthorID db.Column[int64], column author
PublishedAt *time.Timedb.Column[*time.Time] (compare with new(t), set NULL with nil)
Tags []string \db:“tags,json”``db.Column[[]string] made with db.JSONCol
Fields of embedded structs (db.Model: ID, CreatedAt, UpdatedAt)Flattened in place, like the runtime
Author *User \rel:“belongs_to”`, Comments []Comment `rel:“has_many”``A relation handle in PostRels: Author db.Rel[Post, User], made with db.RelOf[Post, User]("Author")
Untagged struct, pointer-to-struct and slice-of-struct fieldsNothing
db:"-" and unexported fieldsNothing

The column rules are the db package’s (models reference). The generated names are the struct field names; an unexported model post gets postCols. Imports get another name (time2) when the package already declares that name in any of its files (in-package tests and other platforms’ files included).

Files it manages

  • It only overwrites or removes a models_gen.go that starts with its header (Unix or Windows line endings); any other file with that name is an error, even one excluded from the build.
  • It removes models_gen.go from a package with no models left.
  • It ignores the current models_gen.go while reading the package, and compile errors outside model fields (such as code using a column not generated yet). Syntax errors, and type errors in a model’s fields, stop it.
  • Packages are only type-checked when they import the db package (directly or not), mention TableName or a //anetos: directive, or already have a models_gen.go.

Errors

MessageMeaning
two fields map to column "x"Two fields have the same column name
unknown db tag option "x" (known: pk, json, readonly)A typo in a db tag
more than one pk fieldComposite keys aren’t supported by models
columns "a" and "b" both come from fields named XTwo fields (one embedded) share a Go name; rename one
XCols is already declared, XRels is already declaredThe package declares a name anetos gen needs
unknown relation "x", bad has_many option "x"A typo in a rel tag
a has_many relation is a slice of models, … a pointer to a modelThe field’s type doesn’t fit the relation kind
field X has a db tag and a rel tagA field is a column or a relation, not both
field X has …, which package … can't nameAn embedded struct from another package has a field of an unexported type, a type from an internal package yours can’t import, or an anonymous struct with unexported fields; tag it db:"-" or change the embedded struct
models in files with build constraints aren't supported, embeds X, declared in a file with build constraintsThe model, or a struct of the package it embeds, is in a _linux.go-style file or one with a //go:build line: the generated file would differ per platform
embeds itselfA struct embeds itself through a pointer
generic types and aliases can't be models//anetos:model on a generic type or alias
is marked //anetos:model but is not a model structThe type isn’t a struct, or scans itself
models_gen.go was not written by anetos genRename your file