kanna コマンドは、kanna コードジェネレータファミリーを、必要な順序で実行します。パッケージの一覧をプロジェクトで持つ必要がなくなります。設定は増えません。実行するのは、すでにある //go:generate go tool kanna-* の行です。各ジェネレータは、このコマンドがなくても今までどおり動きます。
インストール
go get -tool github.com/go-kanna/kanna@latest実行するジェネレータは、-deps に答えられるリリースである必要があります。そうでないものがあれば kanna gen が伝えます。
使い方
$ 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
何もすることがなければ 11 tasks, 0 files changed の一行だけです。最初に失敗した task で止まり、それより前の task が書いたものは残ります。
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
go コマンドと同じくパッケージで絞り込めます。既定は ./... です。指定したパッケージが読むものを書く task は一緒に実行し、それを読む task は実行しません。
go tool kanna gen --plan は、何も実行せず、実行するものとその順序の理由を表示します。
$ 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 は、ディスク上の内容と生成される内容を比較し、何も書き込みません。差分のあるファイルがあるとき、および検査できなかった task があるときに失敗します。検査できないのは、差分のある task が書くものを読む task です。
- run: go tool kanna gen --check実行するもの、しないもの
task は //go:generate go tool kanna-* の一行で、go generate と同じように実行します。パッケージのディレクトリで、GOFILE などの環境変数付きで実行し、行の引用符や $ の変数も同じように読みます。同じパッケージに同じ行が二つあれば、一回だけ実行します。
次の計画は、開始する前に拒否します。task が互いを待っているもの、二つの task が同じファイルを書くもの、入力が存在しないもの、そしてジェネレータを別の形で実行しようとする行です。別の形とは、-command エイリアス、シェル、別の実行ファイル、kanna-orm describe です。他のジェネレータの行には触れません。buf や sqlc が書くものは先に用意しておく必要があり、その検査もそれぞれのツールの役目です。
順序の決まり方
各ジェネレータは、-deps に対して一回の実行が読むものと書くものを答えます。どのパッケージが何を import するかは、モジュールの手書きのファイルからわかります。task は、自分が読むパッケージに書き込む task の後に実行します。ジェネレータが書いたものはどこにも使わないので、ジェネレータの実行前でも実行後でも計画は変わりません。
二つの task が、どちらも読むパッケージに書き込むときは、コードが何を呼んでいるかで順序を決めます。task は出力を置いた後でそのコードを検査するので、コードが呼ぶものを書く task の後に実行します。コードが両方の書くものを呼んでいると、どの順序でもコンパイルが通らず、go generate では何もない状態から生成できません。kanna gen は片方を先に実行し、もう一方の名前がこれから書かれることを伝えます。最後に実行する task の時点でその名前が揃っていなければ、エラーとして報告します。
ファミリーの開発
DEVELOPING.md には、複数のリポジトリにまたがる変更のしかたを書いています。dev にある全チェックアウトのワークスペース、それに対して全リポジトリのテストを実行するスクリプト、リリースの順序です。
このモジュールの以前のバージョン
github.com/go-kanna/kanna は、以前は別のモジュール(kanna v0.2.x と初代の kanna-orm)でした。そのバージョン v0.0.1 から v0.2.0 は Go モジュールプロキシに残っていますが、取り下げてあるので go get が警告を出します。コードはサイトのリポジトリの archive/v0.2 ブランチにあります。kanna コマンドは、それより上の v0.3.0 から始まります。