【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


【Android】「Navigation Bar」はどちらか分かりますか?

混乱しません?

【Android】「Navigation Bar」はどちらか分かりますか

【Android】「Navigation Bar」はどちらか分かりますか
👉 Window insets in Compose  |  Jetpack Compose  |  Android Developers hatena-bookmark

【Android】「Navigation Bar」はどちらか分かりますか
👉 Navigation bar – Material Design 3 hatena-bookmark

ネーミングややこしくない?

最近の Android 界隈。


【Apple】ヤマト運輸 (クロネコヤマト) の「ADSC支店」は今どこにあるのか

調べてみると、2013年の記事です。

調べてみるとADSC支店は国内だと言うことが判明。どうやら国内まで到着しているようだ。そしてこの謎の支店は「Apple Delivery Support Center」の略だとか。

国内AppleStoreで購入したものは中には海外からの発送される物があり、そういった商品は一度ADSC支店に集められそこから再出荷するのである。ちなみに場所は有明ね。あの倉庫だらけの有明。つまり私が2日に注文した商品は今日ADSC支店から出荷され近々届けられるのである。

👉 アップル製品をオンライン注文時の「ADSC支店」って何? その謎に迫る! | ガジェット通信 GetNews hatena-bookmark

実際、Mac を購入、下取りを Apple 公式サイトでやってみた結果。

以下、購入時の状況経過。注文から、1週間で到着しました。

【Apple】ヤマト運輸 (クロネコヤマト) の「ADSC支店」は今どこにあるのか

「深セン」の次が「ADSC支店」で次が「羽田クロノゲートベース」。

続いて、下取り送付時の流れ。

【Apple】ヤマト運輸 (クロネコヤマト) の「ADSC支店」は今どこにあるのか

「羽田クロノゲートベース」のあと「ADSC支店」で終了。

この時点で、下取り完了のメールを受け取りました。

【Apple】ヤマト運輸 (クロネコヤマト) の「ADSC支店」は今どこにあるのか

なんとなく「ADSC支店」は、「東京ベース」のある有明ではなく、羽田空港近くの「羽田クロノゲートベース」近辺にあるように見えます。



ADSC支店

オンラインのApple Storeで購入した商品が、必ず通るとされるヤマト運輸の支店。

具体的な場所は公開されていないため確定できないが、これを著している時点では羽田クロノゲート外部リンク内に存在し、管轄は南東京主管と予想されている。

👉 ADSC支店 ‐ 通信用語の基礎知識 hatena-bookmark

羽田主管支店 ADSC支店(ロジ)

京急空港線「穴守稲荷」駅 徒歩5分 JR「蒲田」駅より無料送迎バス利用可

👉 ヤマト運輸株式会社 物流センターの作業スタッフ 求人情報:東京都大田区 hatena-bookmark

「羽田クロノゲート」内にありそうです。

配達の方に聞けば良かったわ。

まあ、どっちでもいいか。

👉 羽田クロノゲート | ヤマト運輸 hatena-bookmark