SpotlessのフォーマットチェックからRoomのDAOクラスを除外する

# はじめに

AndroidプロジェクトのKotlinコードが既定のフォーマットになっているかのチェックをCIで行うために、[DroidKaigi/conference-app-2021を真似して](https://github.com/DroidKaigi/conference-app-2021/blob/1eec6933e065ee97f67305717d280426cbec7274/build.gradle#L61)、[Spotless plugin for Gradle](https://github.com/diffplug/spotless/tree/main/plugin-gradle)を導入しました。

導入方法はDroidKaigi/conference-app　App Ownerのtakahiromさんが解説しています。
[KtLint + Spotless + GitHub ActionsでPRにsuggested changeさせる](https://qiita.com/takahirom/items/2a3d2912e74107748765)

# RoomのDAOクラスはフォーマットチェックの対象外にしたい

例えば[RoomのDAOクラス](https://developer.android.com/training/data-storage/room/accessing-data?hl=ja)に長いSQL文があるとします。
Android StudioはRoomのSQL文をハイライト表示してくれるので読みやすいです。

![スクリーンショット 2021-06-24 23.14.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334798/055aa076-3a8b-d8b0-3711-b300109fd38c.png)
(画像はAndroid Studio。手元に長いSQL文が無かったので、無意味なORDER BY句で長くしています。)

`./gradlew spotlessCheck` コマンドでフォーマットチェックを行うと、1行が長いとktlintに怒られます。

```
> Task :spotlessKotlin FAILED
Step 'ktlint' found problem in 'data/local/src/main/java/com/tfandkusu/videobookmark/data/local/dao/BookmarkDao.kt':
Error on line: 17, column: 1
Exceeded max line length (100)
java.lang.AssertionError: Error on line: 17, column: 1
Exceeded max line length (100)
```

よってSQL文を1行100文字越えないように、文字列を+で繋いで2行に分けて書きます。
そうするとktlintに怒られなくなります。
しかしSQL文のハイライト表示が無くなってしまいます。
これは読みづらいです。

![スクリーンショット 2021-06-24 23.22.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334798/8e509a9d-1cf4-b255-361a-76e00e712fcf.png)

よって、RoomのDAOクラスだけフォーマットチェックの対象外とする設定を行います。

# 前提

RoomのDAOクラスのファイル名は `Dao.kt` で終わるものとします。

# Spotlessの設定を変更する

targetExcludeパラメータで `Dao.kt`　で終わるファイルをチェックの対象外にすることができます。

```build.gradle
allprojects {
    repositories {
        google()
        mavenCentral()
    }
    apply plugin: "com.diffplug.spotless"
    spotless {
        ratchetFrom 'origin/main'
        kotlin {
            target '**/*.kt'
            // Dao.ktで終わるファイルを除外
            targetExclude('**/*Dao.kt')
            ktlint("0.41.0")
                    .userData([android: "true", experimental: "true"])
        }
    }
}
```

## targetExcludeパラメータの有効性

targetExcludeパラメータは最後の1個しか有効でないようです。
(一次資料は見つけられず)
なので、他のtargetExcludeパラメータが　`targetExclude('**/*Dao.kt')` の下にあると、 `Dao.kt` で終わるファイルを除外できません。


```build.gradle

allprojects {
    repositories {
        google()
        mavenCentral()
    }
    apply plugin: "com.diffplug.spotless"
    spotless {
        ratchetFrom 'origin/main'
        kotlin {
            target '**/*.kt'
            targetExclude('**/*Dao.kt')
            targetExclude("$buildDir/**/*.kt")
            targetExclude('bin/**/*.kt')
            targetExclude("**/generated/**/*.kt")
            ktlint("0.41.0")
                    .userData([android: "true", experimental: "true"])
        }
    }
}
```

しかしtargetExcludeパラメータに複数のパスを設定することはできます。

```gradle
allprojects {
    repositories {
        google()
        mavenCentral()
    }
    apply plugin: "com.diffplug.spotless"
    spotless {
        ratchetFrom 'origin/main'
        kotlin {
            target '**/*.kt'
            targetExclude('**/*Dao.kt',"$buildDir/**/*.kt", 'bin/**/*.kt', "**/generated/**/*.kt")
            ktlint("0.41.0")
                    .userData([android: "true", experimental: "true"])
        }
    }
}
```