Goの静的解析ツールをgolintからstaticcheckに移行した話

こんにちは、@ueokandeです。 つい先日Go 1.16がリリースされましたね。 サイボウズではGoで書かれたプロダクトやツールなどが数多く存在しており、GitHubで公開しているものも多数あります。

自分の所属するYakumoチームでも、Kubernetes上にデプロイしているサービス、AWS Lambda、開発者向けのツールなどをGoで実装しています。 本日は、Goの静的解析ツールをgolintからstaticcheckに移行したお話をします。

x/lint: freeze and deprecate

Goコードの静的解析ツールとして、Yakumoチームではgolintを採用していました。 golintはGoの静的解析ツールとして、長らくデファクトスタンダードとされており、サイボウズ社内でも多くのチームで利用していました。 しかしgolintの開発チームから今後はメンテナンスされないことが発表され、利用も非推奨となりました。 Yakumoチームも含めた社内でgolintを使っているチームは移行を迫られました。

github.com

Go静的解析ツールの選定

golintの移行先として、いくつかのGo静的解析ツールが挙がりました。

その中でYakumoチームではstaticcheckを採用しました。 採用理由は、staticcheckはデフォルト設定でも程よいルールが適用され、golintほど過剰な指摘がないという点です。 またstaticcheckはGoogleが公式でスポンサーをしており、社内のNecoチームがすでに利用していたというのも理由の1つです。

ここで挙げたツールとgolintは、指摘内容が異なる点に注意する必要があります。 これらのツールはバグとなりうるコードを指摘するのに対して、golintはスタイルチェッカーです*1。 例えばgolintはexportされた関数へのドキュメントコメントを強制しますが、staticcheckではデフォルトでそのチェックが無効になっています。 またstaticcheckは、err確認漏れ (if err != nil)を指摘してくれますが、golintにはその機能がありません。

golintからstaticcheckへの移行

CI/CDへの導入

まずやることは、CI/CDパイプラインで利用しているgolintをstaticcheckに置き換えることです。 試しに既存のコードをstaticcheckでチェックしてみたところ、非常に多くの箇所がエラーになることがわかりました。 コードの差分が多くなると、レビュワーへの負担になったり、レビュー漏れが発生しそうです。 またレビューをしている間にコンフリクトが発生して、レビューが一向に終わらないという懸念点もありました。

そこで最初のステップとして、staticcheckへの置き換えのみを目的にしたPull Req.を作成します。 既存のエラーはstaticcheckでスキップするようにコマンドラインで指定して、CI/CDパイプラインは通過するようにします。 レビュワーにはstaticcheckの導入にのみ集中してもらいたいため、既存のGoコードは一切手を加えません。

- test -z "$(go list ./... | xargs golint | grep -v ': exported ' | tee /dev/stderr)"
+ staticcheck -checks inherit,-S1038,-S1007,-ST1005,-U1000,-S1039,-S1002,-SA1006,-SA4006,-S1021,-S1030,-S1004,-S1034,-SA6005,-S1016,-S1036,-S1028,-SA4011,-ST1011 ./...

もちろんこの時点では潜在的な不具合やエラーになりやすいコードは残ったままですが、レビュワーへの負担は減りPull Req.もすぐにマージできました。 いち早くレポジトリにstaticcheckに移行することで、新たなエラーを防ぐこともできます。

ルールの有効化

さてstaticcheckが導入できれば、あとは地道にエラーを1つずつ外していくのみです。 この作業も、変更点が大きくなりすぎないように、適度な粒度でエラーを外していきます。 これをすべてのエラーがなくなるまで、いくつかのPull Req.に分けてルールの有効化を進めました。

staticcheckのルールを段階的に有効化していく
staticcheckのルールを段階的に有効化していく

最終的にはスキップするルールがゼロにして、無事移行完了です。

サイボウズはstaticcheckを応援しています

サイボウズ社内ではstaticcheckを広く利用しているため、サイボウズからstaticcheckの作者へ寄付することにしました。

github.com

寄付は「投資」ではなく、そのOSSを利用したおかげで事業が成長できた分を還元していく「フィードバック」であるという考えのもとに、 サイボウズはこれからもOSSに寄付をしていきます。