gRPC のコード差分
仕事で Go を使って gRPC の開発をしているとき、 同じ *.proto
から生成された *.pb.go
ファイルが人によって差分が生じるという問題が起こりました。
出てくる差分というのは、下記のように整形されていないコメントがあったとき、これから生成される *.pb.go
内のコメントが整形されたりされなかったりするというものです。
syntax = "proto3";
option go_package = "example.com/person";
// Person はプロフィールを表すメッセージです。
message Person {
optional string name = 1;
optional int32 id = 2;
optional string email = 3;
}
// Person は人のプロフィールを表します。
type Person struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name *string `protobuf:"bytes,1,opt,name=name,proto3,oneof" json:"name,omitempty"`
Id *int32 `protobuf:"varint,2,opt,name=id,proto3,oneof" json:"id,omitempty"`
Email *string `protobuf:"bytes,3,opt,name=email,proto3,oneof" json:"email,omitempty"`
}
// Person は人のプロフィールを表します。
type Person struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name *string `protobuf:"bytes,1,opt,name=name,proto3,oneof" json:"name,omitempty"`
Id *int32 `protobuf:"varint,2,opt,name=id,proto3,oneof" json:"id,omitempty"`
Email *string `protobuf:"bytes,3,opt,name=email,proto3,oneof" json:"email,omitempty"`
}
差分が出る原因
調べてみたところ、どうやら Go 1.19 を使うかどうかでコメントが整形されるかどうかの挙動が変わるようでした。リリースノートを読んでみると下記の通り gofmt
がコメントを整形するようになったことが原因のようです。
Doc Comments
Go 1.19 adds support for links, lists, and clearer headings in doc comments. As part of this change, gofmt now reformats doc comments to make their rendered meaning clearer. See “Go Doc Comments” for syntax details and descriptions of common mistakes now highlighted by gofmt. As another part of this change, the new package go/doc/comment provides parsing and reformatting of doc comments as well as support for rendering them to HTML, Markdown, and text.
つまり別に gRPC を使ってなくても単に Go ファイルを整形すれば、これまで未整形だったコメントは整形されるようになるということです。
gRPC のコメントが整形されるかどうかは protoc-gen-go
をインストールする際にどの Go バージョンでインストールしたかで変わってきます。
# go が 1.19 以上ならコメントが整形される
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
対策
根本原因は *.proto
ファイルのコメントが整形されていないことなので、まずはこれを整形してあげたいところです。
*.proto
ファイルの整形は clang-format
を使えばできるのですが、残念ながらコメントの整形には対応していないようです・・・
仕方がないので gRPC を生成するときだけ Go のバージョンを開発者全員で統一することにしました。
$ go install golang.org/dl/go1.18.9@latest
$ go1.18.9 download
$ go1.18.9 install google.golang.org/protobuf/cmd/protoc-gen-go@latest
まとめ
*.pb.go
は自分で整形するファイルじゃないので、原因特定で結構ハマりました。まさか protoc-gen-go
をビルドした Go バージョンで差分が出るとは・・・