追記
VSCode と Intellij IDEA をはじめとした Jetbrains IDE 向けのプラグインが用意されている
- plexsystems/vscode-protolint: A protobuf linter for visual studio code
- yoheimuta/intellij-protolint: A protobuf linter for JetBrains IDEs
protolint
protolint は Protocol Buffer ファイル(proto3) のリントを行うコマンドラインツールである。
現在のところ、Google のスタイルガイド準拠をサポートしている。
特徴は次の通り。
- 処理が早い。内部的にはパースするだけなので、少なくともコンパイラーのアドオンによるものより高速。
- Google のスタイルガイドとルールが 1対1 で対応している。
- ファイルのコメントでリントルールの除外ができる。
ファイルのコメントでリントルールの除外ができるのは、すでにリリース済みのプロダクトでは特に有用。
除外範囲を最小限にしつつ、新規の定義にはルールを適用できる。
enum Foo {
// protolint:disable:next ENUM_FIELD_NAMES_UPPER_SNAKE_CASE
firstValue = 0; // no error
second_value = 1; // protolint:disable:this ENUM_FIELD_NAMES_UPPER_SNAKE_CASE
THIRD_VALUE = 2; // spits out an error
}
ルール
現在(2018.12.27)、サポートしているルールは次の 6 つ。
ID | Purpose |
---|---|
ENUM_FIELD_NAMES_UPPER_SNAKE_CASE | enum フィールド名が CAPITALS_WITH_UNDERSCORES かチェックする |
ENUM_NAMES_UPPER_CAMEL_CASE | enum 名 が CamelCase (with an initial capital) かチェックする |
FIELD_NAMES_LOWER_SNAKE_CASE | field 名が underscore_separated_names かチェックする |
MESSAGE_NAMES_UPPER_CAMEL_CASE | message 名が CamelCase (with an initial capital) かチェックする |
RPC_NAMES_UPPER_CAMEL_CASE | rpc 名が CamelCase (with an initial capital) かチェックする |
SERVICE_NAMES_UPPER_CAMEL_CASE | service 名が CamelCase (with an initial capital) かチェックする |
以下はそれぞれのルールの例。
-
がスタイル違反で、+
がスタイル準拠。
ENUM_FIELD_NAMES_UPPER_SNAKE_CASE
enum Foo {
- firstValue = 0;
+ FIRST_VALUE = 0;
- second_value = 1;
+ SECOND_VALUE = 1;
}
ENUM_NAMES_UPPER_CAMEL_CASE
- enum foobar {
+ enum FooBar {
FIRST_VALUE = 0;
SECOND_VALUE = 1;
}
FIELD_NAMES_LOWER_SNAKE_CASE
message SongServerRequest {
- required string SongName = 1;
+ required string song_name = 1;
}
MESSAGE_NAMES_UPPER_CAMEL_CASE
- message song_server_request {
+ message SongServerRequest {
required string SongName = 1;
required string song_name = 1;
}
RPC_NAMES_UPPER_CAMEL_CASE
service FooService {
- rpc get_something(FooRequest) returns (FooResponse);
+ rpc GetSomething(FooRequest) returns (FooResponse);
}
RPC_NAMES_UPPER_CAMEL_CASE
- service foo_service {
+ service FooService {
rpc get_something(FooRequest) returns (FooResponse);
rpc GetSomething(FooRequest) returns (FooResponse);
}
使い方
pl lint example.proto example2.proto # file mode, specify multiple specific files
pl lint . # directory mode, search for all .proto files recursively
pl . # same as "pl lint ."
pl list # list all current lint rules being used
例えば、スタイル違反が見つかると、以下のようなエラーメッセージが出る。また、exit code 1 を返す。
❯❯❯ pl .
[v1/master/master.proto:30:5] Field name "shouldInvalidate" must be LowerSnakeCase
[v1/search/search.proto:45:5] Field name "brandEnds" must be LowerSnakeCase
[v1/support/marketing.proto:62:5] Field name "announcementInApp" must be LowerSnakeCase
[v1/support/marketing.proto:64:5] Field name "announcementApns" must be LowerSnakeCase
[v1/values/itemContentCondition.proto:35:5] EnumField name "Unidentified" must be UpperSnakeCase
❯❯❯ ~/.go/bin/pl list
ENUM_FIELD_NAMES_UPPER_SNAKE_CASE: Verifies that all enum field names are CAPITALS_WITH_UNDERSCORES.
ENUM_NAMES_UPPER_CAMEL_CASE: Verifies that all enum names are CamelCase (with an initial capital).
FIELD_NAMES_LOWER_SNAKE_CASE: Verifies that all field names are underscore_separated_names.
MESSAGE_NAMES_UPPER_CAMEL_CASE: Verifies that all message names are CamelCase (with an initial capital).
RPC_NAMES_UPPER_CAMEL_CASE: Verifies that all rpc names are CamelCase (with an initial capital).
SERVICE_NAMES_UPPER_CAMEL_CASE: Verifies that all service names are CamelCase (with an initial capital).
CircleCI での導入手順
.circleci/config.yaml を作成するだけ。
以下はリポジトリ直下すべてに再帰的に lint 処理を行う。
version: 2
jobs:
lint:
docker:
- image: circleci/golang:1.11.4
environment:
GO111MODULE: "on"
steps:
- checkout
- run:
name: Enforce Protocol Buffer style and conventions.
command: |
go get -u -v github.com/yoheimuta/protolint/cmd/pl
pl lint .
workflows:
version: 2
lint:
jobs:
- lint
まとめ
十分気をつけていると思っていたプロジェクトでも、スタイル違反が見つかったので、早速導入した。
最初からリントプロセスは CI に入れておくと良い。リリースしてしまうと、修正するのは大変なため。