Skip to content

Commit

Permalink
allow to upload PQL from Gradle
Browse files Browse the repository at this point in the history
  • Loading branch information
martinbonnin committed Aug 17, 2023
1 parent 8af7b9b commit fea4170
Show file tree
Hide file tree
Showing 17 changed files with 1,253 additions and 2,193 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ internal class PublishSchemaCommand: CliktCommand() {

override fun run() {
SchemaUploader.uploadSchema(
key = key,
apolloKey = key,
graph = graph,
variant = graphVariant,
sdl = File(schema).readText(),
Expand Down
1 change: 1 addition & 0 deletions libraries/apollo-compiler/api/apollo-compiler.api
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,7 @@ public final class com/apollographql/apollo3/compiler/pqm/PersistedQueryManifest
}

public final class com/apollographql/apollo3/compiler/pqm/PersistedQueryManifestKt {
public static final fun toPersistedQueryManifest (Ljava/io/File;)Lcom/apollographql/apollo3/compiler/pqm/PersistedQueryManifest;
public static final fun toPersistedQueryManifest (Ljava/util/Map;)Lcom/apollographql/apollo3/compiler/pqm/PersistedQueryManifest;
public static final fun writeTo (Lcom/apollographql/apollo3/compiler/pqm/PersistedQueryManifest;Ljava/io/File;)V
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,15 @@ private fun List<GQLSelection>.addRequiredFields(
val requiresTypename = when(addTypename) {
"ifPolymorphic" -> isRoot && isPolymorphic(schema, fragments, parentType)
"ifFragments" -> {
println("Using addTypename=\"ifFragments\" is deprecated. Use \"always\" if you're using the cache or \"ifPolymorphic\" else.")
println("""Apollo: addTypename=\"ifFragments\" (default) is deprecated as it could lead to cache misses. Use \"always\" if you're using the cache or \"ifPolymorphic\" else:
|apollo {
| service("service") {
| addTypename.set("$ADD_TYPENAME_ALWAYS")
| // or
| addTypename.set("$ADD_TYPENAME_IF_POLYMORPHIC")
| }
|}
""".trimMargin())
selectionSet.any { it is GQLFragmentSpread || it is GQLInlineFragment }
}
"ifAbstract" -> isRoot && schema.typeDefinition(parentType).isAbstract()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.apollographql.apollo3.compiler.pqm

import com.apollographql.apollo3.compiler.operationoutput.OperationDescriptor
import com.apollographql.apollo3.compiler.operationoutput.OperationOutput
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
Expand Down Expand Up @@ -34,6 +33,13 @@ fun PersistedQueryManifest.writeTo(file: File) {
}
}

@OptIn(ExperimentalSerializationApi::class)
fun File.toPersistedQueryManifest(): PersistedQueryManifest {
return source().buffer().use {
Json.decodeFromBufferedSource(it)
}
}

fun OperationOutput.toPersistedQueryManifest(): PersistedQueryManifest {
return PersistedQueryManifest(
format = "apollo-persisted-query-manifest",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public abstract interface class com/apollographql/apollo3/gradle/api/RegisterOpe
public abstract fun getGraph ()Lorg/gradle/api/provider/Property;
public abstract fun getGraphVariant ()Lorg/gradle/api/provider/Property;
public abstract fun getKey ()Lorg/gradle/api/provider/Property;
public abstract fun getListId ()Lorg/gradle/api/provider/Property;
}

public abstract interface class com/apollographql/apollo3/gradle/api/Registry {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package com.apollographql.apollo3.gradle.api
import org.gradle.api.provider.Property

interface RegisterOperationsConfig {
val listId: Property<String>

val key: Property<String>

val graph: Property<String>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ abstract class ApolloPushSchemaTask : DefaultTask() {
// Files are relative to the root project. It is not possible in a consistent way to have them relative to the current
// working directory where the gradle command was started
SchemaUploader.uploadSchema(
key = key,
apolloKey = key,
graph = graph,
variant = graphVariant ?: "current",
sdl = File(projectRootDir).resolve(schema).readText(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,97 @@
package com.apollographql.apollo3.gradle.internal

import com.apollographql.apollo3.compiler.MANIFEST_OPERATION_OUTPUT
import com.apollographql.apollo3.compiler.MANIFEST_PERSISTED_QUERY
import com.apollographql.apollo3.compiler.operationoutput.toOperationOutput
import com.apollographql.apollo3.compiler.pqm.toPersistedQueryManifest
import com.apollographql.apollo3.tooling.CannotModifyOperationBody
import com.apollographql.apollo3.tooling.GraphNotFound
import com.apollographql.apollo3.tooling.PermissionError
import com.apollographql.apollo3.tooling.PersistedQuery
import com.apollographql.apollo3.tooling.PublishOperationsSuccess
import com.apollographql.apollo3.tooling.RegisterOperations
import okio.buffer
import okio.source
import com.apollographql.apollo3.tooling.publishOperations
import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction

abstract class ApolloRegisterOperationsTask: DefaultTask() {
@get:InputFile
abstract val operationOutput: RegularFileProperty

@get:Input
@get:Optional
abstract val listId: Property<String>

@get:Input
abstract val key: Property<String>

@get:Input
abstract val graph: Property<String>

@get:Input
abstract val operationManifestFormat: Property<String>

@get:Input
@get:Optional
abstract val graphVariant: Property<String>

@TaskAction
fun taskAction() {
RegisterOperations.registerOperations(
key = key.get() ?: error("key is required to register operations"),
graphID = graph.get() ?: error("graphID is required to register operations"),
graphVariant = graphVariant.get() ?: error("graphVariant is required to register operations"),
operationOutput = operationOutput.get().asFile.toOperationOutput()
)
if (listId.isPresent) {
check(operationManifestFormat.get() == MANIFEST_PERSISTED_QUERY) {
"""Apollo: registering operations to a persisted query list requires operationManifestFormat = "$MANIFEST_PERSISTED_QUERY":
|apollo {
| service("service") {
| operationManifestFormat.set("$MANIFEST_PERSISTED_QUERY")
| }
|}
""".trimMargin()
}
val result = publishOperations(
listId = listId.get(),
persistedQueries = operationOutput.get().asFile.toPersistedQueryManifest().operations.map {
PersistedQuery(
name = it.name,
id = it.id,
body = it.body,
operationType = it.type
)
},
apolloKey = key.get(),
graph = graph.get()
)

when(result) {
is PublishOperationsSuccess -> {
println("Apollo: persisted query list uploaded successfully")
}

is CannotModifyOperationBody -> error("Cannot upload persisted query list: cannot modify operation body ('${result.message}')")
GraphNotFound -> error("Cannot upload persisted query list: graph '$graph' not found")
is PermissionError -> error("Cannot upload persisted query list: permission error ('${result.message}')")
}
} else {
println("Apollo: registering operations without a listId is deprecated")
check(operationManifestFormat.get() == MANIFEST_OPERATION_OUTPUT) {
"""Apollo: registering legacy operations requires operationManifestFormat = "$MANIFEST_OPERATION_OUTPUT":
|apollo {
| service("service") {
| operationManifestFormat.set("$MANIFEST_OPERATION_OUTPUT")
| }
|}
""".trimMargin()
}
RegisterOperations.registerOperations(
key = key.get() ?: error("key is required to register operations"),
graphID = graph.get() ?: error("graphID is required to register operations"),
graphVariant = graphVariant.get() ?: error("graphVariant is required to register operations"),
operationOutput = operationOutput.get().asFile.toOperationOutput()
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,8 @@ abstract class DefaultApolloExtension(
project.tasks.register(ModelNames.registerApolloOperations(service), ApolloRegisterOperationsTask::class.java) { task ->
task.group = TASK_GROUP

task.operationManifestFormat.set(service.operationManifestFormat())
task.listId.set(registerOperationsConfig.listId)
task.graph.set(registerOperationsConfig.graph)
task.graphVariant.set(registerOperationsConfig.graphVariant)
task.key.set(registerOperationsConfig.key)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,6 @@ abstract class DefaultService @Inject constructor(val project: Project, override
"Apollo: registerOperations {} cannot be configured outside of a service {} block"
}

val existing = operationManifestFormat.orNull
check(existing == null || existing == MANIFEST_OPERATION_OUTPUT) {
"Apollo: registerOperation {} requires $MANIFEST_OPERATION_OUTPUT (found $existing)"
}
operationManifestFormat.set(MANIFEST_OPERATION_OUTPUT)
operationManifestFormat.finalizeValue()

val registerOperationsConfig = objects.newInstance(DefaultRegisterOperationsConfig::class.java)

if (this.registerOperationsConfig != null) {
Expand Down
39 changes: 39 additions & 0 deletions libraries/apollo-tooling/api/apollo-tooling.api
Original file line number Diff line number Diff line change
@@ -1,3 +1,42 @@
public final class com/apollographql/apollo3/tooling/CannotModifyOperationBody : com/apollographql/apollo3/tooling/PublishOperationsResult {
public fun <init> (Ljava/lang/String;)V
public final fun getMessage ()Ljava/lang/String;
}

public final class com/apollographql/apollo3/tooling/GraphNotFound : com/apollographql/apollo3/tooling/PublishOperationsResult {
public static final field INSTANCE Lcom/apollographql/apollo3/tooling/GraphNotFound;
}

public final class com/apollographql/apollo3/tooling/PermissionError : com/apollographql/apollo3/tooling/PublishOperationsResult {
public fun <init> (Ljava/lang/String;)V
public final fun getMessage ()Ljava/lang/String;
}

public final class com/apollographql/apollo3/tooling/PersistedQueriesUploaderKt {
}

public final class com/apollographql/apollo3/tooling/PersistedQuery {
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
public final fun getBody ()Ljava/lang/String;
public final fun getId ()Ljava/lang/String;
public final fun getName ()Ljava/lang/String;
public final fun getOperationType ()Ljava/lang/String;
}

public abstract interface class com/apollographql/apollo3/tooling/PublishOperationsResult {
}

public final class com/apollographql/apollo3/tooling/PublishOperationsSuccess : com/apollographql/apollo3/tooling/PublishOperationsResult {
public fun <init> (IIIIILjava/lang/String;I)V
public final fun getAdded ()I
public final fun getIdentical ()I
public final fun getName ()Ljava/lang/String;
public final fun getRemoved ()I
public final fun getRevision ()I
public final fun getUnaffected ()I
public final fun getUpdated ()I
}

public final class com/apollographql/apollo3/tooling/SchemaDownloader$SpecVersion : java/lang/Enum {
public static final field Draft Lcom/apollographql/apollo3/tooling/SchemaDownloader$SpecVersion;
public static final field June_2018 Lcom/apollographql/apollo3/tooling/SchemaDownloader$SpecVersion;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,37 @@ mutation PublishSubgraphSchema($graphID: ID!, $variant: String!, $subgraph: Stri
}
}
}

mutation PublishOperationsMutation($graphId: ID!, $listId: ID!, $operationManifest: [PersistedQueryInput!]) {
graph(id: $graphId) {
persistedQueryList(id: $listId) {
publishOperations(operations: $operationManifest) {
__typename
... on PermissionError {
message
}
... on CannotModifyOperationBodyError {
message
}
... on PublishOperationsResult {
build {
revision
publish {
operationCounts {
added
identical
updated
unaffected
removed
}
}
list {
name
}
}
unchanged
}
}
}
}
}
Loading

0 comments on commit fea4170

Please sign in to comment.