🚀

Buf CLI v1.3.2リリースに伴う変更点

2024/06/07に公開

2024年5月にBuf CLIのv1.3.2がリリースされました。それに伴いbuf.yamlbuf.gen.yamlにおいてv2の設定を適用できるようになりました。また、それ以外にBSRのUIなどに変更があったり、Protobuf Editionsをサポートしたりなどの変更があったようです。

本記事では以下の公式ブログの内容をもとに変更箇所の紹介をしていきたいと思います。

https://buf.build/blog/buf-cli-next-generation

Bufについてまだ知らない方はこちらをご参考ください

https://zenn.dev/jy8752/books/33743f8091c39d

Buf モジュールのモノレポサポート

Buf CLIは各モジュールを別々のソース管理リポジトリで管理することを主な前提に設計されており、これは今でも変わりません。

しかし、実際の大規模なプロジェクトでは複数のProtobufモジュールをモノレポのように一つのリポジトリで管理したいというニーズが多かったようです。

このニーズに対応するためにBuf CLIはワークスペースという概念を取り入れbuf.work.yamlファイルを介して複数のProtobufモジュールを操作することを可能としました。

しかし、ワークスペースの機能は十分ではなく以下のような問題があったようです。

  • モノレポProtobufを一度にまとめてBSRにpushできない
  • 各モジュールが独自の依存関係を持つため、ワークスペース内のモジュール間で依存関係が衝突していた

このような問題は既存の設計では改善が難しいとBufチームは判断し、再設計を行なった結果モジュールとワークスペースの設定を一つのファイルにまとめワークスペース内のモジュールが同じ外部依存を共有するようにしました。

buf.yamlのv2対応

v2のbuf.yamlbuf.work.yamlと統合されワークスペースとそれぞれのモジュール設定を行います。

buf.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.yamlbuf.work.yamlがv2で統合された例です。

proto/buf.yaml
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
# 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
# buf.work.yaml
version: v1
directories:
  - proto
  - vendor

buf.yaml(v2)
buf.yaml
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のマネージドモードの設定は直感的ではなく何も見ないでこれらの設定を記述するには難しいと言っています。

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ではマネージドモードの設定をdisableoverrideという2つのカテゴリに分類することでエクスペリエンスを向上したとしています。

buf.gen.yaml
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フィールドに記述できるようになった。

buf.gen.yaml
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 initbuf config initに移動された。

v1 -> v2 へのマイグレーション

v1からv2への移行はBufチームがマイグレーションコマンドを用意してくれているので非常に簡単です。

buf config migrate

上記のコマンドを実行することで全てのbuf.yamlbuf.gen.yamlbuf.work.yamlを見つけそれらをv2のbuf.yamlbuf.gen.yamlにアップグレードする。

まとめ

  • Buf CLIはv1.3.2から設定ファイルにv2を使用できるようになった
  • buf.yamlのv2対応でProtobufモジュールのモノレポをサポートした
  • buf.work.yamlbuf.yamlに統合された
  • buf.gen.yamlのv2対応でマネージドモードの記載はより直感的になった
  • buf.gen.yamlのv2対応でbuf generateに指定していた引数やフラグを指定できるようになった
  • buf modのコマンドは全て移動された

最後にBufが掲げている単純なことを簡単にという言葉がすごく開発者っぽくて好きです。今回の変更もその言葉に従った変更です。

また、Bufチームは後方互換性に関して非常に気にしているため今まで通りv1のままでもまったく問題はないはずです。

ただ、より使いやすくなったと筆者は感じるので積極的にv2にアップグレードしていくことをおすすめいたします!

今回は以上です🐼

GitHubで編集を提案

Discussion