diff --git a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/plugins/android/CompositeBuildPluginAndroidApp.kt b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/plugins/android/CompositeBuildPluginAndroidApp.kt index 3b686664..8188e75b 100644 --- a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/plugins/android/CompositeBuildPluginAndroidApp.kt +++ b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/plugins/android/CompositeBuildPluginAndroidApp.kt @@ -12,13 +12,13 @@ class CompositeBuildPluginAndroidApp { |import org.gradle.api.Plugin |import org.gradle.api.JavaVersion |import org.gradle.api.Project + |import org.gradle.api.plugins.JavaPluginExtension |import org.gradle.kotlin.dsl.configure |import org.gradle.api.tasks.compile.JavaCompile |import org.gradle.jvm.toolchain.JavaLanguageVersion |import org.gradle.jvm.toolchain.JavaToolchainService |import org.gradle.kotlin.dsl.dependencies |import org.gradle.kotlin.dsl.withType - |import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension | |class CompositeBuildPluginAndroidApp : Plugin { | override fun apply(target: Project) { @@ -51,11 +51,12 @@ class CompositeBuildPluginAndroidApp { | buildFeatures { | compose = true | } + | compileOptions { + | sourceCompatibility = JavaVersion.VERSION_${versions.project.jdk} + | targetCompatibility = JavaVersion.VERSION_${versions.project.jdk} + | } | } - | target.extensions.getByType(KotlinAndroidProjectExtension::class.java).apply { - | jvmToolchain(${versions.project.jdk}) - | } - | target.extensions.getByType(org.gradle.api.plugins.JavaPluginExtension::class.java).apply { + | target.extensions.getByType(JavaPluginExtension::class.java).apply { | toolchain.languageVersion.set(org.gradle.jvm.toolchain.JavaLanguageVersion.of(${versions.project.jdk})) | } | ${hiltToolchainFix(versions, di)} @@ -70,7 +71,11 @@ class CompositeBuildPluginAndroidApp { fun provideKotlinProcessor(versions: Versions, di: DependencyInjection): String { if (versions.kotlin.kotlinProcessor.processor == Processor.KAPT) { - return """apply("kotlin-kapt")""" + return if (versions.android.agp.isAgp9()) { + """apply("com.android.legacy-kapt")""" + } else { + """apply("kotlin-kapt")""" + } } val shouldApplyKsp = di == DependencyInjection.HILT || versions.android.roomDatabase return if (shouldApplyKsp) """apply("com.google.devtools.ksp")""" else "" diff --git a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/plugins/android/CompositeBuildPluginAndroidKmpLib.kt b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/plugins/android/CompositeBuildPluginAndroidKmpLib.kt index 0708d2e6..3e275101 100644 --- a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/plugins/android/CompositeBuildPluginAndroidKmpLib.kt +++ b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/plugins/android/CompositeBuildPluginAndroidKmpLib.kt @@ -1,5 +1,6 @@ package io.github.cdsap.projectgenerator.generator.plugins.android +import io.github.cdsap.projectgenerator.generator.extension.isAgp9 import io.github.cdsap.projectgenerator.model.DependencyInjection import io.github.cdsap.projectgenerator.model.Processor import io.github.cdsap.projectgenerator.model.Versions @@ -56,7 +57,11 @@ class CompositeBuildPluginAndroidKmpLib { private fun provideKotlinProcessor(versions: Versions, di: DependencyInjection): String { if (versions.kotlin.kotlinProcessor.processor == Processor.KAPT) { - return """apply("kotlin-kapt")""" + return if (versions.android.agp.isAgp9()) { + """apply("com.android.legacy-kapt")""" + } else { + """apply("kotlin-kapt")""" + } } val shouldApplyKsp = di == DependencyInjection.HILT || versions.android.roomDatabase return if (shouldApplyKsp) """apply("com.google.devtools.ksp")""" else "" diff --git a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/plugins/android/CompositeBuildPluginAndroidLib.kt b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/plugins/android/CompositeBuildPluginAndroidLib.kt index c86db2c6..db97eb2a 100644 --- a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/plugins/android/CompositeBuildPluginAndroidLib.kt +++ b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/plugins/android/CompositeBuildPluginAndroidLib.kt @@ -12,9 +12,9 @@ class CompositeBuildPluginAndroidLib { |import org.gradle.api.Plugin |import org.gradle.api.JavaVersion |import org.gradle.api.Project + |import org.gradle.api.plugins.JavaPluginExtension |import org.gradle.kotlin.dsl.configure |import org.gradle.kotlin.dsl.dependencies - |import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension | |class CompositeBuildPluginAndroidLib : Plugin { | override fun apply(target: Project) { @@ -49,11 +49,7 @@ class CompositeBuildPluginAndroidLib { | } | } | - | target.extensions.getByType(KotlinAndroidProjectExtension::class.java).apply { - | jvmToolchain(${versions.project.jdk}) - | } - | - | target.extensions.getByType(org.gradle.api.plugins.JavaPluginExtension::class.java).apply { + | target.extensions.getByType(JavaPluginExtension::class.java).apply { | toolchain.languageVersion.set(org.gradle.jvm.toolchain.JavaLanguageVersion.of(${versions.project.jdk})) | } | @@ -67,7 +63,11 @@ class CompositeBuildPluginAndroidLib { fun provideKotlinProcessor(versions: Versions, di: DependencyInjection): String { if (versions.kotlin.kotlinProcessor.processor == Processor.KAPT) { - return """apply("kotlin-kapt")""" + return if (versions.android.agp.isAgp9()) { + """apply("com.android.legacy-kapt")""" + } else { + """apply("kotlin-kapt")""" + } } val shouldApplyKsp = di == DependencyInjection.HILT || versions.android.roomDatabase return if (shouldApplyKsp) """apply("com.google.devtools.ksp")""" else "" diff --git a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/rootproject/BuildGradle.kt b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/rootproject/BuildGradle.kt index 9a0d849d..da4120f2 100644 --- a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/rootproject/BuildGradle.kt +++ b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/rootproject/BuildGradle.kt @@ -1,5 +1,6 @@ package io.github.cdsap.projectgenerator.generator.rootproject +import io.github.cdsap.projectgenerator.generator.extension.isAgp9 import io.github.cdsap.projectgenerator.model.DependencyInjection import io.github.cdsap.projectgenerator.model.Processor import io.github.cdsap.projectgenerator.model.Versions @@ -9,7 +10,7 @@ class BuildGradle { fun getAndroid(versions: Versions, di: DependencyInjection) = """ plugins { alias(libs.plugins.kotlin.jvm) apply false - alias(libs.plugins.kotlin.android) apply false + ${kotlinAndroidPlugin(versions)} alias(libs.plugins.kotlin.compose) apply false alias(libs.plugins.android.application) apply false ${androidLibraryRootPlugin(versions)} @@ -56,4 +57,12 @@ class BuildGradle { } } + private fun kotlinAndroidPlugin(versions: Versions): String { + return if (versions.android.agp.isAgp9()) { + "" + } else { + "alias(libs.plugins.kotlin.android) apply false" + } + } + } diff --git a/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/AndroidKotlinMultiplatformLibraryE2EValidationTest.kt b/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/AndroidKotlinMultiplatformLibraryE2EValidationTest.kt index 158b718d..973d4791 100644 --- a/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/AndroidKotlinMultiplatformLibraryE2EValidationTest.kt +++ b/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/AndroidKotlinMultiplatformLibraryE2EValidationTest.kt @@ -85,7 +85,7 @@ class AndroidKotlinMultiplatformLibraryE2EValidationTest { } private fun assemble(projectName: String) = GradleRunner.create() - .withProjectDir(File("$tempDir/$projectName/project_kts")) + .withProjectDir(File("$tempDir/$projectName/project_kts").also(AndroidSdkTestSupport::writeLocalProperties)) .withArguments("assemble") .build() } diff --git a/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/AndroidSdkTestSupport.kt b/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/AndroidSdkTestSupport.kt new file mode 100644 index 00000000..627c8eaa --- /dev/null +++ b/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/AndroidSdkTestSupport.kt @@ -0,0 +1,23 @@ +package io.github.cdsap.projectgenerator + +import org.junit.jupiter.api.Assumptions.assumeTrue +import java.io.File + +object AndroidSdkTestSupport { + fun writeLocalProperties(projectDir: File) { + val sdkDir = androidSdkDir() + assumeTrue(sdkDir != null, "Android SDK not configured. Set ANDROID_HOME or ANDROID_SDK_ROOT.") + + File(projectDir, "local.properties").writeText("sdk.dir=${sdkDir!!.invariantSeparatorsPath}\n") + } + + private fun androidSdkDir(): File? { + return listOfNotNull( + System.getenv("ANDROID_HOME"), + System.getenv("ANDROID_SDK_ROOT"), + "${System.getProperty("user.home")}/Library/Android/sdk" + ) + .map(::File) + .firstOrNull { it.isDirectory } + } +} diff --git a/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/RoomDiVariantsAssembleE2EValidationTest.kt b/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/RoomDiVariantsAssembleE2EValidationTest.kt index 20622671..9a9b1576 100644 --- a/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/RoomDiVariantsAssembleE2EValidationTest.kt +++ b/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/RoomDiVariantsAssembleE2EValidationTest.kt @@ -49,6 +49,7 @@ class RoomDiVariantsAssembleE2EValidationTest { ).write() val projectDir = File("$tempDir/$projectName/project_kts") + AndroidSdkTestSupport.writeLocalProperties(projectDir) val assemble = GradleRunner.create() .withProjectDir(projectDir) .withArguments("clean", "assemble") diff --git a/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/generator/rootproject/BuildGradleTest.kt b/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/generator/rootproject/BuildGradleTest.kt new file mode 100644 index 00000000..73c9dcb3 --- /dev/null +++ b/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/generator/rootproject/BuildGradleTest.kt @@ -0,0 +1,35 @@ +package io.github.cdsap.projectgenerator.generator.rootproject + +import io.github.cdsap.projectgenerator.model.Android +import io.github.cdsap.projectgenerator.model.Kotlin +import io.github.cdsap.projectgenerator.model.KotlinProcessor +import io.github.cdsap.projectgenerator.model.Processor +import io.github.cdsap.projectgenerator.model.Versions +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +class BuildGradleTest { + @Test + fun `android root build file omits kotlin android plugin for agp9 built in kotlin`() { + val result = BuildGradle().getAndroid(Versions(), Versions().di) + + assertFalse(result.contains("libs.plugins.kotlin.android")) + } + + @Test + fun `android root build file keeps kotlin android plugin before agp9`() { + val result = BuildGradle().getAndroid(Versions(android = Android(agp = "8.13.0")), Versions().di) + + assertTrue(result.contains("alias(libs.plugins.kotlin.android) apply false")) + } + + @Test + fun `android root build file omits ksp plugin for kapt`() { + val versions = Versions(kotlin = Kotlin(kotlinProcessor = KotlinProcessor(Processor.KAPT))) + + val result = BuildGradle().getAndroid(versions, versions.di) + + assertFalse(result.contains("libs.plugins.kotlin.ksp")) + } +} diff --git a/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/writer/ConventionPluginWriterTest.kt b/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/writer/ConventionPluginWriterTest.kt index 55a30eff..5c5a2f57 100644 --- a/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/writer/ConventionPluginWriterTest.kt +++ b/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/writer/ConventionPluginWriterTest.kt @@ -7,10 +7,14 @@ import io.github.cdsap.projectgenerator.generator.plugins.android.CompositeBuild import io.github.cdsap.projectgenerator.generator.plugins.android.CompositeBuildPluginAndroidLib import io.github.cdsap.projectgenerator.generator.plugins.jvm.CompositeBuildJvmLib import io.github.cdsap.projectgenerator.model.Android +import io.github.cdsap.projectgenerator.model.Kotlin +import io.github.cdsap.projectgenerator.model.KotlinProcessor import io.github.cdsap.projectgenerator.model.LanguageAttributes +import io.github.cdsap.projectgenerator.model.Processor import io.github.cdsap.projectgenerator.model.TypeProjectRequested import io.github.cdsap.projectgenerator.model.Versions import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test import org.junit.jupiter.api.io.TempDir @@ -143,6 +147,28 @@ class ConventionPluginWriterTest { ) } + @Test + fun `write should use legacy kapt plugin for agp9 built in kotlin`() { + val projectName = "androidKapt" + val language = LanguageAttributes(projectName = "${tempDir.path}/$projectName", extension = "gradle.kts") + val versions = Versions(kotlin = Kotlin(kotlinProcessor = KotlinProcessor(Processor.KAPT))) + val writer = ConventionPluginWriter( + languages = listOf(language), + versions = versions, + requested = TypeProjectRequested.ANDROID + ) + + writer.write() + + val appPlugin = File("${language.projectName}/build-logic/convention/src/main/kotlin/com/logic/CompositeBuildPluginAndroidApp.kt") + val libPlugin = File("${language.projectName}/build-logic/convention/src/main/kotlin/com/logic/CompositeBuildPluginAndroidLib.kt") + + assertTrue(appPlugin.readText().contains("apply(\"com.android.legacy-kapt\")")) + assertTrue(libPlugin.readText().contains("apply(\"com.android.legacy-kapt\")")) + assertFalse(appPlugin.readText().contains("apply(\"kotlin-kapt\")")) + assertFalse(libPlugin.readText().contains("apply(\"kotlin-kapt\")")) + } + private fun assertAndroidConventionFilesExist(projectBasePath: String, versions: Versions) { val conventionSrcDir = File("$projectBasePath/build-logic/convention/src/main/kotlin/com/logic") assertTrue(conventionSrcDir.exists() && conventionSrcDir.isDirectory, "Convention src dir missing for $projectBasePath")