Buf CLI v1.3.2リリースに伴う変更点
2024年5月にBuf CLIのv1.3.2がリリースされました。それに伴いbuf.yaml
、buf.gen.yaml
においてv2
の設定を適用できるようになりました。また、それ以外にBSRのUIなどに変更があったり、Protobuf Editionsをサポートしたりなどの変更があったようです。
本記事では以下の公式ブログの内容をもとに変更箇所の紹介をしていきたいと思います。
Bufについてまだ知らない方はこちらをご参考ください
Buf モジュールのモノレポサポート
Buf CLIは各モジュールを別々のソース管理リポジトリで管理することを主な前提に設計されており、これは今でも変わりません。
しかし、実際の大規模なプロジェクトでは複数のProtobufモジュールをモノレポのように一つのリポジトリで管理したいというニーズが多かったようです。
このニーズに対応するためにBuf CLIはワークスペースという概念を取り入れbuf.work.yaml
ファイルを介して複数のProtobufモジュールを操作することを可能としました。
しかし、ワークスペースの機能は十分ではなく以下のような問題があったようです。
- モノレポProtobufを一度にまとめてBSRにpushできない
- 各モジュールが独自の依存関係を持つため、ワークスペース内のモジュール間で依存関係が衝突していた
このような問題は既存の設計では改善が難しいとBufチームは判断し、再設計を行なった結果モジュールとワークスペースの設定を一つのファイルにまとめワークスペース内のモジュールが同じ外部依存を共有するようにしました。
buf.yaml
のv2対応
v2のbuf.yaml
はbuf.work.yaml
と統合されワークスペースとそれぞれのモジュール設定を行います。
version: v2
# modules contains all of the modules defined within your source control repository.
#
# For the common case where there is a single module whose path is ".", this section
# can be omitted, and a module name can be specified at the top-level.
modules:
# Each module has a path.
# This is the path to the module relative to the location of the buf.yaml
#
# The name key is also available here. If names are specified for all modules in
# this buf.yaml, the entire workspace can be pushed to the BSR.
- path: proto
# A second module containing files that are locally vendored.
- path: vendor
# This module has its own lint configuration that is seperate from the default lint
# configuration applied to modules without individual lint configurations.
lint:
use:
- MINIMAL
ignore:
# All file paths in buf.yaml are now relative to the location of buf.yaml.
- vendor/files-not-on-bsr/a.proto
# Modules now share a common set of dependencies. This was the major concern with the v1
# buf.work.yaml and v1 buf.yaml setup - every module had its own (potentially conflicting)
# set of dependencies, which made simultaneously pushing the modules impossible, and led
# many commands within the buf CLI to effectively mash the dependencies together in ways
# not exposed to users.
#
# There will be a single buf.lock file produced, which lives alongside this buf.yaml.
deps:
- buf.build/googleapis/googleapis
- buf.build/grpc/grpc
# The default lint configuration applied to modules specified in this file.
lint:
use:
- DEFAULT
- UNARY_RPC
# The default breaking configuration applied to modules specified in this file.
breaking:
use:
- PACKAGE
見てわかる通り依存関係はモジュール全てにおいて同じものを共有し、buf.lock
ファイルも一つになります。lintやbreakingなどのモジュール設定はデフォルトとしてトップレベルに宣言することもできますし、モジュールそれぞれに設定することも可能です。
以下は公式ブログに記載のあったv1のbuf.yaml
とbuf.work.yaml
がv2で統合された例です。
proto/buf.yaml
# proto/buf.yaml
version: v1
deps:
- buf.build/googleapis/googleapis
lint:
use:
- DEFAULT
- UNARY_RPC
breaking:
use:
- PACKAGE
vendor/buf.yaml
# vendor/buf.yaml
version: v1
deps:
# vendor also depends on googleapis. This would mean that both proto/buf.lock and vendor/buf.lock
# would exist, potentially with conflicts.
- buf.build/googleapis/googleapis
- buf.build/grpc/grpc
lint:
use:
- MINIMAL
breaking:
use:
- PACKAGE
buf.work.yaml
# buf.work.yaml
version: v1
directories:
- proto
- vendor
buf.yaml(v2)
version: v2
modules:
- path: proto
name: buf.build/acme/finance
deps:
- buf.build/googleapis/googleapis
- buf.build/grpc/grpc
lint:
use:
- DEFAULT
- UNARY_RPC
breaking:
use:
- PACKAGE
buf.gen.yaml
のv2対応
buf.yaml
のv2対応に合わせてbuf.gen.yaml
もv2が使えるようになりました。Bufチームは公式ブログ内でbuf.gen.yaml
のマネージドモードの設定は直感的ではなく何も見ないでこれらの設定を記述するには難しいと言っています。
# This is a v1 example - we agree it is not great! Keep scrolling to see this
# cleaned up in v2.
version: v1
managed:
# Enable managed mode.
# This will result in file options being overridden for all Protobuf files.
enabled: true
# Override managed mode's default setting for the "optimize_for" file option by setting it to
# "CODE_SIZE" for all Protobuf files.
optimize_for: CODE_SIZE
# Override managed mode's default setting for the "go_package" file option for all Protobuf
# files.
go_package_prefix:
# go_package will be "github.com/acme/finance/gen/go/path/to/dir/of/proto_file" by default.
default: github.com/acme/finance/gen/go
except:
# Do not override go_package for any file coming from the
# buf.build/googleapis/googleapis module.
- buf.build/googleapis/googleapis
override:
# go_package will be "github.com/acme/billing/path/to/dir/of/proto_file" for any file
# coming from the buf.build/acme/billing module
buf.build/acme/billing: github.com/acme/billing
# Override managed mode's default setting for the "java_package" file option for all Protobuf
# files.
java_package_prefix:
# "java_package" will be "org.proto.package.name" by default.
default: "org"
override:
JAVA_PACKAGE:
# For the file at path acme/finance/v1/finance.proto, directly set the "java_package"
# file option to "org.finance".
acme/finance/v1/finance.proto: "org.finance"
Without comments, would you understand the exact behavior of the above configuration? Would you remember how to do this configuration if you had to reproduce it? We wrote the spec, and we both don't intuitively understand it, nor remember how to reproduce it without looking at our own docs. If we can't understand it, we shouldn't expect you to.
コメントなしで、上記のコンフィギュレーションの正確な動作を理解できるだろうか?もしこの設定を再現しなければならなくなった場合、どのように行うか覚えているだろうか?仕様書を書いたのは我々だが、我々二人とも直感的には理解できないし、自分のドキュメントを見ずに再現する方法も覚えていない。私たちが理解できないのであれば、あなたに期待すべきではない。 (DeepL翻訳)
また、buf generate
に続くフラグや引数を設定ファイルで記述することができないのも問題であると言っています。
v2のbuf.gen.yaml
ではマネージドモードの設定をdisable
とoverride
という2つのカテゴリに分類することでエクスペリエンスを向上したとしています。
version: v2
managed:
enabled: true
disable:
- file_option: go_package
module: buf.build/googleapis/googleapis
override:
- file_option: optimize_for
value: CODE_SIZE
- file_option: go_package_prefix
value: github.com/acme/finance/gen/go
# This rule takes precedence over the previous rule as it appears later in the override list.
- file_option: go_package_prefix
module: buf.build/acme/billing
value: github.com/acme/billing
- file_option: java_package_prefix
value: org
- file_option: java_package
path: acme/finance/v1/finance.proto
value: org.finance
v1では以下のようにフラグ指定はコマンド実行時につける必要があった。
buf generate proto \
--path proto/acme \
--exclude-path proto/acme/billing
buf generate vendor
buf generate https://github.com/acme/tax#branch=dev \
--path proto/acme/bar
v2では以下のように設定ファイルのinputs
フィールドに記述できるようになった。
version: v2
inputs:
- directory: proto
paths:
- proto/acme
exclude_paths:
- proto/acme/billing
- directory: vendor
- git_repo: https://github.com/acme/tax
branch: dev
buf mod
の廃止
Protobufモジュールのモノレポ対応の一環としてbuf mod
のコマンドをモジュール固有のコマンドとしてリストするのはあまり意味がなかったとして、buf mod
のコマンドを全て移動させた。全ての記載は省略しますが、例えばbuf mod init
はbuf config init
に移動された。
v1 -> v2 へのマイグレーション
v1からv2への移行はBufチームがマイグレーションコマンドを用意してくれているので非常に簡単です。
buf config migrate
上記のコマンドを実行することで全てのbuf.yaml
とbuf.gen.yaml
、buf.work.yaml
を見つけそれらをv2のbuf.yaml
とbuf.gen.yaml
にアップグレードする。
まとめ
- Buf CLIはv1.3.2から設定ファイルにv2を使用できるようになった
-
buf.yaml
のv2対応でProtobufモジュールのモノレポをサポートした -
buf.work.yaml
はbuf.yaml
に統合された -
buf.gen.yaml
のv2対応でマネージドモードの記載はより直感的になった -
buf.gen.yaml
のv2対応でbuf generate
に指定していた引数やフラグを指定できるようになった -
buf mod
のコマンドは全て移動された
最後にBufが掲げている単純なことを簡単にという言葉がすごく開発者っぽくて好きです。今回の変更もその言葉に従った変更です。
また、Bufチームは後方互換性に関して非常に気にしているため今まで通りv1のままでもまったく問題はないはずです。
ただ、より使いやすくなったと筆者は感じるので積極的にv2にアップグレードしていくことをおすすめいたします!
今回は以上です🐼
Discussion