Skip to content

Commit 5b7c7af

Browse files
TapchicomaSpace Team
authored andcommitted
[Gradle] Fail the build if AGP has already configured Kotlin in the project
Since AGP 9.0 has support for built-in Kotlin and 'org.jetbrains.kotlin .android' plugin application in the project is not required. With this change we produce nice user error if 'org.jetbrains.kotlin .android' still was applied in the project after AGP. ^KT-80172 Verification Pending
1 parent 1756c32 commit 5b7c7af

File tree

5 files changed

+126
-0
lines changed

5 files changed

+126
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
3+
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
4+
*/
5+
6+
package org.jetbrains.kotlin.gradle.internal.diagnostics
7+
8+
import org.gradle.api.Project
9+
import org.jetbrains.kotlin.gradle.dsl.kotlinAndroidExtensionOrNull
10+
import org.jetbrains.kotlin.gradle.plugin.AndroidGradlePluginVersion
11+
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
12+
import org.jetbrains.kotlin.gradle.plugin.diagnostics.reportDiagnostic
13+
14+
internal object AgpWithBuiltInKotlinAppliedCheck {
15+
val minimalBuiltInKotlinSupportedAgpVersion = AndroidGradlePluginVersion(9, 0, 0, "alpha01")
16+
17+
fun Project.runAgpWithBuiltInKotlinIfAppliedCheck(
18+
agpVersionProvider: AndroidGradlePluginVersionProvider = AndroidGradlePluginVersionProvider.Default
19+
) {
20+
val isKotlinAndroidExtensionExists = kotlinAndroidExtensionOrNull != null
21+
val agpVersion = agpVersionProvider.get()
22+
if (isKotlinAndroidExtensionExists &&
23+
agpVersion != null &&
24+
agpVersion >= minimalBuiltInKotlinSupportedAgpVersion
25+
) {
26+
project.reportDiagnostic(
27+
KotlinToolingDiagnostics.AgpWithBuiltInKotlinIsAlreadyApplied(
28+
project.buildFile.relativeTo(project.rootDir),
29+
Throwable()
30+
)
31+
)
32+
}
33+
}
34+
35+
interface AndroidGradlePluginVersionProvider {
36+
fun get(): AndroidGradlePluginVersion?
37+
38+
object Default : AndroidGradlePluginVersionProvider {
39+
override fun get(): AndroidGradlePluginVersion? {
40+
return AndroidGradlePluginVersion.currentOrNull
41+
}
42+
}
43+
}
44+
}

libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.gradle.internal.KOTLIN_COMPILER_EMBEDDABLE
3131
import org.jetbrains.kotlin.gradle.internal.KOTLIN_MODULE_GROUP
3232
import org.jetbrains.kotlin.gradle.internal.attributes.setupAttributesMatchingStrategy
3333
import org.jetbrains.kotlin.gradle.internal.diagnostics.AgpCompatibilityCheck.runAgpCompatibilityCheckIfAgpIsApplied
34+
import org.jetbrains.kotlin.gradle.internal.diagnostics.AgpWithBuiltInKotlinAppliedCheck.runAgpWithBuiltInKotlinIfAppliedCheck
3435
import org.jetbrains.kotlin.gradle.internal.diagnostics.GradleCompatibilityCheck.runGradleCompatibilityCheck
3536
import org.jetbrains.kotlin.gradle.internal.diagnostics.KotlinCompilerEmbeddableCheck.checkCompilerEmbeddableInClasspath
3637
import org.jetbrains.kotlin.gradle.internal.properties.PropertiesBuildService
@@ -225,6 +226,7 @@ abstract class KotlinBasePluginWrapper : DefaultKotlinBasePlugin() {
225226
project.addPgpSignatureHelpers()
226227
project.addPomValidationHelpers()
227228
project.addSigningValidationHelpers()
229+
if (projectExtensionClass == KotlinAndroidProjectExtension::class) project.runAgpWithBuiltInKotlinIfAppliedCheck()
228230

229231
project.createKotlinExtension(projectExtensionClass).apply {
230232
coreLibrariesVersion = pluginVersion

libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/KotlinToolingDiagnostics.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,6 +1810,18 @@ internal object KotlinToolingDiagnostics {
18101810
.documentationLink(URI("https://kotl.in/9l92c3"))
18111811
}
18121812
}
1813+
1814+
internal object AgpWithBuiltInKotlinIsAlreadyApplied : ToolingDiagnosticFactory(FATAL, DiagnosticGroup.Kgp.Misconfiguration) {
1815+
operator fun invoke(
1816+
buildFile: File,
1817+
trace: Throwable,
1818+
) = build(throwable = trace) {
1819+
title("Failed to apply plugin 'com.jetbrains.kotlin.android'")
1820+
.description("The 'org.jetbrains.kotlin.android' plugin is no longer required for Kotlin support since AGP 9.0.")
1821+
.solution("Remove the 'org.jetbrains.kotlin.android' plugin from this project's build file: ${buildFile}.")
1822+
.documentationLink(URI("https://issuetracker.google.com/438678642"))
1823+
}
1824+
}
18131825
}
18141826

18151827
private fun String.indentLines(nSpaces: Int = 4, skipFirstLine: Boolean = true): String {
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
3+
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
4+
*/
5+
6+
package org.jetbrains.kotlin.gradle.unitTests.checkers
7+
8+
import org.gradle.api.InvalidUserCodeException
9+
import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension
10+
import org.jetbrains.kotlin.gradle.dsl.createKotlinExtension
11+
import org.jetbrains.kotlin.gradle.internal.diagnostics.AgpWithBuiltInKotlinAppliedCheck
12+
import org.jetbrains.kotlin.gradle.internal.diagnostics.AgpWithBuiltInKotlinAppliedCheck.minimalBuiltInKotlinSupportedAgpVersion
13+
import org.jetbrains.kotlin.gradle.internal.diagnostics.AgpWithBuiltInKotlinAppliedCheck.runAgpWithBuiltInKotlinIfAppliedCheck
14+
import org.jetbrains.kotlin.gradle.plugin.AndroidGradlePluginVersion
15+
import org.jetbrains.kotlin.gradle.util.assertNoDiagnostics
16+
import org.jetbrains.kotlin.gradle.util.buildProject
17+
import org.jetbrains.kotlin.gradle.util.checkDiagnostics
18+
import org.jetbrains.kotlin.gradle.util.registerMinimalVariantImplementationFactoriesForTests
19+
import org.junit.Test
20+
import kotlin.test.assertFails
21+
import kotlin.test.assertTrue
22+
23+
class AgpWithBuiltInKotlinAppliedCheckTest {
24+
25+
private val projectWithKotlinAndroidExtensionApplied = buildProject {
26+
gradle.registerMinimalVariantImplementationFactoriesForTests()
27+
project.createKotlinExtension(KotlinAndroidProjectExtension::class)
28+
}
29+
30+
private val unaffectedAgpVersion = FixedAndroidGradlePluginVersionProvider("8.12.0")
31+
private val unknownAgpVersion = FixedAndroidGradlePluginVersionProvider(null)
32+
private val affectedAgpVersion = FixedAndroidGradlePluginVersionProvider(minimalBuiltInKotlinSupportedAgpVersion.toString())
33+
34+
@Test
35+
fun testNotAffectedVersion() {
36+
projectWithKotlinAndroidExtensionApplied.runAgpWithBuiltInKotlinIfAppliedCheck(unaffectedAgpVersion)
37+
projectWithKotlinAndroidExtensionApplied.assertNoDiagnostics()
38+
}
39+
40+
@Test
41+
fun testAffectedVersion() {
42+
val error = assertFails {
43+
projectWithKotlinAndroidExtensionApplied.runAgpWithBuiltInKotlinIfAppliedCheck(affectedAgpVersion)
44+
}
45+
46+
assertTrue(error is InvalidUserCodeException)
47+
projectWithKotlinAndroidExtensionApplied.checkDiagnostics("checkers/agpBuiltInKotlinCheck/affectedVersion")
48+
}
49+
50+
@Test
51+
fun testNoAgpApplied() {
52+
projectWithKotlinAndroidExtensionApplied.runAgpWithBuiltInKotlinIfAppliedCheck(unknownAgpVersion)
53+
projectWithKotlinAndroidExtensionApplied.assertNoDiagnostics()
54+
}
55+
56+
internal class FixedAndroidGradlePluginVersionProvider(
57+
private val version: String?
58+
) : AgpWithBuiltInKotlinAppliedCheck.AndroidGradlePluginVersionProvider {
59+
override fun get(): AndroidGradlePluginVersion? {
60+
if (version == null) return null
61+
return AndroidGradlePluginVersion(version)
62+
}
63+
}
64+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[AgpWithBuiltInKotlinIsAlreadyApplied | FATAL] Failed to apply plugin 'com.jetbrains.kotlin.android'
2+
The 'org.jetbrains.kotlin.android' plugin is no longer required for Kotlin support since AGP 9.0.
3+
Remove the 'org.jetbrains.kotlin.android' plugin from this project's build file: build.gradle.
4+
See https://issuetracker.google.com/438678642 for more details.

0 commit comments

Comments
 (0)