LoginSignup
6
3

More than 3 years have passed since last update.

Protocol Buffer - protolint の説明と CI 導入手順

Last updated at Posted at 2018-12-27

追記

VSCode と Intellij IDEA をはじめとした Jetbrains IDE 向けのプラグインが用意されている

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 に入れておくと良い。リリースしてしまうと、修正するのは大変なため。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3