Slide 1

Slide 1 text

プロジェクトのルールを チェックするためのlint mercari.go#4

Slide 2

Slide 2 text

目次 ● 自己紹介 ● golint ● チームで取り入れたいルール ● テストのために取り入れたいルール ● パッケージの役割を分けるために取り入れたいルール ● ルールをチームで共有する方法 ● ルール表現のために作成したツール「self-lint」 ● まとめ

Slide 3

Slide 3 text

自己紹介 ● 名前 ○ 水野 敬太 ● github ○ mizkei ● twitter ○ @mizkei11 ● 仕事 ○ Backend/マイクロサービス開発

Slide 4

Slide 4 text

golint

Slide 5

Slide 5 text

golintによるコーディングスタイルの指摘 ● Effective Go や Go Code Review Comments に基づいた指摘 ○ 不要なelse ○ コメントのフォーマット ○ context.WithValueのkeyの型 ○ 変数・パッケージ名 ○ import Dot ○ main以外でのblank import ○ ...

Slide 6

Slide 6 text

golintによるコーディングスタイルの指摘 ● プロジェクトにおけるコードの書き方がある程度統一される ● エディタの設定をすれば、編集しながら確認可能 ● reviewdog にログを食べてもらえば、github上でも指摘される 綺麗なGoのコードを書くためのルールとしては非常に有用だが、 チームのローカルルールが欲しい場合もある

Slide 7

Slide 7 text

チームで取り入れたいルール

Slide 8

Slide 8 text

特定パッケージのimport制限 ● Assertなどを提供する外部パッケージ ○ Why does Go not have assertions? ● プロジェクトにおけるテスト用パッケージ ○ e.g. githoge.com/project/root/test ○ テスト用のデータを用意するための便利メソッド群 ■ 複数パッケージのテストで参照されるために一つのパッケージとして作成

Slide 9

Slide 9 text

プロジェクトにおけるテスト用パッケージ ● テスト用のmock ○ テストではないパッケージに含めたくない ■ package modelをimportしてしまえば誰でも使えてしまうため ● テストデータ作成便利メソッド ○ *intなどを各パッケージのテストで書いていると手間がかかる

Slide 10

Slide 10 text

プロジェクトにおけるテスト用パッケージ

Slide 11

Slide 11 text

テストのために取り入れたいルール

Slide 12

Slide 12 text

特定メソッド・変数への参照制限 ● テストのための時間停止用メソッドなど ○ メソッドとして用意しない方法もあるが、テストが一手間増える ○ 手間をかけないために楽をしたときにできてしまう副産物を テスト以外では利用できないようにしたい

Slide 13

Slide 13 text

テスト用に時間を停止するメソッド ● 現在時刻による動作の差異がある場合をテストする時の方法 ○ Now() time.Timeを実装したインターフェースを渡せるようにする ■ テスト用に各種パッケージにインターフェースを渡すのが手間 ○ グローバルにtime.Nowへの参照を持ったパッケージを作成して、 現在時刻取得はそのメソッドから行い、テスト時に差し替える ■ テスト時に差し替える用のメソッドは `*_test.go` から参照できる必要があるため Publicなメソッドにしなければならない

Slide 14

Slide 14 text

現在時刻を差し替える(interface版) ● interfaceを渡すべき構造体が複数ある場合など、テストでの管理が面倒

Slide 15

Slide 15 text

現在時刻を差し替える(global書き換え版) ● build tagsを記述したファイルのみにメソッドを定義した場合、 エディタのlint設定も変更しなければならない ● タグがなければ、差し替えるメソッドは機能しないが、差し替えるメソッドを TestGoFiles, XTestGofiles以外で参照することすらあってほしくはない

Slide 16

Slide 16 text

パッケージの役割を分けるために取 り入れたいルール

Slide 17

Slide 17 text

特定builtin機能の制限 ● panic書く機会はほぼないため禁止してしまいたい ○ web application書いているときなど ● データの構造についてのみ記述するためのパッケージで条件分岐など不要 ○ e.g. githoge.com/project/root/data ○ 構造体の定義だけ記述されていたり、 値を詰め込むだけのメソッドしか存在してほしくない

Slide 18

Slide 18 text

ルールの共有方法

Slide 19

Slide 19 text

チームでのルールの共有方法 ● Wikiにまとめる ○ 更新され続ける保証はない ○ 読まないで書いてくる人いるかも ○ レビューで指摘するとして、チームに入ってからの歴が浅いと 見逃してしまう可能性がある 人がチェックすると見逃す可能性を排除することはできないので、 チームルールを自動的にチェックするためのツールが欲しい

Slide 20

Slide 20 text

「self-lint」

Slide 21

Slide 21 text

self-lint ● https://github.com/mizkei/self-lint ● チームでの禁止事項(ローカルルール)をチェックするためのツール ○ 特定importのチェック ○ 特定packageのメソッドや変数への参照 ○ panicなどのbuiltin functionの使用 ● CIを利用した自動チェック ○ golintと同じ出力形式であるため、reviewdogが食べてくれる

Slide 22

Slide 22 text

self-lintの設定 ● target ○ 対象のパッケージ ■ globalは全てのパッケージ ● import ○ 禁止したいパッケージを書く ● ref ○ 禁止したいパッケージの値を書く ● write ○ 禁止したいbuiltin functionを書く ■ panic, if, switch, or for

Slide 23

Slide 23 text

特定importのチェック ● テストファイル以外でtestパッケージはimportしてはいけない

Slide 24

Slide 24 text

特定パッケージの値への参照 ● テスト用に作成されたメソッドを テストファイル以外で参照してほしくない

Slide 25

Slide 25 text

特定のbuiltinやstatementsの利用 ● データを定義しているだけのパッケージでpanicしてほしくない

Slide 26

Slide 26 text

まとめ ● lintに加えて、チームでの開発において、更に制限が欲しくなる場合に ついて述べた ● チームとして設定した制限を自動チェックするために self-lintというツールを作成した