Skip to content

Commit 3befacc

Browse files
BoDmartinbonnin
andauthored
Update Apollo compiler plugin to 4.3 API (#169)
* Update Apollo compiler plugin to 4.3 API * Add a check for Apollo compiler v4.3, and revert to plugin provider * Add a comment about using ApolloCacheCompilerPluginProvider * Make ApolloCacheCompilerPlugin again * Update normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/AddKeyFieldsDocumentTransform.kt Co-authored-by: Martin Bonnin <[email protected]> * use the preview * Add a test for Apollo 4.2 * Use apollo kotlin 4.3.0 * Keep mavenLocal() * Add 4.3.0 requirement --------- Co-authored-by: Martin Bonnin <[email protected]>
1 parent 1bc04a6 commit 3befacc

File tree

24 files changed

+145
-59
lines changed

24 files changed

+145
-59
lines changed

Writerside/topics/welcome.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ are added here instead. In the future, the main repository Normalized Cache will
2626
2727
{style="warning"}
2828

29+
The Normalized Cache requires Apollo Kotlin v4.3.0 or later.
30+
2931
1. Add the dependencies to your project
3032

3133
```kotlin

gradle/libs.versions.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[versions]
22
kotlin-plugin = "2.1.21"
33
android-plugin = "8.7.0"
4-
apollo = "4.2.0"
4+
apollo = "4.3.0"
55
okio = "3.9.0"
66
atomicfu = "0.23.1" # Must be the same version as the one used by apollo-testing-support or native compilation will fail
77
sqldelight = "2.1.0"
@@ -49,4 +49,5 @@ sqldelight-plugin = { module = "app.cash.sqldelight:gradle-plugin", version.ref
4949

5050
[plugins]
5151
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin-plugin" }
52+
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin-plugin" }
5253
apollo = { id = "com.apollographql.apollo", version.ref = "apollo" }

normalized-cache-apollo-compiler-plugin/api/normalized-cache-apollo-compiler-plugin.api

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
public final class com/apollographql/cache/apollocompilerplugin/ApolloCacheCompilerPlugin : com/apollographql/apollo/compiler/ApolloCompilerPlugin {
2+
public fun <init> ()V
3+
public fun beforeCompilationStep (Lcom/apollographql/apollo/compiler/ApolloCompilerPluginEnvironment;Lcom/apollographql/apollo/compiler/ApolloCompilerRegistry;)V
4+
}
5+
16
public final class com/apollographql/cache/apollocompilerplugin/ApolloCacheCompilerPluginProvider : com/apollographql/apollo/compiler/ApolloCompilerPluginProvider {
27
public fun <init> ()V
38
public fun create (Lcom/apollographql/apollo/compiler/ApolloCompilerPluginEnvironment;)Lcom/apollographql/apollo/compiler/ApolloCompilerPlugin;

normalized-cache-apollo-compiler-plugin/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Librarian.module(project)
99
dependencies {
1010
compileOnly(libs.apollo.compiler)
1111
testImplementation(libs.apollo.compiler)
12+
testImplementation(gradleTestKit())
1213
implementation(libs.apollo.ast)
1314
implementation(libs.kotlin.poet)
1415
testImplementation(libs.kotlin.test)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
@file:OptIn(ApolloExperimental::class)
2+
3+
package com.apollographql.cache.apollocompilerplugin
4+
5+
import com.apollographql.apollo.annotations.ApolloExperimental
6+
import com.apollographql.apollo.ast.ForeignSchema
7+
import com.apollographql.apollo.compiler.ApolloCompilerPlugin
8+
import com.apollographql.apollo.compiler.ApolloCompilerPluginEnvironment
9+
import com.apollographql.apollo.compiler.ApolloCompilerRegistry
10+
import com.apollographql.cache.apollocompilerplugin.internal.AddKeyFieldsExecutableDocumentTransform
11+
import com.apollographql.cache.apollocompilerplugin.internal.CacheSchemaCodeGenerator
12+
import com.apollographql.cache.apollocompilerplugin.internal.cacheGQLDefinitions
13+
14+
class ApolloCacheCompilerPlugin : ApolloCompilerPlugin {
15+
override fun beforeCompilationStep(
16+
environment: ApolloCompilerPluginEnvironment,
17+
registry: ApolloCompilerRegistry,
18+
) {
19+
registry.registerForeignSchemas(listOf(ForeignSchema("cache", "v0.1", cacheGQLDefinitions)))
20+
registry.registerExecutableDocumentTransform("com.apollographql.cache.addKeyFields", transform = AddKeyFieldsExecutableDocumentTransform)
21+
registry.registerSchemaCodeGenerator(CacheSchemaCodeGenerator(environment))
22+
}
23+
}

normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/ApolloCacheCompilerPluginProvider.kt

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,25 @@
33
package com.apollographql.cache.apollocompilerplugin
44

55
import com.apollographql.apollo.annotations.ApolloExperimental
6+
import com.apollographql.apollo.compiler.APOLLO_VERSION
67
import com.apollographql.apollo.compiler.ApolloCompilerPlugin
78
import com.apollographql.apollo.compiler.ApolloCompilerPluginEnvironment
8-
import com.apollographql.apollo.compiler.ApolloCompilerPluginProvider
9-
import com.apollographql.cache.apollocompilerplugin.internal.ApolloCacheCompilerPlugin
109

11-
class ApolloCacheCompilerPluginProvider : ApolloCompilerPluginProvider {
10+
// ApolloCacheCompilerPluginProvider is deprecated in favor of ApolloCompilerPlugin, but we want to display a nice error message
11+
// in projects using AK < 4.3.0
12+
class ApolloCacheCompilerPluginProvider : @Suppress("DEPRECATION") com.apollographql.apollo.compiler.ApolloCompilerPluginProvider {
1213
override fun create(environment: ApolloCompilerPluginEnvironment): ApolloCompilerPlugin {
13-
return ApolloCacheCompilerPlugin(environment)
14+
checkCompilerVersion()
15+
return ApolloCacheCompilerPlugin()
16+
}
17+
}
18+
19+
private fun checkCompilerVersion() {
20+
val matchResult = Regex("""^(\d+)\.(\d+).*$""").matchEntire(APOLLO_VERSION)
21+
val versionMajor = matchResult?.groupValues?.get(1)?.toIntOrNull()
22+
val versionMinor = matchResult?.groupValues?.get(2)?.toIntOrNull()
23+
if (versionMinor == null || versionMajor == null) error("Invalid Apollo Kotlin compiler version: $APOLLO_VERSION")
24+
if (versionMajor < 4 || (versionMajor == 4 && versionMinor < 3)) {
25+
error("The Apollo Cache compiler plugin requires Apollo Kotlin version 4.3.0 or higher (found $APOLLO_VERSION)")
1426
}
1527
}

normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/AddKeyFieldsDocumentTransform.kt

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package com.apollographql.cache.apollocompilerplugin.internal
44

55
import com.apollographql.apollo.annotations.ApolloExperimental
66
import com.apollographql.apollo.annotations.ApolloInternal
7+
import com.apollographql.apollo.ast.GQLDocument
78
import com.apollographql.apollo.ast.GQLField
89
import com.apollographql.apollo.ast.GQLFragmentDefinition
910
import com.apollographql.apollo.ast.GQLFragmentSpread
@@ -19,18 +20,26 @@ import com.apollographql.apollo.ast.definitionFromScope
1920
import com.apollographql.apollo.ast.rawType
2021
import com.apollographql.apollo.ast.responseName
2122
import com.apollographql.apollo.ast.rootTypeDefinition
22-
import com.apollographql.apollo.compiler.DocumentTransform
23+
import com.apollographql.apollo.compiler.ExecutableDocumentTransform
2324

2425
/**
25-
* Add key fields and `__typename` to selections on types that declare them via `@typePolicy`.
26+
* Add `__typename` to every composite selection set and key fields to selection sets on types where `@typePolicy` declare them.
2627
*/
27-
internal class AddKeyFieldsDocumentTransform : DocumentTransform {
28-
override fun transform(schema: Schema, fragment: GQLFragmentDefinition): GQLFragmentDefinition {
29-
return fragment.withRequiredFields(schema)
30-
}
31-
32-
override fun transform(schema: Schema, operation: GQLOperationDefinition): GQLOperationDefinition {
33-
return operation.withRequiredFields(schema)
28+
internal object AddKeyFieldsExecutableDocumentTransform : ExecutableDocumentTransform {
29+
override fun transform(
30+
schema: Schema,
31+
document: GQLDocument,
32+
extraFragmentDefinitions: List<GQLFragmentDefinition>,
33+
): GQLDocument {
34+
return document.copy(
35+
definitions = document.definitions.map {
36+
when (it) {
37+
is GQLFragmentDefinition -> it.withRequiredFields(schema)
38+
is GQLOperationDefinition -> it.withRequiredFields(schema)
39+
else -> it
40+
}
41+
}
42+
)
3443
}
3544

3645
private fun GQLOperationDefinition.withRequiredFields(schema: Schema): GQLOperationDefinition {
@@ -152,7 +161,6 @@ internal class AddKeyFieldsDocumentTransform : DocumentTransform {
152161
return copy(selections = newSelectionSet)
153162
}
154163

155-
@OptIn(ApolloExperimental::class)
156164
private fun buildField(name: String): GQLField {
157165
return GQLField(
158166
name = name,

normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/ApolloCacheCompilerPlugin.kt

Lines changed: 0 additions & 26 deletions
This file was deleted.
Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
package com.apollographql.cache.apollocompilerplugin.internal
44

55
import com.apollographql.apollo.annotations.ApolloExperimental
6+
import com.apollographql.apollo.ast.GQLDocument
67
import com.apollographql.apollo.ast.Schema
8+
import com.apollographql.apollo.ast.toSchema
79
import com.apollographql.apollo.compiler.ApolloCompilerPluginEnvironment
8-
import com.apollographql.apollo.compiler.SchemaListener
10+
import com.apollographql.apollo.compiler.SchemaCodeGenerator
911
import com.apollographql.cache.apollocompilerplugin.VERSION
1012
import com.squareup.kotlinpoet.ClassName
1113
import com.squareup.kotlinpoet.CodeBlock
@@ -29,17 +31,18 @@ private object Symbols {
2931
val TypePolicy = ClassName("com.apollographql.cache.normalized.api", "TypePolicy")
3032
}
3133

32-
internal class CacheSchemaListener(
34+
internal class CacheSchemaCodeGenerator(
3335
private val environment: ApolloCompilerPluginEnvironment,
34-
) : SchemaListener {
35-
override fun onSchema(schema: Schema, outputDirectory: File) {
36+
) : SchemaCodeGenerator {
37+
override fun generate(schema: GQLDocument, outputDirectory: File) {
38+
val validSchema = schema.toSchema()
3639
val packageName = (environment.arguments["packageName"] as? String
3740
?: throw IllegalArgumentException("packageName argument is required and must be a String")) + ".cache"
3841
val file = FileSpec.builder(packageName, "Cache")
3942
.addType(
4043
TypeSpec.objectBuilder("Cache")
41-
.addProperty(maxAgeProperty(schema))
42-
.addProperty(typePoliciesProperty(schema))
44+
.addProperty(maxAgeProperty(validSchema))
45+
.addProperty(typePoliciesProperty(validSchema))
4346
.build()
4447
)
4548
.addFileComment(
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
package com.apollographql.cache.apollocompilerplugin.internal
44

55
import com.apollographql.apollo.annotations.ApolloExperimental
6-
import com.apollographql.apollo.ast.GQLOperationDefinition
76
import com.apollographql.apollo.ast.SourceAwareException
87
import com.apollographql.apollo.ast.internal.SchemaValidationOptions
98
import com.apollographql.apollo.ast.parseAsGQLDocument
@@ -14,7 +13,7 @@ import kotlin.test.Test
1413
import kotlin.test.assertEquals
1514
import kotlin.test.assertFailsWith
1615

17-
class AddKeyFieldsDocumentTransformTest {
16+
class AddKeyFieldsExecutableDocumentTransformTest {
1817
@Test
1918
fun keyFieldsOnObject() {
2019
// language=GraphQL
@@ -326,8 +325,8 @@ private fun checkTransform(schemaText: String, operationText: String, expected:
326325
foreignSchemas = emptyList(),
327326
)
328327
).getOrThrow()
329-
val operation = operationText.toGQLDocument().definitions.first() as GQLOperationDefinition
330-
assertEquals(expected, AddKeyFieldsDocumentTransform().transform(schema, operation).toUtf8().trim())
328+
val document = operationText.toGQLDocument()
329+
assertEquals(expected, AddKeyFieldsExecutableDocumentTransform.transform(schema, document, emptyList()).toUtf8().trim())
331330
}
332331

333332
private fun checkTransformThrows(schemaText: String, operationText: String, expectedMessage: String) {
@@ -339,9 +338,9 @@ private fun checkTransformThrows(schemaText: String, operationText: String, expe
339338
foreignSchemas = emptyList(),
340339
)
341340
).getOrThrow()
342-
val operation = operationText.toGQLDocument().definitions.first() as GQLOperationDefinition
341+
val document = operationText.toGQLDocument()
343342
assertFailsWith<SourceAwareException> {
344-
AddKeyFieldsDocumentTransform().transform(schema, operation)
343+
AddKeyFieldsExecutableDocumentTransform.transform(schema, document, emptyList())
345344
}.apply {
346345
assertEquals(expectedMessage, message)
347346
}

0 commit comments

Comments
 (0)