みなさん、Scalaの静的チェックツール使ってますか?
今回、Githubで☆多めな次の4つの静的チェックツールを試してみました。(2015/12/21時点)
- WartRemover(414)
- Scalastyle(332)
- Linter Compiler Plugin(135)
- Scapegoat(112)
それぞれのツールを使って、fpinscala/exercisesをlintにかけてみます。
比較結果
以下の点を比較しました。
- デフォルトで用意されてるルールの数
- fpinscala/exercisesをlintして検出されたエラーの数
初期設定で出るエラーの量が多いほど、心を折る効果が高くていいですね。
ルール, エラーはそれぞれで粒度も違いますので、参考程度に...
WartRemoverはデフォルトでは何もルールが有効になっていないので、Warts.allですべてのルールを設定しました。
||ルール数|エラー数|
|:--|:--|:--|:--|
|WartRemover|27|328 errors|
|Scalastyle|63|266 warnings|
|Linter Compiler Plugin|103|6 warnings|
|Scapegoat|107|8 errors, 163 warnings, 35 infos|
使い方
ではそれぞれのlinterをfpinscalaのsbtプロジェクトに組み込んで、使い方をみていきましょう。
WartRemover
sbtプラグインが提供されています。
project/plugins.sbt
を以下の内容で作り、project/Build.scala
に追記します。
addSbtPlugin("org.brianmckenna" % "sbt-wartremover" % "0.14")
object FPInScalaBuild extends Build {
val opts = Project.defaultSettings ++ Seq(
scalaVersion := "2.11.7",
resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/",
wartremover.wartremoverErrors ++= wartremover.Warts.all
)
...
これで、compileタスクでWartRemoverが有効になります。
$ sbt exercises/compile
...
[error] 328 errors found
[error] (exercises/compile:compileIncremental) Compilation failed
[error] Total time: 12 s, completed Dec 21, 2015 7:11:31 PM
Scalastyle
これもsbtプラグインが提供されています。
addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "0.8.0")
Scalastyleもcompileタスクに組み込むことはできますが、scalastyle
というタスクが定義されるので、それを使ってみます。
$ sbt exercises/scalastyleGenerateConfig exercises/scalastyle
...
[info] Processed 22 file(s)
[info] Found 0 errors
[info] Found 266 warnings
[info] Found 0 infos
[info] Finished in 45 ms
また、結果がexercises/target/scalastyle-result.xml
に出力されます。
Linter Compiler Plugin
これは名前の通りCompiler Pluginです。
object FPInScalaBuild extends Build {
val opts = Project.defaultSettings ++ Seq(
scalaVersion := "2.11.7",
resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/",
addCompilerPlugin("org.psywerx.hairyfotr" %% "linter" % "0.1.12")
)
...
これでphaseが追加されます。
$ sbt exercises/compile
...
[warn] 6 warnings found
余談ですが、Linter Compiler Pluginはscalastyle使ってるみたいですね
Scapegoat
こちらもsbtプラグインです。
addSbtPlugin("com.sksamuel.scapegoat" %% "sbt-scapegoat" % "1.0.0")
これでscapegoat
タスクが定義されます。
$ sbt exercises/scapegoat
...
[warning] fpinscala.testing.Gen.scala:20: Unused method parameter
Unused method parameter (val f: A => Boolean = _)
[warning] fpinscala.testing.Gen.scala:24: Unused method parameter
Unused method parameter (val a: => A = _)
[error] [scapegoat] Analysis complete - 8 errors 163 warns 35 infos
まとめ
☆の数どおり、(ほぼ)初期設定で検出するエラーの数・compileタスクへの組み込みの容易さはWartRemover, Scalastyleに軍配が上がりそうです。
また今回は紹介できませんでしたが、WartRemoverではWartTraverserをextendsして手軽に独自ルールが定義できるようです。
ScapegoatのREADMEには、
In fact it could be beneficial as the total set of possible warnings is the union of the inspections of all the enabled tools.
と述べられており、複数のlintツールを使ってもいいかもしれません。