🕵️‍♂️

マルチプロジェクト構成でDetektを全てのサブプロジェクトのGradleのcheckタスクから外そうとしたら大変だった話

2022/03/28に公開

こんにちは、エンジニアのtsukakeiです。

皆さん、Kotlin書いていますか?

今日は、Kotlinの静的解析器Detektを入れたときに困った話をしようと思います。

TL;DR

マルチプロジェクト構成でDetektを全てのサブプロジェクトのcheckタスクから外したいときは

./gradlew check -x detekt

しよう!
https://github.com/detekt/detekt/issues/4396

Detektとは

DetektはKotlinの静的解析ツールです!
ソースコードを解析して、メソッドの複雑度や変数名が命名規則に則っているかなどのコードスメルを分析してくれます。

リファクタリングをする際に、どこから手をつけたらいいかの指標になるといいなと思い、入れてみました。

Detekt関連記事

入れてみて困ったこと

入れてみたところ、CIのビルドが通らないという問題が発生しました。
これを調べてみると、checkタスク内で自動実行されてしまい、静的解析の結果が芳しくない(デフォルトの閾値が結構厳しい!)ため、ビルドが失敗するという事象が発生していました。

ここで閾値を下げるというのもよくある手なのですが、個人で勝手に導入してみただけなので、GradleのcheckタスクからDetektを外す形で対応したいなと思いました。

DetektをGradleのcheckタスクから外す

Stack Overflowを参考にしてみた(断念)

Stack Overflowの回答を参考にしてみたのですが、これはうまく動かず断念しました。

gradle
task detect {
    doFirst {
        println 'detect'
    }
}

detect.onlyIf { project.hasProperty('runDetect') }

公式ドキュメントを参考にしてみた(断念)

こういうときこそ、公式ドキュメントに当たるべきだろうということで探し回った結果、求めていた記述が見つかりました!

gradle
tasks.named("check").configure {
    this.setDependsOn(this.dependsOn.filterNot {
        it is TaskProvider<*> && it.name == "detekt"
    })
}

僕のGradle力が低いせいもあり、マルチプロジェクト構成の場合は全プロジェクトのgradleファイルにこれを書かないといけませんでした。
これはさすがに辛すぎるので他にいい方法がないか探しました。

ソースコードを参考にしてみた(達成)

Detektは幸運なことにGitHubでソースコードが公開されています。
探せばSKIPしてくれそうな実行オプションあるだろって思って探してみました。

そうしたら、なんとdetekt-dry-runというDry Run用のpropertyを発見しました!
どうやらこのdetekt-dry-run'true'を設定したらDry Runしてくれるようです。

kotlin
private const val DRY_RUN_PROPERTY = "detekt-dry-run"

internal fun Project.isDryRunEnabled(): Boolean {
    return hasProperty(DRY_RUN_PROPERTY) && property(DRY_RUN_PROPERTY) == "true"
}

https://github.com/detekt/detekt/blob/9f18b6b374e8b341bff1e7504c7b56e0a255c1b4/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/invoke/DetektInvoker.kt#L33-L37

CIのビルド時に

./gradelew ... -P detekt-dry-run=true ...

とすることで無事にDetektを外すことができました!
めでたしめでたし!

Issueにもっといい解法があった

What about ./gradlew check -x detekt? That will not execute the Detekt task.

この記事を書くためにDetektのskip周りで調べていたら、前述の記述の後に関連したIssueが挙げられていて、それにスマートな解法が載っているのを発見しました👀

こちらの書き方の方がDetektの内部実装によらないので良さそうです。
先ほど弊社のレポジトリにも修正PRを出しました!

おわりに

  • Detektはいいぞ
    まだまだ活用しきれていませんが、Detektを使ってコードの品質改善をした話をいつか書こうかなと思っています

  • Gradle力を上げたい
    Gradle力がもう少しあれば、ここまで困らなかったと思うので、Gradle力を上げたい!!

株式会社イエソドはエンジニアを募集しています!

弊社はKotlinとTypeScriptで開発をしています。
気軽にカジュアル面談しましょう!

https://herp.careers/v1/yesodco/5yQcbvDulNfy

https://herp.careers/v1/yesodco/9SKtd3pNgxfO

Discussion