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


はじめに

AndroidプロジェクトのKotlinコードが既定のフォーマットになっているかのチェックをCIで行うために、DroidKaigi/conference-app-2021を真似してSpotless plugin for Gradleを導入しました。

導入方法はDroidKaigi/conference-app App Ownerのtakahiromさんが解説しています。
KtLint + Spotless + GitHub ActionsでPRにsuggested changeさせる

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

例えばRoomのDAOクラスに長いSQL文があるとします。
Android StudioはRoomのSQL文をハイライト表示してくれるので読みやすいです。


(画像は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文のハイライト表示が無くなってしまいます。
これは読みづらいです。

よって、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パラメータに複数のパスを設定することはできます。

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"])
        }
    }
}