Skip to content

Commit f97dd0a

Browse files
authored
Isolated Projects support (#6351)
* Add support for isolated projects * Revert Gradle for some reason it broke the included build
1 parent 53a63c1 commit f97dd0a

File tree

11 files changed

+83
-31
lines changed

11 files changed

+83
-31
lines changed

gradle.properties

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,11 @@ POM_DEVELOPER_NAME=Apollo
1515

1616
android.useAndroidX=true
1717

18-
# Keep in sync with other projects
19-
# Give more memory to the Gradle daemon
2018
org.gradle.jvmargs=-Xmx8g
21-
# Do not automatically add stdlib dependency
2219
kotlin.stdlib.default.dependency=false
23-
# Enable the build cache
2420
org.gradle.caching=true
25-
# Enable the configuration cache
2621
org.gradle.configuration-cache=true
27-
22+
#org.gradle.unsafe.isolated-projects=true
2823
org.gradle.parallel=true
2924

3025
org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled

libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo/gradle/internal/DefaultApolloExtension.kt

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,15 @@ abstract class DefaultApolloExtension(
278278
null -> { // default: automatic detection
279279
project.configurations.configureEach {
280280
it.dependencies.configureEach {
281-
// Try to detect if a native version of apollo-normalized-cache-sqlite is in the classpath
282-
if (it.group?.contains("apollo") == true
281+
/*
282+
* Try to detect if a native version of apollo-normalized-cache-sqlite is in the classpath
283+
* This is a heuristic and will not work in 100% of the cases.
284+
*
285+
* Note: we only check external dependencies as reading the group of project dependencies
286+
* is not compatible with isolated projects
287+
*/
288+
if (it is ExternalModuleDependency
289+
&& it.group?.contains("apollo") == true
283290
&& it.name.contains("normalized-cache-sqlite")
284291
&& !it.name.contains("jvm")
285292
&& !it.name.contains("android")) {
@@ -360,10 +367,8 @@ abstract class DefaultApolloExtension(
360367

361368
it.inputs.property("allVersions", Callable {
362369
val allDeps = (
363-
getDeps(project.rootProject.buildscript.configurations) +
364370
getDeps(project.buildscript.configurations) +
365371
getDeps(project.configurations)
366-
367372
)
368373
allDeps.distinct().sorted()
369374
})
@@ -1033,12 +1038,16 @@ abstract class DefaultApolloExtension(
10331038
.filter {
10341039
/**
10351040
* When using plugins {}, the group is the plugin id, not the maven group
1036-
*/
1037-
/**
1041+
*
10381042
* the "_" check is for refreshVersions,
10391043
* see https://github.com/jmfayard/refreshVersions/issues/507
1044+
*
1045+
* Note: we only check external dependencies as reading the group of project dependencies
1046+
* is not compatible with isolated projects
1047+
*
10401048
*/
1041-
it.group in listOf("com.apollographql.apollo", "com.apollographql.apollo.external")
1049+
it is ExternalModuleDependency
1050+
&& it.group in listOf("com.apollographql.apollo", "com.apollographql.apollo.external")
10421051
&& it.version != "_"
10431052
}.mapNotNull { dependency ->
10441053
dependency.version

libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo/gradle/internal/KotlinPluginFacade.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ fun Project.apolloGetKotlinPluginVersion(): String? {
4343
return project.getKotlinPluginVersion()
4444
}
4545

46+
/*
47+
* Inspired by SQLDelight:
48+
* https://github.com/sqldelight/sqldelight/blob/ae8c348f6cf76822828bc65832106ec151ca5b6c/sqldelight-gradle-plugin/src/main/kotlin/app/cash/sqldelight/gradle/kotlin/LinkSqlite.kt#L7
49+
* https://github.com/sqldelight/sqldelight/issues/1442
50+
*
51+
* Ideally this can be forwarded automatically, but I don't think this can be done as of today.
52+
*/
4653
internal fun linkSqlite(project: Project) {
4754
val extension = project.kotlinMultiplatformExtension ?: return
4855

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ tasks.register("cleanStaleTestProjects") {
134134
}
135135
}
136136

137-
tasks.withType<Test> {
137+
tasks.register("publishDependencies") {
138+
dependsOn("publishAllPublicationsToPluginTestRepository")
138139
dependsOn(":apollo-annotations:publishAllPublicationsToPluginTestRepository")
139140
dependsOn(":apollo-api:publishAllPublicationsToPluginTestRepository")
140141
dependsOn(":apollo-ast:publishAllPublicationsToPluginTestRepository")
@@ -143,8 +144,10 @@ tasks.withType<Test> {
143144
dependsOn(":apollo-compiler:publishAllPublicationsToPluginTestRepository")
144145
dependsOn(":apollo-gradle-plugin-external:publishAllPublicationsToPluginTestRepository")
145146
dependsOn(":apollo-tooling:publishAllPublicationsToPluginTestRepository")
146-
dependsOn("publishAllPublicationsToPluginTestRepository")
147+
}
147148

149+
tasks.withType<Test> {
150+
dependsOn("publishDependencies")
148151
dependsOn("cleanStaleTestProjects")
149152

150153
addRelativeInput("testFiles", "testFiles")

libraries/apollo-gradle-plugin/src/test-java11/kotlin/com/apollographql/apollo/gradle/test/GradleToolingTests.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ class GradleToolingTests {
7474

7575
@Test
7676
fun `tooling model exposes apollo metadata dependencies`() {
77-
TestUtils.withTestProject("multi-modules-diamond") { dir ->
77+
testProjectWithIsolatedProjectsWorkaround("multi-modules-diamond") { dir ->
78+
7879
val toolingModel = GradleConnector.newConnector()
7980
.forProjectDirectory(File(dir, "leaf"))
8081
.connect()

libraries/apollo-gradle-plugin/src/test-java11/kotlin/com/apollographql/apollo/gradle/test/KotlinPluginVersionTests.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import util.TestUtils
44
import com.google.common.truth.Truth
55
import org.gradle.testkit.runner.TaskOutcome
66
import org.junit.Test
7+
import util.disableIsolatedProjects
78
import java.io.File
89

910
class KotlinPluginVersionTests {
@@ -14,6 +15,8 @@ class KotlinPluginVersionTests {
1415
@Test
1516
fun `kotlin JVM min version succeeds`() {
1617
TestUtils.withTestProject("kotlin-plugin-version-min") { dir ->
18+
dir.disableIsolatedProjects() // old KGP versions do not support isolated projects
19+
1720
val result = TestUtils.executeTask("build", dir)
1821

1922
Truth.assertThat(result.task(":build")!!.outcome).isEqualTo(TaskOutcome.SUCCESS)

libraries/apollo-gradle-plugin/src/test-java11/kotlin/com/apollographql/apollo/gradle/test/LanguageVersionTests.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ import org.gradle.testkit.runner.UnexpectedBuildFailure
55
import org.junit.Assert
66
import org.junit.Test
77
import util.TestUtils
8+
import util.disableIsolatedProjects
89
import java.io.File
910

1011
class LanguageVersionTests {
1112
@Test
1213
fun `compiling with 1_5 features with Kotlin 1_5 is working`() {
1314
withProject(kotlinLanguageVersion = "1.5", apolloLanguageVersion = "1.5") { dir ->
15+
dir.disableIsolatedProjects() // old KGP versions do not support isolated projects
1416
TestUtils.executeTaskAndAssertSuccess(":assemble", dir)
1517
}
1618
}

libraries/apollo-gradle-plugin/src/test-java11/kotlin/com/apollographql/apollo/gradle/test/LazyTests.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,21 @@ apollo {
3636

3737
val apolloConfiguration = """
3838
abstract class InstallGraphQLFilesTask: DefaultTask() {
39+
@get:InputDirectory
40+
abstract val inputDir: DirectoryProperty
41+
3942
@get:OutputDirectory
4043
abstract val outputDir: DirectoryProperty
44+
4145
@TaskAction
4246
fun taskAction() {
4347
println("installing graphql files")
44-
project.file( "src/main/graphql/com/example").copyRecursively(outputDir.asFile.get())
48+
inputDir.asFile.get().copyRecursively(outputDir.asFile.get())
4549
}
4650
}
4751
val installTask = tasks.register("installTask", InstallGraphQLFilesTask::class.java) {
4852
outputDir.set(project.file("build/toto"))
53+
inputDir.set(project.file("src/main/graphql/com/example"))
4954
}
5055
apollo {
5156
service("service") {

libraries/apollo-gradle-plugin/src/test-java11/kotlin/com/apollographql/apollo/gradle/test/MultiModulesTests.kt

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,35 @@ import org.gradle.testkit.runner.UnexpectedBuildFailure
66
import org.junit.Assert
77
import org.junit.Test
88
import util.TestUtils
9+
import util.disableIsolatedProjects
910
import util.replaceInText
1011
import java.io.File
1112

13+
14+
internal fun testProjectWithIsolatedProjectsWorkaround(name: String, block: (File) -> Unit) {
15+
/*
16+
* There seems to be an issue running KGP in project isolation mode
17+
* It's happening mostly for multi-module tests, I'm guessing because of a race or so.
18+
* See https://youtrack.jetbrains.com/issue/KT-74394
19+
*/
20+
TestUtils.withTestProject(name) { dir ->
21+
dir.disableIsolatedProjects()
22+
block(dir)
23+
}
24+
}
25+
1226
class MultiModulesTests {
1327
@Test
1428
fun `multi-modules project compiles`() {
15-
TestUtils.withTestProject("multi-modules") { dir ->
29+
testProjectWithIsolatedProjectsWorkaround("multi-modules") { dir ->
1630
val result = TestUtils.executeTask(":leaf:assemble", dir)
1731
Assert.assertEquals(TaskOutcome.SUCCESS, result.task(":leaf:assemble")!!.outcome)
1832
}
1933
}
2034

2135
@Test
2236
fun `multi-modules project can use transitive dependencies`() {
23-
TestUtils.withTestProject("multi-modules-transitive") { dir ->
37+
testProjectWithIsolatedProjectsWorkaround("multi-modules-transitive") { dir ->
2438
val result = TestUtils.executeTask(":leaf:assemble", dir)
2539
Assert.assertEquals(TaskOutcome.SUCCESS, result.task(":leaf:assemble")!!.outcome)
2640
Assert.assertEquals(TaskOutcome.SUCCESS, result.task(":leaf:generateServiceApolloSources")!!.outcome)
@@ -32,15 +46,15 @@ class MultiModulesTests {
3246
/**
3347
* A diamond shaped hierarchy does not include the schema multiple times
3448
*/
35-
TestUtils.withTestProject("multi-modules-diamond") { dir ->
49+
testProjectWithIsolatedProjectsWorkaround("multi-modules-diamond") { dir ->
3650
val result = TestUtils.executeTask(":leaf:jar", dir)
3751
Assert.assertEquals(TaskOutcome.SUCCESS, result.task(":leaf:generateServiceApolloSources")!!.outcome)
3852
}
3953
}
4054

4155
@Test
4256
fun `duplicate fragments are detected correctly`() {
43-
TestUtils.withTestProject("multi-modules-duplicates") { dir ->
57+
testProjectWithIsolatedProjectsWorkaround("multi-modules-duplicates") { dir ->
4458
// duplicate fragments in sibling modules are fine
4559
TestUtils.executeTaskAndAssertSuccess(":node1:impl:generateApolloSources", dir)
4660

@@ -63,7 +77,7 @@ class MultiModulesTests {
6377

6478
@Test
6579
fun `changing a fragment in module does not recompile siblings`() {
66-
TestUtils.withTestProject("multi-modules-duplicates") { dir ->
80+
testProjectWithIsolatedProjectsWorkaround("multi-modules-duplicates") { dir ->
6781
// Change the fragment so that it doesn't name clash anymore
6882
File(dir, "node1/impl/src/main/graphql/com/library/operations.graphql").replaceInText("CatFragment", "CatFragment1")
6983
// Execute jar a first time
@@ -89,7 +103,7 @@ class MultiModulesTests {
89103

90104
@Test
91105
fun `custom scalars are registered if added to customScalarMappings`() {
92-
TestUtils.withTestProject("multi-modules-custom-scalar") { dir ->
106+
testProjectWithIsolatedProjectsWorkaround("multi-modules-custom-scalar") { dir ->
93107
TestUtils.executeTaskAndAssertSuccess(":leaf:assemble", dir)
94108
// Date and GeoPoint is generated in the root module
95109
Assert.assertTrue(File(dir, "root/build/generated/source/apollo/service/com/library/type/Date.kt").exists())
@@ -101,7 +115,7 @@ class MultiModulesTests {
101115

102116
@Test
103117
fun `scalar mapping can only be registered in the schema module`() {
104-
TestUtils.withTestProject("multi-modules-custom-scalar-defined-in-leaf") { dir ->
118+
testProjectWithIsolatedProjectsWorkaround("multi-modules-custom-scalar-defined-in-leaf") { dir ->
105119
try {
106120
TestUtils.executeTaskAndAssertSuccess(":leaf:assemble", dir)
107121
Assert.fail("the build did not detect scalar mapping registered in leaf module")
@@ -113,15 +127,15 @@ class MultiModulesTests {
113127

114128
@Test
115129
fun `metadata is published`() {
116-
TestUtils.withTestProject("multi-modules-publishing-producer") { dir ->
130+
testProjectWithIsolatedProjectsWorkaround("multi-modules-publishing-producer") { dir ->
117131
val result = TestUtils.executeTask(
118132
"publishAllPublicationsToPluginTestRepository",
119133
dir
120134
)
121135
Assert.assertEquals(TaskOutcome.SUCCESS, result.task(":schema:publishAllPublicationsToPluginTestRepository")?.outcome)
122136
Assert.assertEquals(TaskOutcome.SUCCESS, result.task(":fragments:publishAllPublicationsToPluginTestRepository")?.outcome)
123137
}
124-
TestUtils.withTestProject("multi-modules-publishing-consumer") { dir ->
138+
testProjectWithIsolatedProjectsWorkaround("multi-modules-publishing-consumer") { dir ->
125139
TestUtils.executeTaskAndAssertSuccess(
126140
":build",
127141
dir
@@ -131,23 +145,23 @@ class MultiModulesTests {
131145

132146
@Test
133147
fun `schema targetLanguage propagates`() {
134-
TestUtils.withTestProject("multi-modules-badconfig") { dir ->
148+
testProjectWithIsolatedProjectsWorkaround("multi-modules-badconfig") { dir ->
135149
dir.resolve("root/build.gradle.kts").replacePlaceHolder("generateKotlinModels.set(false)")
136150
TestUtils.executeTaskAndAssertSuccess(":leaf:build", dir)
137151
}
138152
}
139153

140154
@Test
141155
fun `schema codegenModels propagates`() {
142-
TestUtils.withTestProject("multi-modules-badconfig") { dir ->
156+
testProjectWithIsolatedProjectsWorkaround("multi-modules-badconfig") { dir ->
143157
dir.resolve("root/build.gradle.kts").replacePlaceHolder("codegenModels.set(\"responseBased\")")
144158
TestUtils.executeTaskAndAssertSuccess(":leaf:build", dir)
145159
}
146160
}
147161

148162
@Test
149163
fun `bad targetLanguage is detected`() {
150-
TestUtils.withTestProject("multi-modules-badconfig") { dir ->
164+
testProjectWithIsolatedProjectsWorkaround("multi-modules-badconfig") { dir ->
151165
dir.resolve("root/build.gradle.kts").replacePlaceHolder("generateKotlinModels.set(true)")
152166
dir.resolve("leaf/build.gradle.kts").replacePlaceHolder("generateKotlinModels.set(false)")
153167

@@ -162,7 +176,7 @@ class MultiModulesTests {
162176

163177
@Test
164178
fun `bad codegenModels is detected`() {
165-
TestUtils.withTestProject("multi-modules-badconfig") { dir ->
179+
testProjectWithIsolatedProjectsWorkaround("multi-modules-badconfig") { dir ->
166180
dir.resolve("root/build.gradle.kts").replacePlaceHolder("codegenModels.set(\"responseBased\")")
167181
dir.resolve("leaf/build.gradle.kts").replacePlaceHolder("codegenModels.set(\"operationBased\")")
168182

libraries/apollo-gradle-plugin/src/test-java17/kotlin/test/AndroidProjectTests.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import org.gradle.testkit.runner.TaskOutcome
1010
import org.junit.Assert.assertEquals
1111
import org.junit.Assert.assertTrue
1212
import org.junit.Test
13+
import util.disableIsolatedProjects
1314
import java.io.File
1415

1516
class AndroidProjectTests {
@@ -93,6 +94,7 @@ class AndroidProjectTests {
9394
@Test
9495
fun `kotlin Android min version succeeds`() {
9596
withTestProject("kotlin-android-plugin-version") { dir ->
97+
dir.disableIsolatedProjects()
9698
val result = TestUtils.executeTask("build", dir)
9799

98100
Truth.assertThat(result.task(":build")!!.outcome).isEqualTo(TaskOutcome.SUCCESS)

0 commit comments

Comments
 (0)