あちこちの著名なアプリ開発で使われているようなので、標準的な正しい記述を学ぶことができると思います。
🧑💻 インストール方法
いくつかの方法があるのでどれを使ったらいいのか分からない。
一通り「Getting Started」を読んでみたけど、まず初めは手っ取り早い「IDE プラグイン」か「Gradle プラグイン」でしょうか。
🧑💻 IDE プラグインをインストール
👉 detekt - IntelliJ IDEs Plugin | Marketplace
👉 detekt/detekt-intellij-plugin: detekt plugin for IntelliJ
ファイルから右クリックで実行できるので便利そう。
しかし、detekt.yml を利用してのチェックポリシー変更がなぜか反映されない。
👉 Issues · detekt/detekt-intellij-plugin
issues にもそのような事例多く上がっているのでとりあえず捨てる。
🧑💻 Gradle プラグインをインストール
きっと、リポジトリに mavenCentral() は設定済みだと思うので、追加するのは1行。
// build.gradle.kts
plugins {
id("io.gitlab.arturbosch.detekt") version("1.23.1" )
}
インストールはこれだけです。
タスクに登録されているか確認します。
❯ ./gradlew tasks | grep detekt
detekt
detektBaseline - Creates a detekt baseline on the given --baseline path.
detektBaselineDebug - EXPERIMENTAL: Creates detekt baseline for debug classes with type resolution
detektBaselineDebugAndroidTest - EXPERIMENTAL: Creates detekt baseline for debugAndroidTest classes with type resolution
detektBaselineDebugUnitTest - EXPERIMENTAL: Creates detekt baseline for debugUnitTest classes with type resolution
detektBaselineMain - EXPERIMENTAL: Creates detekt baseline files for production classes across all variants with type resolution
detektBaselineRelease - EXPERIMENTAL: Creates detekt baseline for release classes with type resolution
detektBaselineReleaseUnitTest - EXPERIMENTAL: Creates detekt baseline for releaseUnitTest classes with type resolution
detektBaselineTest - EXPERIMENTAL: Creates detekt baseline files for test classes across all variants with type resolution
detektDebug - EXPERIMENTAL: Run detekt analysis for debug classes with type resolution
detektDebugAndroidTest - EXPERIMENTAL: Run detekt analysis for debugAndroidTest classes with type resolution
detektDebugUnitTest - EXPERIMENTAL: Run detekt analysis for debugUnitTest classes with type resolution
detektGenerateConfig - Generate a detekt configuration file inside your project.
detektMain - EXPERIMENTAL: Run detekt analysis for production classes across all variants with type resolution
detektRelease - EXPERIMENTAL: Run detekt analysis for release classes with type resolution
detektReleaseUnitTest - EXPERIMENTAL: Run detekt analysis for releaseUnitTest classes with type resolution
detektTest - EXPERIMENTAL: Run detekt analysis for test classes across all variants with type resolution
❯ ./gradlew tasks | grep detekt | grep -v EXPERIMENTAL
detekt
detektBaseline - Creates a detekt baseline on the given --baseline path.
detektGenerateConfig - Generate a detekt configuration file inside your project.
これらの Gradle プラグインによって登録された Gradle タスクを実行することでコード記述のチェックができるようです。
インストール方法としては、これで進めていきます。
🧑💻 設定ファイル
Gradle タスクを使って書き出します。
❯ ./gradlew detektGenerateConfig
> Task :app:detektGenerateConfig
Successfully copied default config to /path/to/project/config/detekt/detekt.yml
デフォルトの設定のコピー detekt.yml が表示されてる位置に書き出されました。
チェックポリシーを変更する場合は、この YML 形式のファイルを書き換えます。
820行もあります。
🧑💻 実行する
では、実行してチェックしてみます。
❯ ./gradlew detekt
> Task :app:detekt FAILED
/path/to/project/app/src/main/java/com/example/ea/ui/theme/Theme.kt:41:5: Function names should match the pattern: [a-z][a-zA-Z0-9]* [FunctionNaming]
/path/to/project/app/src/main/java/com/example/ea/MainActivity.kt:92:5: Function names should match the pattern: [a-z][a-zA-Z0-9]* [FunctionNaming]
/path/to/project/app/src/main/java/com/example/ea/ui/theme/Color.kt:5:22: This expression contains a magic number. Consider defining it to a well named constant. [MagicNumber]
/path/to/project/app/src/main/java/com/example/ea/ui/theme/Color.kt:6:26: This expression contains a magic number. Consider defining it to a well named constant. [MagicNumber]
/path/to/project/app/src/main/java/com/example/ea/ui/theme/Color.kt:7:20: This expression contains a magic number. Consider defining it to a well named constant. [MagicNumber]
/path/to/project/app/src/main/java/com/example/ea/ui/theme/Color.kt:9:22: This expression contains a magic number. Consider defining it to a well named constant. [MagicNumber]
/path/to/project/app/src/main/java/com/example/ea/ui/theme/Color.kt:10:26: This expression contains a magic number. Consider defining it to a well named constant. [MagicNumber]
/path/to/project/app/src/main/java/com/example/ea/ui/theme/Color.kt:11:20: This expression contains a magic number. Consider defining it to a well named constant. [MagicNumber]
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:detekt'.
> Analysis failed with 8 weighted issues.
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
BUILD FAILED in 545ms
1 actionable task: 1 executed
8箇所に2種類のエラーがでました。
Function names should match the pattern: [a-z][a-zA-Z0-9]* [FunctionNaming]
This expression contains a magic number. Consider defining it to a well named constant. [MagicNumber]
チェックするコードとして、AndroidStudio 同梱の新規プロジェクトテンプレート「Empty Activity」を書き出しただけのプロジェクトなのですが。
それぞれ内容を見ていきます。
🧑💻 Function names should match the pattern: [a-z][a-zA-Z0-9]* [FunctionNaming]
@Composable
fun FooButton(text: String, onClick: () -> Unit) {
Unit を返す @Composable 関数名は PascalCase なので、JetpackCompose に向けて設定ファイル detekt.yml を以下のいずれかに変更します。
FunctionNaming:
active: true
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
# functionPattern: '[a-z][a-zA-Z0-9]*'
functionPattern: '[a-zA-Z][a-zA-Z0-9]*'
excludeClassPattern: '$^'
FunctionNaming:
active: true
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
functionPattern: '[a-z][a-zA-Z0-9]*'
excludeClassPattern: '$^'
ignoreAnnotated: ['Composable'] # 追加
FunctionNaming:
active: true
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
functionPattern: '[a-z][a-zA-Z0-9]*'
excludeClassPattern: '$^'
ignoreAnnotated: # 追加
- 'Composable' # 追加
どうやら、detekt デフォルトの設定は JetpackCompose に十分には対応してないようです。
🧑💻 This expression contains a magic number. Consider defining it to a well named constant. [MagicNumber]
val color1 = Color(0xFFEA6D7E)
クラス、コンパニオンオブジェクト、トップレベルのプロパティのオブジェクト記述は、名前付きパラメータを指定しないと違反となるようです。
以下のいずれかで。
val color1 = Color(color = 0xFFEA6D7E)
MagicNumber:
active: true
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.kts']
ignoreNumbers:
- '-1'
- '0'
- '1'
- '2'
ignoreHashCodeFunction: true
# ignorePropertyDeclaration: false
ignorePropertyDeclaration: true
あまり、ignore* 系は使わない方がいいような気もする。
🧑💻 まとめ
などと書いてきましたが、これらは以下の detekt 公式ページにまとめられています。
👉 Configuration for Compose | detekt
逆にいえば、これらは、
「Kotlin と JetpackCompose の記述ルールの違い」
ということになるのでしょう。
detekt を使わない方も一読しておくといいと思われます。