【Android】detektのセットアップ方法
Androidのモジュール分割していないプロジェクトでの情報が少なかったのでメモ。
detektを導入する
まずは、detektをプロジェク直下のbuild.gradle.ktsに追加します。
plugins {
id("io.gitlab.arturbosch.detekt") version "1.23.3" apply false
}
次に各モジュールのbuild.gradle.ktsで有効にします。
モジュール分割していなければ、以下のようになります。
plugins {
id("io.gitlab.arturbosch.detekt") version "1.23.3"
}
以下のコマンドを実行すると、detektのルールに違反している箇所が出力されます。
$ ./gradlew detekt
適用するルールのカスタマイズ
このままではdetektのデフォルトのルールが適用されるので、ルールをカスタマイズできるようにします。
以下のコマンドを実行することで/config/detekt/detekt.yml
が生成されます。
このファイルを編集することで、必要なルールのみ有効にできます。
$ ./gradlew detektConfig
上記で生成したymlを使用するように指定します。
detekt{
config.setFrom("${rootProject.projectDir}/config/detekt/detekt.yml")
buildUponDefaultConfig = true
}
例:
naming:
active: true
BooleanPropertyNaming:
active: false
ClassNaming:
active: true
Jetpack Compose用のルールを追加
detektのルールのいくつかはJetpack Composeには適していません(特に関数の命名規則など)。
そこで、Jetpack Compose用のルールを追加していきます。
以下をapp/build.gradle.ktsに追加します。
dependencies {
detektPlugins ("io.nlopez.compose.rules:detekt:0.3.3")
}
これで新たなルールが適用されるようになります。
また、detekt.ymlで適用するルールを選択できます。
ルールの詳細は公式ドキュメントで確認できます。
例:
Compose:
ComposableAnnotationNaming:
active: true
PreviewPublic:
active: false
レポートの種類と出力場所の設定
出力するレポートの形式と出力場所を指定できます。
html形式のレポートのみを出力するように変更しました。
tasks {
withType<Detekt> {
reports {
html.required.set(true)
html.outputLocation.set(file("${buildDir}/reports/detekt.html"))
xml.required.set(false)
txt.required.set(false)
sarif.required.set(false)
}
}
}
Formattingの導入
Formattingを使用することで、detektの実行時に自動でフォーマットを行えます。
dependencies {
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.23.1")
}
detekt{
config.setFrom("${rootProject.projectDir}/config/detekt/detekt.yml")
buildUponDefaultConfig = true
autoCorrect = true //自動でフォーマット
}
また、フォーマットに関するルールもdetekt.yml
で指定できます。
例:
formatting:
active: true
android: true
autoCorrect: true
TrailingCommaOnDeclarationSite:
active: true
pre-commitの導入
pre-commitを使用することで、commit時にdetektを実行できます。
pre-commit公式の手順通りに設定します。
pre-commit-config.yml
とdetekt.sh
は以下のようにしました。
repos:
- repo: local
hooks:
- id: detekt
name: detekt check
description: Runs `detekt` on modified .kt files.
language: script
entry: ./scripts/detekt.sh
files: \.kt
#!/usr/bin/env bash
echo "Running detekt check..."
OUTPUT="/tmp/detekt-$(date +%s)"
./gradlew detekt > $OUTPUT
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ]; then
cat $OUTPUT
rm $OUTPUT
echo "***********************************************"
echo " detekt failed "
echo " Please fix the above issues before committing "
echo "***********************************************"
exit $EXIT_CODE
fi
rm $OUTPUT
detekt.shに対して権限の付与が必要です(chmod +x detekt.sh
)。
最後に、$ pre-commit install
を実行します。
また、自分の場合は、.pre-commit-config.yml
, detekt.sh
を一度commitしないと、有効になりませんでした(要確認)。
pre-commitでstageされたファイルにのみdetektを実行
detekt cli
を利用することで、stageされたファイルのみを対象にpre-commitを実行できます。
ただし、Formattingとcompose-ruleを使用する場合、公式で紹介されている方法ではうまくいきませんでした[1]。
そこで、detekt.shを以下のように書き換えます。
#!/usr/bin/env bash
echo "Running detekt check..."
OUTPUT="/tmp/detekt-$(date +%s)"
./gradlew detekt -PstagedOnly=true > $OUTPUT
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ]; then
cat $OUTPUT
echo "***********************************************"
echo " detekt failed "
echo " Please fix the above issues before committing "
echo "***********************************************"
fi
rm $OUTPUT
exit $EXIT_CODE
detekt cliは使用せず、-PstagedOnly=true
を指定することで、stageされたファイルのみチェックできます。
参考
- https://detekt.dev/
- https://mrmans0n.github.io/compose-rules/
- https://github.com/mrmans0n/compose-rules
- https://pre-commit.com/
-
detekt cliの実行時に
--plugins
でプラグインのjarファイルへのパスを渡せばできるようなのですが、やり方がよくわかりませんでした。 ↩︎
Discussion