diff --git a/CLAUDE.md b/CLAUDE.md index c114446..84c2bb5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -39,7 +39,7 @@ - 何度もフェッチやチェックが走らないよう、必要に応じて取得関数や値オブジェクトを導入する必要がある - 値を比較するテストは、なるべく`data class`同士を1回の`assertEquals`で比較すること(個別プロパティ同士で比較しない) - 仕上げとして必ず`ktfmt`によるフォーマッティングを実行すること - - 変更したビルド側で`./gradlew ktfmtFormat`を実行する。`integration-test`は独立したビルドなので、そちらを変更した場合は`integration-test`ディレクトリでも実行する + - リポジトリルートで`./gradlew ktfmtFormat`を実行する。独立したビルドである`integration-test`もこれ1つで対象になる - フォーマット結果を含めて動作確認・コミットまで行う(未整形のまま完了報告しない) - - `ktfmtCheck`は`check`に紐付いているため、未整形のコードは`build`で失敗する + - `ktfmtCheck`は各ビルドの`check`に紐付いているため、未整形のコードはそのビルドの`build`で失敗する - `gradle-integration`のTestKitフィクスチャ(`src/test/resources/fixtures`)は診断の行番号を検証する入力であり、整形対象外とする diff --git a/build.gradle.kts b/build.gradle.kts index 7363f02..901b92b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -130,6 +130,41 @@ allprojects { ktfmt { kotlinLangStyle() } } +// ktfmt はプロジェクト毎にタスクを登録するため、ルートのタスク(:ktfmtFormat / :ktfmtCheck)が +// 対象とするのはルート直下の *.kts のみで、サブプロジェクトも独立したビルドである integration-test も +// 入らない。作業ツリー全体をルート指定の 1 コマンドで扱えるよう、両者をルートのタスクへ束ねる。 +// integration-test は別ビルドのためタスク依存では辿れず、GradleBuild で入れ子のビルドとして起動する +// ktfmt はプロジェクト毎にタスクを登録するため、ルートを指定した :ktfmtFormat / :ktfmtCheck が +// 対象とするのはルート直下の *.kts に限られる。ルートのタスクを集約点として各サブプロジェクトへ束ね、 +// ルート指定でルートビルド全体が対象になるようにする +listOf("ktfmtFormat", "ktfmtCheck").forEach { taskName -> + tasks.named(taskName) { dependsOn(subprojects.map { "${it.path}:$taskName" }) } +} + +// integration-test は独立したビルドであり、上の集約でも allprojects でも辿れない。仕上げの整形を +// ルート指定の 1 コマンドで完結させるため、ktfmtFormat からラッパー経由の別プロセスとして起動する +// (入れ子のビルドを組む GradleBuild は、integration-test が親ビルドを includeBuild しているため +// 「Cannot include build」となり使えない)。ラッパーと -p の組み合わせは CI が integration-test を +// driving する形と同じで、Gradle 本体の版もルートのラッパーへ揃う。 +// 検証側(ktfmtCheck)を束ねないのは、それが check 経由でルートの build へ載り、ルートビルドの +// 検証が integration-test 側の構成・依存解決の失敗に巻き込まれるため。未整形の検出はビルド毎の +// check が担い、CI もビルド毎にジョブを分けている +val ktfmtFormatIntegrationTest = + tasks.register("ktfmtFormatIntegrationTest") { + val wrapper = + providers.systemProperty("os.name").map { + if (it.startsWith("Windows")) "gradlew.bat" else "gradlew" + } + commandLine( + layout.projectDirectory.file(wrapper.get()).asFile.absolutePath, + "-p", + "integration-test", + "ktfmtFormat", + ) + } + +tasks.named("ktfmtFormat") { dependsOn(ktfmtFormatIntegrationTest) } + // API ドキュメント(GitHub Pages 掲載用)の集約。対象は利用者がコードから触る公開 API を持つ 2 モジュールで、 // compiler-plugin(内部実装)と maven-plugin(利用面は POM の設定であり Kotlin API ではない)は含めない。 // 集約出力は build/dokka/html diff --git a/compiler-plugin/src/main/kotlin/io/github/projectmapk/sealedClassEnumizer/compiler/fir/EnumizeOwnerGeneratorPatch.kt b/compiler-plugin/src/main/kotlin/io/github/projectmapk/sealedClassEnumizer/compiler/fir/EnumizeOwnerGeneratorPatch.kt index f21a850..26856ba 100644 --- a/compiler-plugin/src/main/kotlin/io/github/projectmapk/sealedClassEnumizer/compiler/fir/EnumizeOwnerGeneratorPatch.kt +++ b/compiler-plugin/src/main/kotlin/io/github/projectmapk/sealedClassEnumizer/compiler/fir/EnumizeOwnerGeneratorPatch.kt @@ -11,15 +11,14 @@ import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension // この属性を自前で刻印するしかない。internal API へのリフレクションは、Kotlin のマイナーバージョン毎に // アーティファクトを分割する方針(docs/概要.md §7)の下でバージョンに固定される。 internal object EnumizeOwnerGeneratorPatch { - private val setter: Method? = - runCatching { - Class.forName("org.jetbrains.kotlin.fir.FirGeneratedDeclarationsUtilsKt") - .methods - .firstOrNull { method -> - method.name.startsWith("setOwnerGenerator") && method.parameterCount == 2 - } + private val setter: Method? = runCatching { + Class.forName("org.jetbrains.kotlin.fir.FirGeneratedDeclarationsUtilsKt") + .methods + .firstOrNull { method -> + method.name.startsWith("setOwnerGenerator") && method.parameterCount == 2 } - .getOrNull() + } + .getOrNull() fun stamp(declaration: FirClassLikeDeclaration, extension: FirDeclarationGenerationExtension) { setter?.invoke(null, declaration, extension) diff --git a/compiler-plugin/src/test/kotlin/io/github/projectmapk/sealedClassEnumizer/compiler/EnumizeLabelCaseTest.kt b/compiler-plugin/src/test/kotlin/io/github/projectmapk/sealedClassEnumizer/compiler/EnumizeLabelCaseTest.kt index 4c12149..30fd409 100644 --- a/compiler-plugin/src/test/kotlin/io/github/projectmapk/sealedClassEnumizer/compiler/EnumizeLabelCaseTest.kt +++ b/compiler-plugin/src/test/kotlin/io/github/projectmapk/sealedClassEnumizer/compiler/EnumizeLabelCaseTest.kt @@ -31,7 +31,8 @@ class EnumizeLabelCaseTest { // 具体ケースの集合と並びは一致していなければならない assertEquals( RuntimeLabelCase.entries.map { it.name }, - listOf(RuntimeLabelCase.PROJECT_DEFAULT.name) + EnumizeLabelCase.entries.map { it.name }, + listOf(RuntimeLabelCase.PROJECT_DEFAULT.name) + + EnumizeLabelCase.entries.map { it.name }, ) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4ec642a..4ccc3ba 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,7 +3,7 @@ kotlin = "2.4.10" # maven-plugin がコンパイル時に参照する Maven API の版(kotlin-maven-plugin 自身が依存する版に揃える) maven = "3.9.12" autoservice = "0.1.5" -ktfmt = "0.26.0" +ktfmt = "0.27.0" mavenPublish = "0.37.0" pluginPublish = "2.1.1" dokka = "2.2.0"