Skip to content

Commit 8caf702

Browse files
authored
AGP9 support (#6703)
* AGP9 support * remove debug * Fix the replacement
1 parent d16ad72 commit 8caf702

File tree

75 files changed

+903
-636
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+903
-636
lines changed

gradle/libraries.toml

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
11
[versions]
22
# The version we use by default to build the libs, in tests and benchmarks
3-
# Can be as high as IJ supports
4-
# Consult https://kotlinlang.org/docs/multiplatform-compatibility-guide.html#version-compatibility for compatibility with KGP
3+
# Can be as high as IJ supports.
4+
# See https://kotlinlang.org/docs/multiplatform-compatibility-guide.html#version-compatibility for compatibility with KGP
55
android-plugin = "8.7.2"
6-
# The version we compile against
7-
android-plugin-min = "8.0.0"
8-
# The version used by the 'android-plugin-max' test
9-
android-plugin-max = "8.9.0"
106
android-sdkversion-compile = "34"
117
android-sdkversion-compilebenchmark = "34"
128
android-sdkversion-min = "16"
139
android-sdkversion-compose-min = "21"
1410
android-sdkversion-benchmark-min = "24"
1511
android-sdkversion-target = "30"
1612
androidx-sqlite = "2.3.1"
17-
# This is used by the gradle integration tests to get the artifacts locally
13+
# This is used by the Gradle integration tests to get the artifacts locally
1814
apollo = "5.0.0-alpha.3-SNAPSHOT"
1915
apollo-execution = "0.1.0"
2016
apollo-normalizedcache-incubating = "1.0.0-alpha.4"
@@ -31,9 +27,7 @@ gratatouille-runtime = "0.1.2"
3127
javaPoet = "1.13.0"
3228
jetbrains-annotations = "24.0.1"
3329
junit = "4.13.2"
34-
kotlin-plugin-min = "1.9.0"
3530
kotlin-plugin = "2.1.21"
36-
kotlin-plugin-max = "2.1.21"
3731
kotlinx-coroutines = "1.9.0"
3832
kotlinx-datetime = "0.5.0"
3933
kotlinx-serialization-runtime = "1.6.2"
@@ -50,7 +44,9 @@ truth = "1.1.3"
5044

5145
[libraries]
5246
android-plugin = { group = "com.android.tools.build", name = "gradle", version.ref = "android-plugin" }
53-
android-plugin-min = { group = "com.android.tools.build", name = "gradle", version.ref = "android-plugin-min" }
47+
android-plugin8 = { group = "com.android.tools.build", name = "gradle", version= "8.0.0" }
48+
android-plugin9 = { group = "com.android.tools.build", name = "gradle", version = "9.0.0-alpha05" }
49+
android-tools-common = { module = "com.android.tools:common", version = "31.0.0" }
5450
android-test-runner = { group = "androidx.test", name = "runner", version = "1.5.2" }
5551
androidx-test-uiautomator = "androidx.test.uiautomator:uiautomator:2.2.0"
5652
androidx-activity = "androidx.activity:activity-ktx:1.7.2"
@@ -123,11 +119,8 @@ kotlin-compiletesting = { group = "dev.zacsweers.kctfork", name = "core", versio
123119
graphql-java = "com.graphql-java:graphql-java:20.4"
124120
# The main kotlin version for build-logic and Gradle tests
125121
kotlin-plugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin-plugin" }
126-
kotlin-plugin-annotations = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin-annotations", version.ref = "kotlin-plugin"}
122+
kotlin-plugin-annotations = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin-annotations", version.ref = "kotlin-plugin" }
127123
kotlin-plugin-compose = { group = "org.jetbrains.kotlin", name = "compose-compiler-gradle-plugin", version.ref = "kotlin-plugin" }
128-
# For Gradle integration tests to make sure we stay compatible with 1.5.0
129-
kotlin-plugin-min = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin-plugin-min" }
130-
kotlin-plugin-max = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin-plugin-max" }
131124
kotlin-reflect = { group = "org.jetbrains.kotlin", name = "kotlin-reflect" } # use same version as apiVersion
132125
kotlin-stdlib-common = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-common" } # use same version as apiVersion
133126
kotlin-stdlib-jvm = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib" } # use same version as apiVersion
@@ -136,7 +129,7 @@ kotlin-test-junit = { group = "org.jetbrains.kotlin", name = "kotlin-test-junit"
136129
# The Kotlin/JS standard library has an older version (2.0.20-release-360) than the compiler (2.1.0). Such a configuration is not supported.
137130
# Please, make sure that the standard library has the version in the range [2.1.0 .. 2.1.255]. Adjust your project's settings if necessary.
138131
kotlin-stdlib-js = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-js", version.ref = "kotlin-plugin" }
139-
kotlin-stdlib-wasm-js = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-wasm-js", version.ref = "kotlin-plugin" }
132+
kotlin-stdlib-wasm-js = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-wasm-js", version.ref = "kotlin-plugin" }
140133
kotlinx-benchmark-runtime = "org.jetbrains.kotlinx:kotlinx-benchmark-runtime:0.4.8"
141134
kotlinx-benchmark = "org.jetbrains.kotlinx:kotlinx-benchmark-plugin:0.4.12"
142135
kotlinx-browser = "org.jetbrains.kotlinx:kotlinx-browser:0.2"
@@ -151,7 +144,7 @@ kotlinx-serialization-plugin = { group = "org.jetbrains.kotlin", name = "kotlin-
151144
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinx-serialization-runtime" }
152145
kotlinx-binarycompatibilityvalidator = { group = "org.jetbrains.kotlinx", name = "binary-compatibility-validator", version = "0.16.3" }
153146
ksp = { module = "com.google.devtools.ksp:symbol-processing-gradle-plugin", version.ref = "ksp" }
154-
ktor-client-core = { group = "io.ktor", name= "ktor-client-core", version.ref = "ktor" }
147+
ktor-client-core = { group = "io.ktor", name = "ktor-client-core", version.ref = "ktor" }
155148
ktor-client-okhttp = { group = "io.ktor", name = "ktor-client-okhttp", version.ref = "ktor" }
156149
ktor-client-curl = { group = "io.ktor", name = "ktor-client-curl", version.ref = "ktor" }
157150
ktor-client-darwin = { group = "io.ktor", name = "ktor-client-darwin", version.ref = "ktor" }
@@ -196,6 +189,7 @@ nmcp = "com.gradleup.nmcp:nmcp:1.0.4-SNAPSHOT-7663b69da8628aa2a8e73334af3fb05268
196189
slf4j-simple = "org.slf4j:slf4j-simple:2.0.13"
197190
slf4j-nop = "org.slf4j:slf4j-nop:2.0.13"
198191
licensee = "app.cash.licensee:licensee-gradle-plugin:1.12.0"
192+
kgp-compile = "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0"
199193

200194
[plugins]
201195
apollo = { id = "com.apollographql.apollo", version.ref = "apollo" }
@@ -204,12 +198,8 @@ compat-patrouille = { id = "com.gradleup.compat.patrouille", version.ref = "comp
204198
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin-plugin" }
205199
kotlin-sam = { id = "org.jetbrains.kotlin.plugin.sam.with.receiver", version.ref = "kotlin-plugin" }
206200
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin-plugin" }
207-
kotlin-android-min = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin-plugin-min" }
208-
kotlin-android-max = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin-plugin-max" }
209201
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin-plugin" }
210-
kotlin-jvm-min = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin-plugin-min" }
211202
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin-plugin" }
212203
android-application = { id = "com.android.application", version.ref = "android-plugin" }
213-
android-application-max = { id = "com.android.application", version.ref = "android-plugin-max" }
214204
android-library = { id = "com.android.library", version.ref = "android-plugin" }
215-
grammarkit = { id = "org.jetbrains.grammarkit", version = "2022.3.2.2" }
205+
android-kmp-library = { id = "com.android.kotlin.multiplatform.library", version.ref = "android-plugin"}

gradle/repositories.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ listOf(pluginManagement.repositories, dependencyResolutionManagement.repositorie
1717
includeGroup("com.android.databinding")
1818
includeGroup("com.android.lint")
1919
includeGroup("com.google.testing.platform")
20+
includeGroup("com.android.kotlin.multiplatform.library")
2021
/*
2122
* The com.android.tools groupId is verbose because we don't want to clash with com.android.tools:r8 in the raw repository
2223
*/

gradle/test.settings.gradle.kts

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,17 @@
1-
apply(from = rootDir.resolve("../../../../gradle/repositories.gradle.kts").absolutePath)
2-
31
dependencyResolutionManagement {
42
versionCatalogs {
53
create("libs") {
64
// we are in something like
75
// - libraries/apollo-gradle-plugin/testProjects/$name
86
// - libraries/apollo-gradle-plugin/build/testProject
9-
from(files(rootDir.resolve("../../../../gradle/libraries.toml").absolutePath))
7+
from(files(rootDir.resolve("../../../../gradle/libraries.toml")))
108
}
119
}
1210
}
13-
1411
pluginManagement {
15-
repositories {
16-
maven {
17-
url = uri(rootDir.resolve("../../../../build/localMaven").absolutePath)
18-
}
19-
}
20-
resolutionStrategy {
21-
eachPlugin {
22-
// Workaround for the Kotlin plugin 1.5.0 not publishing the marker
23-
if(requested.id.id.startsWith("org.jetbrains.kotlin")) {
24-
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}")
25-
}
26-
}
27-
}
28-
}
29-
30-
dependencyResolutionManagement {
31-
repositories {
32-
maven {
33-
url = uri(rootDir.resolve("../../../../build/localMaven").absolutePath)
34-
}
12+
listOf(repositories, dependencyResolutionManagement.repositories).forEach {
13+
it.mavenCentral()
14+
it.google()
15+
it.maven("../../../../build/localMaven")
3516
}
36-
}
17+
}

libraries/apollo-gradle-plugin/api/apollo-gradle-plugin.api

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,11 @@ public abstract interface class com/apollographql/apollo/gradle/api/Service {
213213

214214
public abstract interface class com/apollographql/apollo/gradle/api/Service$DirectoryConnection {
215215
public abstract fun connectToAllAndroidVariants ()V
216+
public abstract fun connectToAndroidComponent (Ljava/lang/Object;Z)V
216217
public abstract fun connectToAndroidSourceSet (Ljava/lang/String;)V
218+
public abstract fun connectToAndroidTestComponents (Z)V
217219
public abstract fun connectToAndroidVariant (Ljava/lang/Object;)V
220+
public abstract fun connectToAndroidVariants (Z)V
218221
public abstract fun connectToJavaSourceSet (Ljava/lang/String;)V
219222
public abstract fun connectToKotlinSourceSet (Ljava/lang/String;)V
220223
public abstract fun getOutputDir ()Lorg/gradle/api/provider/Provider;

libraries/apollo-gradle-plugin/build.gradle.kts

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
22
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
33

4+
45
plugins {
56
id("org.jetbrains.kotlin.jvm")
67
id("com.google.devtools.ksp")
@@ -21,14 +22,76 @@ gratatouille {
2122
pluginMarker("com.apollographql.apollo")
2223
}
2324

25+
val agpCompat = kotlin.target.compilations.create("agp-compat")
26+
27+
mapOf(
28+
"8" to setOf(libs.android.plugin8),
29+
"9" to setOf(libs.android.plugin9, libs.kotlin.plugin)
30+
).forEach {
31+
val compilation = kotlin.target.compilations.create("agp-${it.key}")
32+
33+
compilation.associateWith(agpCompat)
34+
kotlin.target.compilations.getByName("main").associateWith(compilation)
35+
36+
tasks.jar {
37+
from(compilation.output.classesDirs)
38+
}
39+
dependencies {
40+
add(compilation.compileOnlyConfigurationName, project(":apollo-annotations"))
41+
it.value.forEach {
42+
add(compilation.compileOnlyConfigurationName, it)
43+
}
44+
// See https://issuetracker.google.com/issues/445209309
45+
add(compilation.compileOnlyConfigurationName, libs.gradle.api.min)
46+
}
47+
}
48+
49+
tasks.jar.configure {
50+
from(agpCompat.output.classesDirs)
51+
}
52+
53+
/**
54+
* associateWith() pulls the secondary compilations into the main dependencies,
55+
* which we don't want.
56+
*
57+
* An alternative would be to not use `associateWith()` but that fails in the IDE,
58+
* probably because there is no way to set `AbstractKotlinCompile.friendSourceSets`
59+
* from public API.
60+
*/
61+
configurations.compileOnly.get().dependencies.removeIf {
62+
when {
63+
it is ExternalDependency && it.group == "com.android.tools.build" && it.name == "gradle" -> true
64+
else -> false
65+
}
66+
}
67+
/**
68+
* Also force our own version of KGP
69+
*/
70+
configurations.compileClasspath.get().resolutionStrategy {
71+
eachDependency {
72+
val kgp = libs.kgp.compile.get()
73+
if (requested.group == kgp.group && requested.name == kgp.name) {
74+
/**
75+
* Use our declared KGP version
76+
*/
77+
useVersion(kgp.version!!)
78+
}
79+
}
80+
}
81+
82+
kotlin.target.compilations.get("main").apply {
83+
associateWith(agpCompat)
84+
}
85+
2486
dependencies {
2587
gratatouille(project(":apollo-gradle-plugin-tasks"))
2688

27-
compileOnly(libs.gradle.api.min)
28-
compileOnly(libs.kotlin.plugin.min)
29-
compileOnly(libs.android.plugin.min)
89+
add(agpCompat.compileOnlyConfigurationName, libs.gradle.api.min)
90+
add(agpCompat.compileOnlyConfigurationName, project(":apollo-annotations"))
3091

3192
compileOnly(libs.gradle.api.min)
93+
compileOnly(libs.kgp.compile)
94+
3295
implementation(project(":apollo-annotations"))
3396
implementation(libs.gratatouille.wiring.runtime)
3497

@@ -41,13 +104,9 @@ dependencies {
41104
testImplementation(libs.apollo.execution)
42105
testImplementation(libs.apollo.execution.http4k)
43106
testImplementation(gradleTestKit())
44-
45107
testImplementation(platform(libs.http4k.bom.get()))
46108
testImplementation(libs.http4k.core)
47109
testImplementation(libs.http4k.server.jetty)
48-
testImplementation(libs.slf4j.nop.get().toString()) {
49-
because("jetty uses SL4F")
50-
}
51110
lintChecks(libs.androidx.lint.rules)
52111
}
53112

@@ -87,6 +146,7 @@ val publishDependencies = tasks.register("publishDependencies") {
87146
dependsOn(":apollo-tooling:publishAllPublicationsToPluginTestRepository")
88147
}
89148

149+
90150
tasks.withType<Test> {
91151
dependsOn(publishDependencies)
92152
dependsOn(cleanStaleTestProjects)
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
@file:Suppress("DEPRECATION")
2+
3+
package com.apollographql.com.apollographql.apollo
4+
5+
import com.android.build.gradle.AppExtension
6+
import com.android.build.gradle.BaseExtension
7+
import com.android.build.gradle.LibraryExtension
8+
import com.android.build.gradle.TestedExtension
9+
import com.android.build.gradle.api.BaseVariant
10+
import com.apollographql.apollo.AgpCompat
11+
import com.apollographql.apollo.AgpComponent
12+
import com.apollographql.apollo.ComponentFilter
13+
import org.gradle.api.file.Directory
14+
import org.gradle.api.provider.Provider
15+
import org.gradle.api.tasks.TaskProvider
16+
17+
internal class Agp8(override val version: String, extension: Any): AgpCompat {
18+
private val extension = extension as BaseExtension
19+
20+
override fun compileSdk(): String? {
21+
return extension.compileSdkVersion
22+
}
23+
24+
override fun targetSdk(): Int? {
25+
return extension.defaultConfig.targetSdk
26+
}
27+
28+
override fun minSdk(): Int? {
29+
return extension.defaultConfig.minSdkVersion?.apiLevel
30+
}
31+
32+
override fun onComponent(filter: ComponentFilter, block: (AgpComponent) -> Unit) {
33+
val main = filter in setOf(ComponentFilter.All, ComponentFilter.Main)
34+
val test = filter in setOf(ComponentFilter.All, ComponentFilter.Test)
35+
36+
if (main) {
37+
if (extension is LibraryExtension) {
38+
extension.libraryVariants.configureEach {
39+
block(Agp8Component(it))
40+
}
41+
}
42+
if (extension is AppExtension) {
43+
extension.applicationVariants.configureEach {
44+
block(Agp8Component(it))
45+
}
46+
}
47+
}
48+
if (test) {
49+
if (extension is TestedExtension) {
50+
extension.testVariants.configureEach {
51+
block(Agp8Component(it))
52+
}
53+
extension.unitTestVariants.configureEach {
54+
block(Agp8Component(it))
55+
}
56+
}
57+
}
58+
}
59+
60+
fun registerSourceGeneratingTask(
61+
variant: Any,
62+
hardCodedOutputDir: Provider<Directory>,
63+
task: TaskProvider<*>,
64+
) {
65+
check(variant is BaseVariant) {
66+
"Apollo: an instance of com.android.build.gradle.api.BaseVariant was expected (found '$variant')"
67+
}
68+
variant.registerJavaGeneratingTask(task, hardCodedOutputDir.get().asFile)
69+
}
70+
}
71+
72+
internal class Agp8Component(private val base: BaseVariant): AgpComponent {
73+
override val name: String
74+
get() = base.name
75+
76+
val sourceSets: List<String>
77+
get() = base.sourceSets.map { it.name }
78+
79+
override val wrappedComponent: Any
80+
get() = base
81+
}
82+

0 commit comments

Comments
 (0)