Protobufの破壊的変更を検知するProto Breaking Change Detectorを使ってみた
概要
Protobufの破壊的変更を検知するProto Breaking Change Detectorというツールを使ってみたら、良さそうだった。 github.com
経緯
uber/protool を使うと破壊的変更を検知できるようだったが、リポジトリがarchiveされている。
prototoolの代替として示されているBufの破壊的変更検出 は、buf.yaml
をディレクトリに置くというBufのルールに従わなければ利用できない。(たぶん。やり方を知っている人がいたら教えて欲しい。)
方法
動かしてみる
mainブランチと現在のワークツリーで、破壊的変更が発生していないかチェックする。
Proto Breaking Change Detector をインストールする。
pip install git+https://github.com/googleapis/proto-breaking-change-detector.git
2つのディレクトリ間でのprotobufの破壊的変更を検知できる。
# --original_api_definition_dirs: 比較元の--proto-pathに指定するディレクトリをカンマ区切りで # --original_proto_files: 比較元のbeaking changeを検出したいファイルをカンマ区切りで # --update_api_definition_dirs: 比較先の--proto-pathに指定するディレクトリをカンマ区切りで # --update_proto_files: 比較先のbeaking changeを検出したいファイルをカンマ区切りで PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python proto-breaking-change-detector \ --original_api_definition_dirs=${ORIGINAL_PROTO_PATH} \ --update_api_definition_dirs=${UPDATE_PROTO_PATH} \ --original_proto_files=${ORIGINAL_FILE} \ --update_proto_files=${UPDATE_FILE} \ --human_readable_message
実行すると、detected_breaking_changes.json
というファイルが作られて、そこに非破壊的変更("change_type": "MINOR")や、破壊的変更("change_type": "MAJOR")を含む変更の情報が入る。
mainブランチからの破壊的変更を検知してみる
mainブランチと今いるブランチの間で、破壊的変更が無いか比較してみるために、サンプルコードを作った。 github.com
cloneしてブランチを切る。
git clone git@github.com:shiba6v/pbcd_trial.git cd pbcd_trial git checkout -b feature/hoge
元のmainブランチのproto/fuga/fuga.proto は、次のような定義にした。
syntax = "proto3"; import "hoge.proto"; message Fuga { int64 id = 1; Hoge hoge = 2; }
mainブランチをcloneしてきたままの状態で、proto-breaking-change-detector
を実行するスクリプトを実行する。
sh detect.sh
もちろんoriginのmainブランチから変更はないので、detected_breaking_changes.json
の中身は空になっている。
[]
次に、破壊的変更と非破壊的変更を加えてみる。
具体的にはHoge hoge = 2;
をstring hoge = 2;
に変更して、int64 count = 3;
を追加する。
syntax = "proto3"; import "hoge.proto"; message Fuga { int64 id = 1; string hoge = 2; int64 count = 3; }
再度sh detect.sh
すると、
$ sh detect.sh pbcd_trial/protobuf/src: warning: directory does not exist. pbcd_trial/protobuf/src: warning: directory does not exist. fuga.proto:3:1: warning: Import hoge.proto is unused. fuga.proto L7: The type of an existing field `hoge` is changed from `message` to `string` in message `..Fuga`.
mainブランチから見ると破壊的変更("change_type": "MAJOR")が起こっていることが確認できる。
[ { "category": "FIELD_ADDITION", "location": { "proto_file_name": "fuga.proto", "source_code_line": 8 }, "change_type": "MINOR", "extra_info": null, "subject": "count", "oldsubject": "", "context": "..Fuga", "type": "", "oldtype": "" }, { "category": "FIELD_TYPE_CHANGE", "location": { "proto_file_name": "fuga.proto", "source_code_line": 7 }, "change_type": "MAJOR", "extra_info": [ "message Fuga {", "hoge" ], "subject": "hoge", "oldsubject": "", "context": "..Fuga", "type": "string", "oldtype": "message" } ]
フィールドの追加は、非破壊的変更("change_type": "MINOR")と判定されており、これは正しい。
今後知りたいこと
- ファイルが追加されるときや、messageがファイルを移動したときはどう検知されるか?
protobuf/src: warning: directory does not exist.
のWarningを抑えたい。protobuf/src
がデフォルトで--proto-pathに追加されている。
結論
を使おう。