よく使われてるKotlinのLintツールとしては、ktlintがあると思いますが、今回はDetektを紹介したいと思います。
DetektはKotlinのコード静的解析ツールになっていて、フォーマットエラーやCode smellを検出してくれるものになります。
ktlintに比べて更に細かいことをしてくれますし、コードで問題がありそうな箇所も検出してくれるの、うまく運用すると非常に強力なものになると思います。
セットアップ
Detektの導入はドキュメントを見ても分かりにくい部分があるので、まずは最低限の設定でやっていきます。
今回はKotlin DSLを使った例になります。
まずはDetektのGardle Pluginをプロジェクト直下の build.gradle
に追加します。
plugins {
id("io.gitlab.arturbosch.detekt").version("1.22.0-RC1")
}
次に各モジュールでDetektのプラグインを有効にします。モジュール分割をしていない場合は適宜置き換えてください。
subprojects {
apply(plugin = "io.gitlab.arturbosch.detekt") detekt {
// ここに設定を書いていく
}
}
これだけで一応は動かくすことが出来ます。
./gradlew tasks — all | grep detekt
を実行してDetektのGradleタスクが生成されていればOKです。
Detektの実行
Detektの実行には2つの種類があり、Type Resolution(型解決)を使用した解析を行うかどうかです。
Type Resolutionは現在まだExperimetalになっています。
Type Resolutionを使用しない
単純にコードのフォーマットやスタイルだけを解析する場合は、以下のように実行します。
$ ./gradlew detekt
これを実行してルールに違反してるものがある場合はエラーになると思います。またレポートファイルはデフォルトでは buid/reports/detekt
フォルダに出力されます。
Type Resolutionを使用
Type Resolutionを使用することで更に高度な解析ができるようになります。
DetekのGradle PluginによってType Resolutionを使用するためのタスクが生成されているのでそちらを使用します。 main
のsourceSetの場合は detektMain
、 test
のsourceSetの場合は detektTest
になります。
$ ./gradlew detektMain
$ ./gradlew detektTest
Androidの場合は detekt<Variant>
のタスクを使用していきます。同様にUnitTestとAndroidTestもそれぞれ別のタスクになってるので、そちらを実行します。
$ ./gradlew detektDebug
$ ./gradlew detektDebugUnitTest
$ ./gradlew detektDebugAndroidTest
Detektの設定ファイル生成
デフォルトの設定を変更するには、設定ファイルを使ってDetektの動作を制御することができます。
設定ファイルを生成するためには、 以下のコマンドで生成することが出来ます。
./gradlew detektGenerateConfig
実行後に、 config/detekt/detekt.yml
が生成されます。この内容はすべてデフォルトになってるので必要な項目を編集します。
Detektの設定について後述します。
ただ、この状態だとすべての設定ファイルに記載されています。
次で説明しますが、Gradleの設定で buildUponDefaultConfig = true
にすることで上書きしたい項目だけを detekt.yml
に記載するだけでよくなります。
Gradle Pluginの設定
Gradle側で設定できる項目について簡単に紹介します。詳細はドキュメントを確認してみてください。
設定項目の例です。
Detektの設定
DetektではYAMLファイルにて設定をしていきます。
繰り返しになりますが、 detektGenerateConfig
で生成した設定ファイルはすべての項目が出力されてだいぶ膨大ですが、 Gradle側で buildUponDefaultConfig = true
を設定することでデフォルトから変更したい箇所だけを記述することが出来ます。
ここではよく設定されるだろう項目について見ていきます。
レポートファイル
出力するレポートファイルを指定することが出来ます。DetektはText, XML, HTML, Markdown, Sarifをサポートしています。
Detektで設定するには出力しないものを指定する感じになります。
output-reports:
active: true
exclude:
- 'HtmlOutputReport'
- 'MdOutputReport'
この例だとHTMLとMarkdownのものは出力しない設定になります。
ルールの設定
ルールの有効・無効、ルールごとの設定などもYAMLで設定していきます。
DetektではRule Setといういくつかのルールがまとめられたものがあり、その中にルールがある感じになります。
ドキュメントのサイドバーの Rules Documentation
を展開すると提供されてるRule Setが確認できます。このRule Setのなかに複数のルールがあります。
このドキュメントを見ながら設定していくのが良いと思います。
例で Style Rule Set
から MandatoryBracesIfStatements
のルールを見ていきます。 https://detekt.dev/docs/rules/style#mandatorybracesifstatements
ドキュメントのキャプチャにコメントしていますが、この内容をもとに設定していきます。このルールは複数行のif文で中括弧が無いものを検出します。ドキュメントを見るとをデフォルトでは無効になっているので、有効にする設定をします。
style:
MandatoryBracesIfStatements:
active: true
この例では style
がRule Set、MandatoryBracesIfStatements
がルール(Issueとも呼ばれる)になっています。
基本的に有効、無効は active
を設定するだけで切り替えられます。
もう一つ他の例を見てみます。 Complexity Rule Set
の NamedArguments
のルールを見てみます。
https://detekt.dev/docs/rules/complexity#namedarguments
このルールは引数の数が多い場合は名前付き引数で渡す必要があります。
最初の例と異なる部分として、 Requires Type Resolution
と、 Configuration options
があります。
このルールはType Resolutionを使用する必要があるので、 detektMain
等で実行しないと検出されません。
ルール固有の設定は以下のようにYAMLで設定できます。
complexity:
NamedArguments:
active: true
threshold: 1 # デフォルトは3だけど、1に変更している
Detektが提供してるルールは他にもたくさんあるので、一通り眺めておくと良いと思います。
つづく
長くなりそうだったので、続きは別記事で書きました。