Siderでサポートしているツールのうちの三つ、QuerlyとPhinder、GoodcheckはSider自身が開発しているものです。*1 *2
これらのツールは
特定のテキストのパターンを発見したときに、なんらかのメッセージを表示する
という動作をします。とても単純な機能ですが、これをどう使えば良いのでしょうか?
チームの知識、経験、歴史
ちょっと一般的な話をしましょう。
コードレビューには「問題があるコードを見つけて修正を促す」という品質に対する効果もありますが、それよりも実際に高く期待されているのは「チームの情報共有を進める」という効果だと言われています。「チームに長くいる人が、過去にチームで発見されたベストプラクティスについて伝える」「以前発生した障害のことを覚えている人が、新しく書かれたコードに似たパターンを見つける」「既に定義されているSASSのmixinについて教えてあげる」こういった、チーム内での知識共有を通して、チームは成長していきます。
一番良いのは開発者同士でレビューして知識を伝えていくことですが、これを多少なりとも自動でやるにはどうしたらいいでしょうか?
Linterでやることもできなくはありません。Linterが提供している組み込みのルールはあなたのチームについての知識を持っていないので、プラグインに相当する仕組みでルールを追加する必要があります。まあ面倒ですよね……一般的なLinterのルールは、それなりに複雑なので、普通のプラグインの仕組みは結構複雑なルールを書けるようになっています。つまり開発のコストが大きすぎる。
「これはチーム全体で知っておいて欲しいことだ!」となにかを思いついた直後に、3分くらいで実装できないといけませんが、プラグインでは困難です。本当はルールを手動で書くこともしたくないのですが、人間のコミュニケーションから自動的に抽出するというのはあまりに難しいのでひとまず諦めましょう。そもそもGitHubとかSlackとかに完全にコミュニケーションが乗っているわけでもないので、まあ無理です。
その辺りをSiderチームで詳細に検討した結果、「パターンにマッチしたメッセージを表示する」くらいのメカニズムが適当なのではないかな、ということになりました。説明に戻ります。
カスタムルール
Siderでは、これを「カスタムルール」と呼んで、自分でルールを追加・定義できるLinterとして活用することを提案しています。プロジェクト内で定義されたAPIについてなんらかの注意事項を表示したり、言葉の利用方法についてレビューで注意したり、オペレーションの手順を表示したりできます。
rules: - id: remove_column pattern: "remove_column(...)" message: カラムを削除するときは https://eagletmt.hateblo.jp/entry/2017/09/24/004709 を読みましょう
これはQuerlyの例ですが、remove_column(...)
というテキストでパターンを定義し、remove_column
メソッドの呼び出しを検出します。この例では、 remove_column
するときの注意事項について説明したブログの記事を紹介していますが、例えばプロジェクトによっては単に「カラムを削除するな」と言うかもしれません。*3
引数の数以外(レシーバも条件にはできますが)で、メソッド呼び出しを特定することはできないというのがポイントです。このくらいなら、パターンの構文を覚えればすぐに書けるようになるし、書きたいものは大体書けます。(「大体」は言い過ぎかもしれませんが、まあ意外と書けます。)ここでは書いていませんが、パターンをユニットテストする仕組みも用意していますので、
- チェックしたいことを考える
- パターンを考える
- テストを書く
まで、YAMLファイルを少し編集すれば書けるようになるのです。
また、多少一般的な感じのルールは、Twitterで紹介しています。「実際にどんなルールを書いたら良いのか??」と悩んだときにご覧ください。
誤検出について
Querlyなどの紹介をしたときに必ず聞かれるのは「誤検出があるのではないか?」ということですが、これについては「そういうもんですが、まあトータルで見たときには利益の方が大きいのでは」というのが私たちの回答になります。
まず、誤検出を減らすことがあまりできない設計になっているのは、意図的なものです。誤検出を減らすためには、高度なプラグラミングが必要になります。簡単に言うと、パターンの正確さと定義のための労力にはけっこうな関連があります。Siderでは、「あんまり深く考えないでルールをたくさん作ってもらう方が利益が大きい」という戦略を採用しています。
誤って検出されたメッセージについては、「Siderからクローズする」という運用を提案しています。Siderでは、
- GitHubのPull Requestで変更したところに関連するメッセージしか表示しない
- 不要なメッセージを気軽に「クローズ(無視)」できるようにする
という工夫があり、誤検出に負けないユーザー体験を提供しています。
逆に言えば、Sider以外でこれらのツールを使おうと思ったときには、残念ながら少し厳しい体験になるはずです。例えば、手元の開発環境でエディタでソースコードを編集している最中に実行しようとすると、「Pull Requestの情報がないので、全部のコードに関する問題を表示する必要があり、誤検出が多すぎて厳しい」ことになるでしょう。*4
極端なことを言えば、「パターンにマッチしたメッセージを表示する」というのはおまけで、「リポジトリにチームの知識が明文化されて残っていく」ということがより重要です。
まとめ
Siderでは、コードレビューの大きな目的の一つである「チーム内の知識共有」について注目し、製品の開発を行っています。通常のLinterが検査する一般的なルールだけではなく、チームの知識をルールとして簡単に記述できるツールを開発しています。Siderを使って、チームの知識をファイルに書き、自動的に共有していきましょう。