11/*
2- * Copyright 2021 Expedia, Inc
2+ * Copyright 2023 Expedia, Inc
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
@@ -20,26 +20,33 @@ import com.expediagroup.graphql.plugin.gradle.tasks.DOWNLOAD_SDL_TASK_NAME
2020import com.expediagroup.graphql.plugin.gradle.tasks.GENERATE_CLIENT_TASK_NAME
2121import com.expediagroup.graphql.plugin.gradle.tasks.GENERATE_SDL_TASK_NAME
2222import com.expediagroup.graphql.plugin.gradle.tasks.GENERATE_TEST_CLIENT_TASK_NAME
23+ import com.expediagroup.graphql.plugin.gradle.tasks.GRAALVM_METADATA_TASK_NAME
2324import com.expediagroup.graphql.plugin.gradle.tasks.GraphQLDownloadSDLTask
2425import com.expediagroup.graphql.plugin.gradle.tasks.GraphQLGenerateClientTask
2526import com.expediagroup.graphql.plugin.gradle.tasks.GraphQLGenerateSDLTask
2627import com.expediagroup.graphql.plugin.gradle.tasks.GraphQLGenerateTestClientTask
28+ import com.expediagroup.graphql.plugin.gradle.tasks.GraphQLGraalVmMetadataTask
2729import com.expediagroup.graphql.plugin.gradle.tasks.GraphQLIntrospectSchemaTask
2830import com.expediagroup.graphql.plugin.gradle.tasks.INTROSPECT_SCHEMA_TASK_NAME
31+ import org.graalvm.buildtools.gradle.NativeImagePlugin.NATIVE_COMPILE_TASK_NAME
2932import org.gradle.api.Plugin
3033import org.gradle.api.Project
3134import org.gradle.api.file.DirectoryProperty
35+ import org.gradle.api.plugins.ApplicationPlugin
36+ import org.gradle.api.plugins.JavaApplication
3237import org.gradle.api.tasks.SourceSetContainer
38+ import org.gradle.jvm.tasks.Jar
3339import java.io.File
3440
3541private const val PLUGIN_EXTENSION_NAME = " graphql"
3642private const val GENERATE_CLIENT_CONFIGURATION = " graphqlClient"
3743private const val GENERATE_SDL_CONFIGURATION = " graphqlSDL"
44+ private const val GRAALVM_METADATA_CONFIGURATION = " graphqlGraalVM"
45+ private const val GRAALVM_PLUGIN_NAME = " org.graalvm.buildtools.native"
3846
3947/* *
4048 * GraphQL Kotlin Gradle Plugin
4149 */
42- @Suppress(" UnstableApiUsage" )
4350class GraphQLGradlePlugin : Plugin <Project > {
4451
4552 override fun apply (project : Project ) {
@@ -49,7 +56,7 @@ class GraphQLGradlePlugin : Plugin<Project> {
4956 val extension = project.extensions.create(PLUGIN_EXTENSION_NAME , GraphQLPluginExtension ::class .java)
5057 project.afterEvaluate {
5158 processExtensionConfiguration(project, extension)
52- configureTaskClasspaths (project)
59+ configureTasks (project)
5360 }
5461 }
5562
@@ -69,6 +76,14 @@ class GraphQLGradlePlugin : Plugin<Project> {
6976
7077 configuration.dependencies.add(project.dependencies.create(" com.expediagroup:graphql-kotlin-sdl-generator:$DEFAULT_PLUGIN_VERSION " ))
7178 }
79+
80+ project.configurations.create(GRAALVM_METADATA_CONFIGURATION ) { configuration ->
81+ configuration.isVisible = true
82+ configuration.isTransitive = true
83+ configuration.description = " Configuration for generating GraalVM reflect metadata"
84+
85+ configuration.dependencies.add(project.dependencies.create(" com.expediagroup:graphql-kotlin-graalvm-metadata-generator:$DEFAULT_PLUGIN_VERSION " ))
86+ }
7287 }
7388
7489 private fun registerTasks (project : Project ) {
@@ -77,6 +92,15 @@ class GraphQLGradlePlugin : Plugin<Project> {
7792 project.tasks.register(GENERATE_TEST_CLIENT_TASK_NAME , GraphQLGenerateTestClientTask ::class .java)
7893 project.tasks.register(GENERATE_SDL_TASK_NAME , GraphQLGenerateSDLTask ::class .java)
7994 project.tasks.register(INTROSPECT_SCHEMA_TASK_NAME , GraphQLIntrospectSchemaTask ::class .java)
95+ project.tasks.register(GRAALVM_METADATA_TASK_NAME , GraphQLGraalVmMetadataTask ::class .java)
96+
97+ // create new source for GraalVM metadata task
98+ if (project.plugins.hasPlugin(GRAALVM_PLUGIN_NAME )) {
99+ val graphQLGraalVmSource = project.extensions.getByType(SourceSetContainer ::class .java).create(" graphqlGraalVm" )
100+ project.tasks.withType(Jar ::class .java).configureEach { jarTask ->
101+ jarTask.from(graphQLGraalVmSource.runtimeClasspath)
102+ }
103+ }
80104 }
81105
82106 private fun processExtensionConfiguration (project : Project , extension : GraphQLPluginExtension ) {
@@ -131,9 +155,22 @@ class GraphQLGradlePlugin : Plugin<Project> {
131155 val generateSchemaTask = project.tasks.named(GENERATE_SDL_TASK_NAME , GraphQLGenerateSDLTask ::class .java).get()
132156 generateSchemaTask.packages.set(supportedPackages)
133157 }
158+
159+ if (extension.isGraalVmConfigurationAvailable()) {
160+ val supportedPackages = extension.graalVmExtension.packages
161+ if (supportedPackages.isEmpty()) {
162+ throw RuntimeException (" Invalid GraphQL graalVm extension configuration - missing required supportedPackages property" )
163+ }
164+
165+ val graalVmMetadataTask = project.tasks.named(GRAALVM_METADATA_TASK_NAME , GraphQLGraalVmMetadataTask ::class .java).get()
166+ graalVmMetadataTask.packages.set(supportedPackages)
167+ extension.graalVmExtension.mainClassName?.let {
168+ graalVmMetadataTask.mainClassName.set(it)
169+ }
170+ }
134171 }
135172
136- private fun configureTaskClasspaths (project : Project ) {
173+ private fun configureTasks (project : Project ) {
137174 val isAndroidProject = project.plugins.hasPlugin(" com.android.application" ) || project.plugins.hasPlugin(" com.android.library" )
138175 val clientGeneratingTaskNames = mutableListOf<GraphQLGenerateClientTask >()
139176 val testClientGeneratingTaskNames = mutableListOf<GraphQLGenerateTestClientTask >()
@@ -183,6 +220,43 @@ class GraphQLGradlePlugin : Plugin<Project> {
183220 // we also need to explicitly configure compile dependencies
184221 configureAndroidCompileTasks(project, clientGeneratingTaskNames, testClientGeneratingTaskNames)
185222 }
223+
224+ // auto-configure graphQLGraalVmMetadata task if GraalVM native plugin is applied
225+ if (project.plugins.hasPlugin(GRAALVM_PLUGIN_NAME )) {
226+ project.tasks.withType(GraphQLGraalVmMetadataTask ::class .java).configureEach { graalVmMetadataTask ->
227+ // set GraalVM application info
228+ if (project.plugins.hasPlugin(ApplicationPlugin .APPLICATION_PLUGIN_NAME )) {
229+ project.extensions.findByType(JavaApplication ::class .java)?.let { javaApplication ->
230+ javaApplication.mainClass.orNull?.let { mainClass ->
231+ graalVmMetadataTask.mainClassName.convention(mainClass)
232+ }
233+ }
234+ }
235+
236+ // create task dependencies
237+ val compileKotlinTask = project.tasks.findByName(" compileKotlin" ) ? : project.tasks.findByName(" compileKotlinJvm" )
238+ if (compileKotlinTask != null ) {
239+ graalVmMetadataTask.dependsOn(compileKotlinTask)
240+ } else {
241+ project.logger.warn(" compileKotlin/compileKotlinJvm tasks not found. Unable to auto-configure the generateSDLTask dependency on compile task." )
242+ }
243+ project.tasks.findByName(NATIVE_COMPILE_TASK_NAME )?.dependsOn(graalVmMetadataTask)
244+
245+ // configure source sets
246+ val sourceSetContainer = project.extensions.getByType(SourceSetContainer ::class .java)
247+ val graalVmSource = sourceSetContainer.getByName(" graphqlGraalVm" )
248+ graalVmSource.resources {
249+ it.setSrcDirs(listOf (graalVmMetadataTask.outputDirectory))
250+ }
251+
252+ val mainSourceSet = sourceSetContainer.getByName(" main" )
253+ graalVmMetadataTask.source(mainSourceSet.output)
254+ graalVmMetadataTask.projectClasspath.setFrom(mainSourceSet.runtimeClasspath)
255+
256+ val configuration = project.configurations.getAt(GRAALVM_METADATA_CONFIGURATION )
257+ graalVmMetadataTask.pluginClasspath.setFrom(configuration)
258+ }
259+ }
186260 }
187261
188262 private fun configureDefaultProjectSourceSet (project : Project , outputDirectory : DirectoryProperty , targetSourceSet : String = "main") {
0 commit comments