【AndroidStudio】detekt で JetpackCompose 記述をチェックする

あちこちの著名なアプリ開発で使われているようなので、標準的な正しい記述を学ぶことができると思います。

【AndroidStudio】detekt で JetpackCompose 記述をチェックする (随時更新)
👉 Welcome | detekt hatena-bookmark

 

🧑‍💻 インストール方法

いくつかの方法があるのでどれを使ったらいいのか分からない。

【AndroidStudio】detekt で JetpackCompose 記述をチェックする (随時更新)

一通り「Getting Started」を読んでみたけど、まず初めは手っ取り早い「IDE プラグイン」か「Gradle プラグイン」でしょうか。

 

🧑‍💻 IDE プラグインをインストール

【AndroidStudio】detekt で JetpackCompose 記述をチェックする (随時更新)

👉 detekt - IntelliJ IDEs Plugin | Marketplace hatena-bookmark
👉 detekt/detekt-intellij-plugin: detekt plugin for IntelliJ hatena-bookmark

ファイルから右クリックで実行できるので便利そう。

【AndroidStudio】detekt で JetpackCompose 記述をチェックする (随時更新)

【AndroidStudio】detekt で JetpackCompose 記述をチェックする (随時更新)

しかし、detekt.yml を利用してのチェックポリシー変更がなぜか反映されない。

【AndroidStudio】detekt で JetpackCompose 記述をチェックする (随時更新)
👉 Issues · detekt/detekt-intellij-plugin hatena-bookmark

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 が表示されてる位置に書き出されました。

【AndroidStudio】detekt で JetpackCompose 記述をチェックする

【AndroidStudio】detekt で JetpackCompose 記述をチェックする

チェックポリシーを変更する場合は、この 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 hatena-bookmark
👉 Configuration for Compose | detekt hatena-bookmark

逆にいえば、これらは、

「Kotlin と JetpackCompose の記述ルールの違い」

ということになるのでしょう。

detekt を使わない方も一読しておくといいと思われます。

👉 【Gradle Plugin】detekt「baseline」とは hatena-bookmark

👉 ファイルの末尾に改行を追加するように Android Studio を設定するにはどうすればよいですか? hatena-bookmark


【AndroidStudio / IDEA】プラグイン「Indent Rainbow」を使う

階層が深くなって見づらいので、対応するカッコを色付けするプラグインを入れましたが、

izhangzhihao/intellij-rainbow-brackets: Rainbow Brackets / Rainbow Parentheses for IntelliJ IDEA based IDEs
👉 IntelliJ IDEA プラグイン「Rainbow Brackets」を使う hatena-bookmark

つづいてインデントも「Indent Rainbow」で色付けします。

【AndroidStudio / IDEA】プラグイン「Indend Rainbow」を使う
👉 Indent Rainbow - IntelliJ IDEs Plugin | Marketplace hatena-bookmark

【AndroidStudio / IDEA】プラグイン「Indend Rainbow」を使う

【AndroidStudio / IDEA】プラグイン「Indend Rainbow」を使う

いいんじゃないですかね、とりあえず。

うざくなった捨てます。


【AndroidStudio】実行時に自動でそれまでのログを消して logcat ウインドウを開く設定

こういう設定があるのは知っているけど設定をどこでするのか毎回分からない、ので。


[Run]

  ↓

[Edit Configulations...]

  ↓

✅ [Show logcat automatically]
✅ [Clear log before launch]


✔[Show logcat automatically]
✔[Clear log before launch]

基本的にこの2つはONにしてていいと思います。