The kanna command runs the kanna family of Go code generators in the order they need,
so that a project keeps no list of packages for it. It adds no configuration: what it runs is the
//go:generate go tool kanna-* lines already there, and each generator goes on working without it.
Install
go get -tool github.com/go-kanna/kanna@latestEach generator it runs has to be a release that answers -deps, which kanna gen tells you when one is not.
Usage
$ go tool kanna gen
internal/feature/todo/model/todo_model.go:15 kanna-value wrote internal/feature/todo/model/value_gen.go
internal/feature/todo/model/todo_model.go:42 kanna-fixture unchanged
internal/feature/todo/usecase/generate.go:3 kanna-validate wrote internal/feature/todo/usecase/validate_gen.go
...
11 tasks, 2 files changed
With nothing to do it says 11 tasks, 0 files changed, and no more. The first task to fail stops the run, and what the
tasks before it wrote stays:
completed internal/feature/todo/model/todo_model.go:15 kanna-value wrote internal/feature/todo/model/value_gen.go
failed internal/feature/todo/mapper/todo_mapper.go:10 kanna-mapper
./todo_mapper.go:32:13: error: cannot use "x" (untyped string constant) as int value in variable declaration
not run internal/feature/todo/handler/todo_handler.go:15 kanna-di
1 completed, 1 failed, 1 not run
1 file changed; completed changes remain in the working tree
Packages narrow it down, as for the go command. ./... is the default. The packages bring along what writes what they
read, and not what reads them.
go tool kanna gen --plan prints what would run, and why in that order, running nothing:
$ go tool kanna gen --plan
...
8. internal/feature/todo/usecase/generate.go:3
run: go tool kanna-validate
writes: internal/feature/todo/usecase/validate_gen.go
after: 5 — reads internal/feature/todo/scopes, which kanna-orm writes into
after: 7 — reads internal/messages, which kanna-i18n writes into
9. internal/feature/todo/usecase/generate.go:4
run: go tool kanna-di
writes: internal/feature/todo/usecase/di_gen.go
after: 2 — its tests read internal/di, which kanna-di writes into
after: 4 — its tests read internal/feature/todo/model/fixture, which kanna-fixture writes into
after: 6 — its tests read internal/feature/todo/postgres, which kanna-orm writes into
after: 8 — code in internal/feature/todo/usecase calls what kanna-validate generates
...
external prerequisites:
internal/gen/showcase/todo/v1 — generated by protoc-gen-go, protoc-gen-go-grpc
go tool kanna gen --check compares what is on disk with what would be generated, and writes nothing. It fails on a
file that differs, and on a task it could not check, which is one that reads what a differing task would write:
- run: go tool kanna gen --checkWhat it does and does not run
A task is one //go:generate go tool kanna-* line, run as go generate runs it: in its package's directory, with
GOFILE and the rest, and with the line's quotes and $ variables read the same way. The same line twice in a package
runs once.
Before starting, it refuses a plan with tasks waiting for each other, two tasks writing one file, an input that is not
there, or a line that means to run a generator some other way: a -command alias, a shell, another executable, or
kanna-orm describe. Other generators' lines it leaves alone, so what buf or sqlc write has to be there first, and is
theirs to check.
How the order is worked out
Each generator answers -deps with what a run reads and writes, and the module's hand-written files say what imports
what. A task comes after what writes into a package it reads. What generators wrote is left out of all of it, so that a
plan is the same before they have run and after.
Two tasks writing into a package they both read are told apart by what the code calls: a task checks that code once its
output is in place, so it comes after what writes what the code calls. When the code calls what both write, no order
compiles, and go generate cannot get through it from nothing. kanna gen runs one first and tells it the other's
names are coming, and the last to run finds them there, or reports them.
Developing the family
DEVELOPING.md says how to change the family across repositories: the workspace of every checkout in
dev, a script running every repository's tests against it, and the order releases go in.
Earlier versions of this module
github.com/go-kanna/kanna used to be another module, kanna v0.2.x with the first kanna-orm. Its versions, v0.0.1 to
v0.2.0, stay in the Go module proxy, retracted so that go get warns of them, and its code on the
archive/v0.2 branch of the site's repository. The
kanna command starts above them, at v0.3.0.