revive

Table of Contents

  1. 解決する問題
  2. 設定
  3. オプション
  4. 主要なルール
    1. 命名規則
    2. コードスタイル
    3. 複雑度・品質
  5. サンプル
    1. 検出例
    2. 修正例
  6. 注意点
  7. 参考リンク

revive は golint の後継となる高速で拡張可能な Go Linter です。

解決する問題

Go の標準的な Linter である golint は非推奨となり、設定の柔軟性やルールの拡張性に限界がありました。revive は golint 互換のルールに加え、100 以上のルールを備え、ルールごとの有効化・無効化・重大度設定が可能です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Before: revive が検出する問題の例

// 公開関数にドキュメントコメントがない
func ProcessData(data []byte) error {
return nil
}

// エラー変数の命名規則違反
var BadError = errors.New("bad") // Err プレフィックスがない

// 未使用のレシーバ名
func (s *Service) Health() string {
return "ok" // s を使っていない
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// After: revive の指摘に従い修正

// ProcessData はバイトデータを処理します。
func ProcessData(data []byte) error {
return nil
}

// ErrBad は不正な状態を表すエラーです。
var ErrBad = errors.New("bad")

// Health はサービスの状態を返します。
func (*Service) Health() string {
return "ok"
}

設定

公式ドキュメント

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# .golangci.yml 設定例
version: "2"

linters:
enable:
- revive
settings:
revive:
severity: warning
enable-default-rules: true
rules:
- name: exported
severity: warning
- name: error-naming
severity: warning
- name: var-naming
severity: warning
- name: unexported-return
severity: warning
- name: blank-imports
severity: warning
- name: context-as-argument
severity: error
- name: dot-imports
severity: warning
- name: error-return
severity: warning
- name: increment-decrement
severity: warning
- name: receiver-naming
severity: warning

オプション

オプション デフォルト 説明
severity string warning デフォルトの重大度(warning / error
confidence float 0.8 この信頼度未満の警告を無視する
enable-all-rules bool false すべてのルールを有効化する
enable-default-rules bool false 明示的なルール指定時もデフォルトルールを維持する
rules []rule [] ルールごとの設定(名前、重大度、引数、除外パターン)
directives []directive [] コメントディレクティブの設定

主要なルール

命名規則

ルール 検出内容
exported 公開シンボルにドキュメントコメントがない
var-naming 変数名が Go の命名規則に違反(mixedCaps でない等)
error-naming エラー変数に Err プレフィックスがない
receiver-naming レシーバ名が一貫していない、または長すぎる
package-comments パッケージコメントがない

コードスタイル

ルール 検出内容
blank-imports テスト以外でのブランクインポート
context-as-argument context.Context が第一引数でない
dot-imports ドットインポートの使用
error-return エラーが最後の戻り値でない
increment-decrement x += 1 の代わりに x++ を使うべき
unexported-return 公開関数が非公開型を返している

複雑度・品質

ルール 検出内容
cognitive-complexity 認知的複雑度が高い関数
cyclomatic 循環的複雑度が高い関数
function-length 関数が長すぎる
argument-limit 引数が多すぎる
confusing-naming 紛らわしい命名

サンプル

検出例

1
2
3
4
5
6
7
8
9
10
11
12
// context-as-argument: context.Context が第一引数でない
func FetchUser(id string, ctx context.Context) (*User, error) {
return nil, nil
}

// dot-imports: ドットインポート
import . "fmt"

// error-return: エラーが最後の戻り値でない
func Parse(s string) (error, *Result) {
return nil, nil
}

修正例

1
2
3
4
5
6
7
8
9
func FetchUser(ctx context.Context, id string) (*User, error) {
return nil, nil
}

import "fmt"

func Parse(s string) (*Result, error) {
return nil, nil
}

注意点

  • revive のルール挙動は独特で、明示的にルールを 1 つでも指定するとデフォルトルールが無効になる。enable-default-rules: true を併用するとデフォルトルールを維持できる
  • //revive:disable / //revive:enable ディレクティブで行やブロック単位で抑制できる
  • golangci-lint 経由では revive のフォーマッター設定は無視される(出力形式は golangci-lint が統一する)

参考リンク