Skip to content
5 changes: 3 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[versions]
kotlin-plugin = "2.1.21"
intellij-platform-plugin = "2.7.0"
apollo = "4.3.1"
apollo = "5.0.0-alpha.2-SNAPSHOT"
grammarkit-plugin = "2022.3.2.2"
changelog-plugin = "2.2.1"
sqlite-jdbc = "3.43.2.0"
Expand Down Expand Up @@ -32,9 +32,10 @@ changelog = { id = "org.jetbrains.changelog", version.ref = "changelog-plugin" }
apollo-annotations = { group = "com.apollographql.apollo", name = "apollo-annotations", version.ref = "apollo" }
apollo-api = { group = "com.apollographql.apollo", name = "apollo-api", version.ref = "apollo" }
apollo-runtime = { group = "com.apollographql.apollo", name = "apollo-runtime", version.ref = "apollo" }
apollo-gradle-plugin-external = { group = "com.apollographql.apollo", name = "apollo-gradle-plugin-external", version.ref = "apollo" }
apollo-gradle-plugin = { group = "com.apollographql.apollo", name = "apollo-gradle-plugin", version.ref = "apollo" }
apollo-ast = { group = "com.apollographql.apollo", name = "apollo-ast", version.ref = "apollo" }
apollo-tooling = { group = "com.apollographql.apollo", name = "apollo-tooling", version.ref = "apollo" }
apollo-compiler = { group = "com.apollographql.apollo", name = "apollo-compiler", version.ref = "apollo" }
apollo-normalized-cache-sqlite-classic = { group = "com.apollographql.apollo", name = "apollo-normalized-cache-sqlite", version.ref = "apollo" }
apollo-normalized-cache-sqlite-new = { group = "com.apollographql.cache", name = "normalized-cache-sqlite", version.ref = "apollo-normalizedcache" }
sqlite-jdbc = { group = "org.xerial", name = "sqlite-jdbc", version.ref = "sqlite-jdbc" }
Expand Down
7 changes: 5 additions & 2 deletions plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ plugins {
}

repositories {
// mavenLocal()
// maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
// maven("https://storage.googleapis.com/apollo-previews/m2/")
mavenCentral()
mavenLocal()

intellijPlatform {
defaultRepositories()
Expand Down Expand Up @@ -178,7 +178,7 @@ dependencies {

// Coroutines must be excluded to avoid a conflict with the version bundled with the IDE
// See https://plugins.jetbrains.com/docs/intellij/using-kotlin.html#coroutinesLibraries
implementation(libs.apollo.gradle.plugin.external) {
implementation(libs.apollo.gradle.plugin) {
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-coroutines-core")
}
implementation(libs.apollo.ast)
Expand All @@ -193,7 +193,10 @@ dependencies {
implementation(libs.apollo.runtime) {
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-coroutines-core")
}
implementation(libs.apollo.compiler)

runtimeOnly(libs.slf4j.simple)

testImplementation(libs.google.testparameterinjector)

// Temporary workaround for https://github.com/JetBrains/intellij-platform-gradle-plugin/issues/1663
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.apollographql.ijplugin.codegen
import com.apollographql.ijplugin.gradle.CODEGEN_GRADLE_TASK_NAME
import com.apollographql.ijplugin.gradle.GradleHasSyncedListener
import com.apollographql.ijplugin.gradle.SimpleProgressListener
import com.apollographql.ijplugin.gradle.apolloKotlinProjectModelService
import com.apollographql.ijplugin.gradle.getGradleRootPath
import com.apollographql.ijplugin.gradle.runGradleBuild
import com.apollographql.ijplugin.project.ApolloProjectListener
Expand All @@ -12,13 +13,15 @@ import com.apollographql.ijplugin.settings.ProjectSettingsListener
import com.apollographql.ijplugin.settings.ProjectSettingsState
import com.apollographql.ijplugin.settings.projectSettingsState
import com.apollographql.ijplugin.util.apolloGeneratedSourcesRoots
import com.apollographql.ijplugin.util.apolloKotlinService
import com.apollographql.ijplugin.util.dispose
import com.apollographql.ijplugin.util.isNotDisposed
import com.apollographql.ijplugin.util.logd
import com.apollographql.ijplugin.util.logw
import com.apollographql.ijplugin.util.newDisposable
import com.apollographql.ijplugin.util.runWriteActionInEdt
import com.intellij.lang.jsgraphql.GraphQLFileType
import com.intellij.lang.jsgraphql.psi.GraphQLFile
import com.intellij.openapi.Disposable
import com.intellij.openapi.components.Service
import com.intellij.openapi.editor.Document
Expand All @@ -33,6 +36,7 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.util.CheckedDisposable
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.psi.PsiDocumentManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import org.gradle.tooling.CancellationTokenSource
Expand Down Expand Up @@ -83,20 +87,19 @@ class ApolloCodegenService(

private fun startOrStopCodegenObservers() {
if (shouldTriggerCodegenAutomatically()) {
// To make the codegen more reactive, any touched GraphQL document will automatically be saved (thus triggering Gradle)
// To make the codegen more reactive, any touched GraphQL document will automatically be saved (thus triggering the codegen)
// as soon as the current editor is changed.
startObserveDocumentChanges()
startObserveFileEditorChanges()

startContinuousGradleCodegen()
startCodegen()

// Since we rely on Gradle's continuous build, which is not re-triggered when Gradle build files change, observe that
// ourselves and restart the build when it happens.
// A Gradle sync is a good indicator that Gradle files have changed - trigger a codegen build when that happens.
startObserveGradleHasSynced()
} else {
stopObserveDocumentChanges()
stopObserveFileEditorChanges()
stopContinuousGradleCodegen()
stopCodegen()
stopObserveGradleHasSynced()
}
}
Expand Down Expand Up @@ -144,8 +147,11 @@ class ApolloCodegenService(
fileEditorChangesDisposable = disposable
project.messageBus.connect(disposable).subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, object : FileEditorManagerListener {
override fun selectionChanged(event: FileEditorManagerEvent) {
logd(event.newFile)
logd(event.newFile?.path)
dirtyGqlDocument?.let {
val operationGraphQLFile = PsiDocumentManager.getInstance(project).getPsiFile(dirtyGqlDocument!!) as? GraphQLFile
val apolloKotlinService = operationGraphQLFile?.apolloKotlinService()
logd("apolloKotlinService=${apolloKotlinService?.id}")
dirtyGqlDocument = null
runWriteActionInEdt {
try {
Expand All @@ -156,6 +162,14 @@ class ApolloCodegenService(
logw(e, "Failed to save document")
}
}

if (apolloKotlinService?.hasCompilerOptions == true) {
// We can use the built-in Apollo compiler
ApolloCompilerHelper(project).generateSources(apolloKotlinService)
} else {
// Fall back to the Gradle codegen task
startGradleCodegen()
}
}
}
})
Expand All @@ -167,7 +181,7 @@ class ApolloCodegenService(
fileEditorChangesDisposable = null
}

private fun startContinuousGradleCodegen() {
private fun startGradleCodegen() {
logd()

if (gradleCodegenCancellation != null) {
Expand All @@ -178,18 +192,17 @@ class ApolloCodegenService(
val modules = ModuleManager.getInstance(project).modules
coroutineScope.launch {
gradleCodegenCancellation = GradleConnector.newCancellationTokenSource()
logd("Start Gradle")
logd("Start Gradle codegen build")
try {
val cancellationToken = gradleCodegenCancellation!!.token()
val gradleProjectPath = project.getGradleRootPath()
if (gradleProjectPath == null) {
logw("Could not get Gradle root project path")
return@launch
}
runGradleBuild(project, gradleProjectPath) {
it.forTasks(CODEGEN_GRADLE_TASK_NAME)
runGradleBuild(project, gradleProjectPath) { buildLauncher ->
buildLauncher.forTasks(CODEGEN_GRADLE_TASK_NAME)
.withCancellationToken(cancellationToken)
.addArguments("--continuous")
.let {
if (project.projectSettingsState.automaticCodegenAdditionalGradleJvmArguments.isNotEmpty()) {
it.addJvmArguments(project.projectSettingsState.automaticCodegenAdditionalGradleJvmArguments.split(' '))
Expand All @@ -199,24 +212,24 @@ class ApolloCodegenService(
}
.addProgressListener(object : SimpleProgressListener() {
override fun onSuccess() {
logd("Gradle build success, marking generated source roots as dirty")
logd("Gradle codegen build success, marking generated source roots as dirty")
// Mark the generated sources dirty so the files are visible to the IDE
val generatedSourceRoots = modules.flatMap { it.apolloGeneratedSourcesRoots() }
logd("Mark dirty $generatedSourceRoots")
VfsUtil.markDirtyAndRefresh(true, true, true, *generatedSourceRoots.toTypedArray())
}
})
}
logd("Gradle execution finished")
logd("Gradle codegen build finished")
} catch (t: Throwable) {
logd(t, "Gradle execution failed")
logd(t, "Gradle codegen build failed")
} finally {
gradleCodegenCancellation = null
}
}
}

private fun stopContinuousGradleCodegen() {
private fun stopCodegen() {
logd()
gradleCodegenCancellation?.cancel()
gradleCodegenCancellation = null
Expand All @@ -235,12 +248,22 @@ class ApolloCodegenService(
project.messageBus.connect(disposable).subscribe(GradleHasSyncedListener.TOPIC, object : GradleHasSyncedListener {
override fun gradleHasSynced() {
logd()
stopContinuousGradleCodegen()
if (shouldTriggerCodegenAutomatically()) startContinuousGradleCodegen()
stopCodegen()
if (shouldTriggerCodegenAutomatically()) startCodegen()
}
})
}

private fun startCodegen() {
if (project.apolloKotlinProjectModelService.getApolloKotlinServices().any { it.hasCompilerOptions }) {
logd("Using Apollo compiler for codegen")
ApolloCompilerHelper(project).generateAllSources()
} else {
logd("Using Gradle codegen task")
startGradleCodegen()
}
}

private fun stopObserveGradleHasSynced() {
logd()
dispose(gradleHasSyncedDisposable)
Expand All @@ -249,6 +272,6 @@ class ApolloCodegenService(

override fun dispose() {
logd("project=${project.name}")
stopContinuousGradleCodegen()
stopCodegen()
}
}
Loading
Loading