Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve relocation in gradle plugin #4528

Merged
merged 4 commits into from
Nov 24, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build-logic/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@ dependencies {
// XXX: This is only needed for tests. We could have different build logic for different
// builds but this seems just overkill for now
runtimeOnly(golatac.lib("kotlin.allopen"))
runtimeOnly(golatac.lib("kotlinx.serialization.plugin"))
} else {
implementation(golatac.lib("kotlin.plugin.duringideasync"))
runtimeOnly(golatac.lib("ksp.duringideasync"))
runtimeOnly(golatac.lib("kotlin.allopen.duringideasync"))
runtimeOnly(golatac.lib("kotlinx.serialization.plugin.duringideasync"))
}

runtimeOnly(golatac.lib("sqldelight.plugin"))
Expand Down
6 changes: 5 additions & 1 deletion gradle/libraries.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ kotlin-plugin-duringideasync = "1.6.10"
kotlin-stdlib = "1.6.21"
kotlinx-coroutines = "1.6.4"
kotlinx-datetime = "0.4.0"
kotlinx-serialization-json = "1.4.1"
ksp = "1.7.21-1.0.8"
ksp-duringideasync = "1.6.10-1.0.2"
ktor = "2.0.2"
Expand Down Expand Up @@ -112,7 +113,10 @@ kotlinx-coroutines-rx3 = { group = "org.jetbrains.kotlinx", name = "kotlinx-coro
kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" }
kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinx-datetime" }
kotlinx-nodejs = { group = "org.jetbrains.kotlinx", name = "kotlinx-nodejs", version = "0.0.7" }
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version = "1.3.2" }
kotlinx-serialization-plugin = { group = "org.jetbrains.kotlin", name = "kotlin-serialization", version.ref = "kotlin-plugin" }
kotlinx-serialization-plugin-duringideasync = { group = "org.jetbrains.kotlin", name = "kotlin-serialization", version.ref = "kotlin-plugin-duringideasync" }
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinx-serialization-json" }
kotlinx-serialization-json-okio = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json-okio", version.ref = "kotlinx-serialization-json" }
kotlinx-binarycompatibilityvalidator = { group = "org.jetbrains.kotlinx", name = "binary-compatibility-validator", version = "0.10.1" }
ksp = { group = "com.google.devtools.ksp", name = "symbol-processing-gradle-plugin", version.ref = "ksp" }
ksp-duringideasync = { group = "com.google.devtools.ksp", name = "symbol-processing-gradle-plugin", version.ref = "ksp.duringideasync" }
Expand Down
3 changes: 2 additions & 1 deletion gradle/repositories.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pluginManagement {
includeModule("me.champeau.gradle", "japicmp-gradle-plugin")
includeModule("com.gradle.publish", "plugin-publish-plugin")
includeModule("com.github.ben-manes", "gradle-versions-plugin")
includeModule("org.jetbrains.kotlin.plugin.serialization", "org.jetbrains.kotlin.plugin.serialization.gradle.plugin")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I missed that one. Do we need this? The serialization plugin should be on maven central these days: https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/plugin/serialization/org.jetbrains.kotlin.plugin.serialization.gradle.plugin/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Version 1.6.10 (which we use during idea sync) is not on Maven central, but now I'm no longer sure this is needed because I removed it on my machine and it still works 😅

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you have configuration cache enabled 😅 . Ok I'll add it again in #4531 with a comment to remove it at some point

}
}
@Suppress("DEPRECATION")
Expand All @@ -25,4 +26,4 @@ pluginManagement {
}
}
}
}
}
471 changes: 315 additions & 156 deletions libraries/apollo-ast/api/apollo-ast.api

Large diffs are not rendered by default.

9 changes: 3 additions & 6 deletions libraries/apollo-ast/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
antlr
id("org.jetbrains.kotlin.jvm")
id("apollo.library")
id("com.google.devtools.ksp")
kotlin("plugin.serialization")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit. We're using the id("") notation everywhere else

Suggested change
kotlin("plugin.serialization")
id("org.jetbrains.kotlin.plugin.serialization")

}

apolloLibrary {
Expand All @@ -17,11 +17,8 @@ dependencies {
api(okio())
api(project(":libraries:apollo-annotations"))

implementation(golatac.lib("moshi"))
implementation(golatac.lib("moshix.sealed.runtime"))

ksp(golatac.lib("moshix.sealed.codegen"))
ksp(golatac.lib("moshix.ksp"))
implementation(golatac.lib("kotlinx.serialization.json"))
implementation(golatac.lib("kotlinx.serialization.json.okio"))

testImplementation(golatac.lib("kotlin.test.junit"))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,87 +1,94 @@
package com.apollographql.apollo3.ast.introspection

import com.squareup.moshi.JsonClass
import com.squareup.moshi.JsonReader
import com.squareup.moshi.Moshi
import dev.zacsweers.moshix.sealed.annotations.TypeLabel
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.okio.decodeFromBufferedSource
import kotlinx.serialization.json.okio.encodeToBufferedSink
import okio.Buffer
import okio.BufferedSource
import okio.ByteString.Companion.decodeHex
import okio.buffer
import okio.sink
import okio.source
import java.io.File

@JsonClass(generateAdapter = true)
@Serializable
private data class IntrospectionSchemaEnvelope(
val data: IntrospectionSchema?,
val __schema: IntrospectionSchema.Schema?,
)

@Serializable
data class IntrospectionSchema(
val __schema: Schema,
) {
@JsonClass(generateAdapter = true)
@Serializable
data class Schema(
val queryType: QueryType,
val mutationType: MutationType?,
val subscriptionType: SubscriptionType?,
val types: List<Type>,
) {
@JsonClass(generateAdapter = true)
@Serializable
data class QueryType(val name: String)

@JsonClass(generateAdapter = true)
@Serializable
data class MutationType(val name: String)

@JsonClass(generateAdapter = true)
@Serializable
data class SubscriptionType(val name: String)

@JsonClass(generateAdapter = true, generator = "sealed:kind")
@Serializable
sealed class Type {
abstract val name: String
abstract val description: String?

@TypeLabel("SCALAR")
@JsonClass(generateAdapter = true)
@SerialName("SCALAR")
@Serializable
data class Scalar(
override val name: String,
override val description: String?,
) : Type()

@TypeLabel("OBJECT")
@JsonClass(generateAdapter = true)
@SerialName("OBJECT")
@Serializable
data class Object(
override val name: String,
override val description: String?,
val fields: List<Field>?,
val interfaces: List<Interface>?,
) : Type()

@TypeLabel("INTERFACE")
@JsonClass(generateAdapter = true)
@SerialName("INTERFACE")
@Serializable
data class Interface(
override val name: String,
override val description: String?,
val kind: String,
martinbonnin marked this conversation as resolved.
Show resolved Hide resolved
val fields: List<Field>?,
val interfaces: List<TypeRef>?,
val possibleTypes: List<TypeRef>?,
) : Type()

@TypeLabel("UNION")
@JsonClass(generateAdapter = true)
@SerialName("UNION")
@Serializable
data class Union(
override val name: String,
override val description: String?,
val fields: List<Field>?,
val possibleTypes: List<TypeRef>?,
) : Type()

@TypeLabel("ENUM")
@JsonClass(generateAdapter = true)
@SerialName("ENUM")
@Serializable
data class Enum(
override val name: String,
override val description: String?,
val enumValues: List<Value>,
) : Type() {


@JsonClass(generateAdapter = true)
@Serializable
data class Value(
val name: String,
val description: String?,
Expand All @@ -90,17 +97,16 @@ data class IntrospectionSchema(
)
}

@TypeLabel("INPUT_OBJECT")
@JsonClass(generateAdapter = true)
@SerialName("INPUT_OBJECT")
@Serializable
data class InputObject(
override val name: String,
override val description: String?,
val inputFields: List<InputField>,
) : Type()
}


@JsonClass(generateAdapter = true)
@Serializable
data class InputField(
val name: String,
val description: String?,
Expand All @@ -110,7 +116,7 @@ data class IntrospectionSchema(
val defaultValue: String?,
)

@JsonClass(generateAdapter = true)
@Serializable
data class Field(
val name: String,
val description: String?,
Expand All @@ -120,7 +126,7 @@ data class IntrospectionSchema(
val args: List<Argument> = emptyList(),
) {

@JsonClass(generateAdapter = true)
@Serializable
data class Argument(
val name: String,
val description: String?,
Expand All @@ -134,7 +140,7 @@ data class IntrospectionSchema(
/**
* An introspection TypeRef
*/
@JsonClass(generateAdapter = true)
@Serializable
data class TypeRef(
val kind: Kind,
val name: String? = "",
Expand All @@ -147,51 +153,36 @@ data class IntrospectionSchema(
}
}

/**
*
*/
@OptIn(ExperimentalSerializationApi::class)
private val json: Json by lazy {
Json {
ignoreUnknownKeys = true
martinbonnin marked this conversation as resolved.
Show resolved Hide resolved
classDiscriminator = "kind"
explicitNulls = false
}
}

@OptIn(ExperimentalSerializationApi::class)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's ok to use this. If a future version changes the signatures, they will break at runtime.

Copy link
Contributor Author

@BoD BoD Nov 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we bundle and relocate the code, so we should be immune to changes? (OTOH I'm ok with avoiding using this)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We relocate in apollo-gradle-plugin but some users might use apollo-ast outside the Gradle context so I'd feel safer avoid this for the time being.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense 👍

fun BufferedSource.toIntrospectionSchema(origin: String = ""): IntrospectionSchema {
val bom = "EFBBBF".decodeHex()

if (rangeEquals(0, bom)) {
skip(bom.size.toLong())
}

return JsonReader.of(this).use {
try {
val schema = Moshi.Builder().build()
.adapter(IntrospectionSchema.Schema::class.java)
.fromJson(it.locateSchemaRootNode())!!
IntrospectionSchema(__schema = schema)
} catch (e: Exception) {
throw RuntimeException("Cannot decode introspection $origin", e)
}
return try {
val introspectionSchemaEnvelope = json.decodeFromBufferedSource<IntrospectionSchemaEnvelope>(this)
introspectionSchemaEnvelope.data ?: introspectionSchemaEnvelope.__schema?.let { IntrospectionSchema(it) }
?: throw IllegalArgumentException("Invalid introspection schema: $origin")
} catch (e: Exception) {
throw RuntimeException("Cannot decode introspection $origin", e)
}
}

fun File.toIntrospectionSchema() = inputStream().source().buffer().toIntrospectionSchema("from `$this`")

fun String.toIntrospectionSchema() = Buffer().writeUtf8(this).toIntrospectionSchema()

private fun JsonReader.locateSchemaRootNode(): JsonReader {
beginObject()

var schemaJsonReader: JsonReader? = null
try {
while (schemaJsonReader == null && hasNext()) {
when (nextName()) {
"data" -> beginObject()
"__schema" -> schemaJsonReader = peekJson()
else -> skipValue()
}
}
} catch (e: Exception) {
throw IllegalArgumentException("Failed to locate schema root node `__schema`", e)
}

return schemaJsonReader ?: throw IllegalArgumentException("Failed to locate schema root node `__schema`")
}

fun IntrospectionSchema.normalize(): IntrospectionSchema {
return copy(
__schema = __schema.normalize()
Expand All @@ -204,3 +195,13 @@ fun IntrospectionSchema.Schema.normalize(): IntrospectionSchema.Schema {
)
}

fun IntrospectionSchema.toJson(): String {
return json.encodeToString(this)
}

@OptIn(ExperimentalSerializationApi::class)
fun IntrospectionSchema.toJson(file: File) {
file.outputStream().sink().buffer().use {
return json.encodeToBufferedSink(this, it)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ private class IntrospectionSchemaBuilder(private val schema: Schema) {
name = name,
description = description,
fields = fields.map { it.toSchemaField() },
interfaces = implementsInterfaces.map { IntrospectionSchema.Schema.Type.Interface(kind = "INTERFACE", name = it, description = null, fields = null, possibleTypes = null, interfaces = null) }.ifEmpty { null },
interfaces = implementsInterfaces.map { IntrospectionSchema.Schema.Type.Interface(name = it, description = null, fields = null, possibleTypes = null, interfaces = null) }.ifEmpty { null },
martinbonnin marked this conversation as resolved.
Show resolved Hide resolved
)
}

Expand Down Expand Up @@ -107,7 +107,6 @@ private class IntrospectionSchemaBuilder(private val schema: Schema) {

private fun GQLInterfaceTypeDefinition.toSchemaType(): IntrospectionSchema.Schema.Type.Interface {
return IntrospectionSchema.Schema.Type.Interface(
kind = "INTERFACE",
name = name,
description = description,
fields = fields.map { it.toSchemaField() },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@ package com.apollographql.apollo3.graphql.ast.test
import com.apollographql.apollo3.ast.SDLWriter
import com.apollographql.apollo3.ast.Schema
import com.apollographql.apollo3.ast.internal.buffer
import com.apollographql.apollo3.ast.introspection.IntrospectionSchema
import com.apollographql.apollo3.ast.introspection.toGQLDocument
import com.apollographql.apollo3.ast.introspection.toIntrospectionSchema
import com.apollographql.apollo3.ast.toSchema
import com.apollographql.apollo3.ast.toUtf8
import com.squareup.moshi.Moshi
import okio.Buffer
import org.junit.Test
import kotlin.test.assertEquals
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import com.apollographql.apollo3.ast.introspection.toIntrospectionSchema
import com.apollographql.apollo3.ast.introspection.toSchemaGQLDocument
import com.apollographql.apollo3.ast.toSchema
import com.apollographql.apollo3.ast.validateAsSchema
import com.squareup.moshi.Moshi
import okio.Buffer
import org.junit.Test
import java.io.File
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package com.apollographql.apollo3.compiler

import com.apollographql.apollo3.ast.toSchema
import com.apollographql.apollo3.ast.toUtf8
import com.apollographql.apollo3.ast.introspection.toGQLDocument
import com.apollographql.apollo3.ast.introspection.toIntrospectionSchema
import com.apollographql.apollo3.ast.introspection.toJson
import com.apollographql.apollo3.ast.introspection.toSchema
import com.apollographql.apollo3.ast.toSchema
import com.apollographql.apollo3.ast.toUtf8
import org.junit.Assert
import org.junit.Test
import java.io.File
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.apollographql.apollo3.gradle.internal

import com.apollographql.apollo3.ast.toUtf8
import com.apollographql.apollo3.ast.introspection.toGQLDocument
import com.apollographql.apollo3.ast.introspection.toIntrospectionSchema
import com.apollographql.apollo3.ast.introspection.toJson
import com.apollographql.apollo3.ast.introspection.toSchema
import com.apollographql.apollo3.compiler.toJson
import com.apollographql.apollo3.ast.toUtf8
import org.gradle.api.DefaultTask
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
Expand Down
Loading