Skip to content

[IJ Plugin] Remove references to GradleExecutionHelper, use Gradle Tooling APIs directly instead #6558

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

Merged
merged 3 commits into from
Jun 6, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ 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.getGradleRootPath
import com.apollographql.ijplugin.gradle.runGradleBuild
import com.apollographql.ijplugin.project.ApolloProjectListener
import com.apollographql.ijplugin.project.ApolloProjectService
import com.apollographql.ijplugin.project.apolloProjectService
Expand All @@ -24,7 +25,6 @@ import com.intellij.openapi.editor.Document
import com.intellij.openapi.editor.EditorFactory
import com.intellij.openapi.editor.event.DocumentEvent
import com.intellij.openapi.editor.event.DocumentListener
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.fileEditor.FileEditorManagerEvent
import com.intellij.openapi.fileEditor.FileEditorManagerListener
Expand All @@ -37,10 +37,6 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import org.gradle.tooling.CancellationTokenSource
import org.gradle.tooling.GradleConnector
import org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings
import org.jetbrains.plugins.gradle.util.GradleConstants
import java.io.File

@Service(Service.Level.PROJECT)
class ApolloCodegenService(
Expand Down Expand Up @@ -180,19 +176,18 @@ class ApolloCodegenService(
}

val modules = ModuleManager.getInstance(project).modules
val rootProjectPath = project.getGradleRootPath() ?: return
coroutineScope.launch {
val executionSettings =
ExternalSystemApiUtil.getExecutionSettings<GradleExecutionSettings>(project, rootProjectPath, GradleConstants.SYSTEM_ID)
val gradleExecutionHelper = GradleExecutionHelper()
gradleExecutionHelper.execute(rootProjectPath, executionSettings) { connection ->
gradleCodegenCancellation = GradleConnector.newCancellationTokenSource()
logd("Start Gradle")
try {
val cancellationToken = gradleCodegenCancellation!!.token()
connection.newBuild()
.setJavaHome(executionSettings.javaHome?.let { File(it) })
.forTasks(CODEGEN_GRADLE_TASK_NAME)
gradleCodegenCancellation = GradleConnector.newCancellationTokenSource()
logd("Start Gradle")
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)
.withCancellationToken(cancellationToken)
.addArguments("--continuous")
.let {
Expand All @@ -211,13 +206,12 @@ class ApolloCodegenService(
VfsUtil.markDirtyAndRefresh(true, true, true, *generatedSourceRoots.toTypedArray())
}
})
.run()
logd("Gradle execution finished")
} catch (t: Throwable) {
logd(t, "Gradle execution failed")
} finally {
gradleCodegenCancellation = null
}
logd("Gradle execution finished")
} catch (t: Throwable) {
logd(t, "Gradle execution failed")
} finally {
gradleCodegenCancellation = null
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,11 @@ import com.intellij.notification.NotificationType
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.Task
import com.intellij.openapi.project.Project
import org.gradle.tooling.Failure
import org.gradle.tooling.model.GradleProject
import org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings
import org.jetbrains.plugins.gradle.util.GradleConstants
import java.io.File

class DownloadSchemaAction : AnAction() {
override fun actionPerformed(e: AnActionEvent) {
Expand All @@ -49,20 +44,13 @@ private class DownloadSchemaTask(project: Project) : Task.Backgroundable(
false,
) {
override fun run(indicator: ProgressIndicator) {
val rootProjectPath = project.getGradleRootPath() ?: return
val gradleExecutionHelper = GradleExecutionHelper()
val executionSettings =
ExternalSystemApiUtil.getExecutionSettings<GradleExecutionSettings>(project, rootProjectPath, GradleConstants.SYSTEM_ID)
val rootGradleProject = gradleExecutionHelper.execute(rootProjectPath, executionSettings) { connection ->
logd("Fetch Gradle project model")
return@execute try {
connection.model<GradleProject>(GradleProject::class.java)
.setJavaHome(executionSettings.javaHome?.let { File(it) })
.get()
} catch (t: Throwable) {
logw(t, "Couldn't fetch Gradle project model")
null
}
val gradleProjectPath = project.getGradleRootPath() ?: return

val rootGradleProject: GradleProject = try {
getGradleModel(project, gradleProjectPath) { it }
} catch (t: Throwable) {
logw(t, "Couldn't fetch Gradle project model")
null
} ?: return

val allDownloadSchemaTasks: List<String> = rootGradleProject.allChildrenRecursively()
Expand All @@ -83,11 +71,9 @@ private class DownloadSchemaTask(project: Project) : Task.Backgroundable(
return
}

gradleExecutionHelper.execute(rootProjectPath, executionSettings) { connection ->
try {
connection.newBuild()
.setJavaHome(executionSettings.javaHome?.let { File(it) })
.forTasks(*allDownloadSchemaTasks.toTypedArray())
try {
runGradleBuild(project, gradleProjectPath) {
it.forTasks(*allDownloadSchemaTasks.toTypedArray())
.addProgressListener(object : SimpleProgressListener() {
override fun onFailure(failures: List<Failure>) {
super.onFailure(failures)
Expand All @@ -112,11 +98,10 @@ private class DownloadSchemaTask(project: Project) : Task.Backgroundable(
)
}
})
.run()
logd("Gradle execution finished")
} catch (t: Throwable) {
logd(t, "Gradle execution failed")
}
logd("Gradle execution finished")
} catch (t: Throwable) {
logd(t, "Gradle execution failed")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import com.apollographql.ijplugin.util.newDisposable
import com.intellij.openapi.Disposable
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.project.Project
Expand All @@ -29,9 +28,6 @@ import kotlinx.coroutines.launch
import org.gradle.tooling.CancellationTokenSource
import org.gradle.tooling.GradleConnector
import org.gradle.tooling.model.GradleProject
import org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings
import org.jetbrains.plugins.gradle.util.GradleConstants
import java.io.File

@Service(Service.Level.PROJECT)
Expand Down Expand Up @@ -160,24 +156,22 @@ class GradleToolingModelService(

private fun doRun() {
logd()
val rootProjectPath = project.getGradleRootPath() ?: return
val gradleExecutionHelper = GradleExecutionHelper()
val executionSettings =
ExternalSystemApiUtil.getExecutionSettings<GradleExecutionSettings>(project, rootProjectPath, GradleConstants.SYSTEM_ID)
val rootGradleProject = gradleExecutionHelper.execute(rootProjectPath, executionSettings) { connection ->
gradleCancellation = GradleConnector.newCancellationTokenSource()
logd("Fetch Gradle project model")
return@execute try {
connection.model<GradleProject>(GradleProject::class.java)
.setJavaHome(executionSettings.javaHome?.let { File(it) })
.withCancellationToken(gradleCancellation!!.token())
.get()
} catch (t: Throwable) {
logw(t, "Couldn't fetch Gradle project model")
null
} finally {
gradleCancellation = null
gradleCancellation = GradleConnector.newCancellationTokenSource()
logd("Fetch Gradle project model")
val gradleProjectPath = project.getGradleRootPath()
if (gradleProjectPath == null) {
logw("Could not get Gradle root project path")
return
}
val rootGradleProject: GradleProject = try {
getGradleModel(project, gradleProjectPath) {
it.withCancellationToken(gradleCancellation!!.token())
}
} catch (t: Throwable) {
logw(t, "Couldn't fetch Gradle project model")
null
} finally {
gradleCancellation = null
} ?: return
project.telemetryService.gradleModuleCount = rootGradleProject.children.size + 1

Expand All @@ -189,27 +183,25 @@ class GradleToolingModelService(

val allToolingModels = allApolloGradleProjects.mapIndexedNotNull { index, gradleProject ->
if (isAbortRequested()) return@doRun
gradleExecutionHelper.execute(gradleProject.projectDirectory.canonicalPath, executionSettings) { connection ->
gradleCancellation = GradleConnector.newCancellationTokenSource()
logd("Fetch tooling model for ${gradleProject.path}")
return@execute try {
connection.model<ApolloGradleToolingModel>(ApolloGradleToolingModel::class.java)
.setJavaHome(executionSettings.javaHome?.let { File(it) })
.withCancellationToken(gradleCancellation!!.token())
.get()
.takeIf {
val isCompatibleVersion = it.versionMajor == ApolloGradleToolingModel.VERSION_MAJOR
if (!isCompatibleVersion) {
logw("Incompatible version of Apollo Gradle plugin in module ${gradleProject.path}: ${it.versionMajor} != ${ApolloGradleToolingModel.VERSION_MAJOR}, ignoring")
}
isCompatibleVersion
}
} catch (t: Throwable) {
logw(t, "Couldn't fetch tooling model for ${gradleProject.path}")
null
} finally {
gradleCancellation = null

gradleCancellation = GradleConnector.newCancellationTokenSource()
logd("Fetch tooling model for ${gradleProject.path}")
try {
getGradleModel<ApolloGradleToolingModel>(project, gradleProject.projectDirectory.canonicalPath ) {
it.withCancellationToken(gradleCancellation!!.token())
}
?.takeIf {
val isCompatibleVersion = it.versionMajor == ApolloGradleToolingModel.VERSION_MAJOR
if (!isCompatibleVersion) {
logw("Incompatible version of Apollo Gradle plugin in module ${gradleProject.path}: ${it.versionMajor} != ${ApolloGradleToolingModel.VERSION_MAJOR}, ignoring")
}
isCompatibleVersion
}
} catch (t: Throwable) {
logw(t, "Couldn't fetch tooling model for ${gradleProject.path}")
null
} finally {
gradleCancellation = null
}
}

Expand All @@ -226,7 +218,7 @@ class GradleToolingModelService(
}
try {
ProgressManager.checkCanceled()
} catch (e: ProcessCanceledException) {
} catch (@Suppress("IncorrectCancellationExceptionHandling") _: ProcessCanceledException) {
logd("Canceled by user")
return true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ import com.apollographql.ijplugin.util.logw
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.project.Project
import org.gradle.tooling.BuildLauncher
import org.gradle.tooling.GradleConnector
import org.gradle.tooling.ModelBuilder
import org.gradle.tooling.model.GradleProject
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings
import org.jetbrains.plugins.gradle.util.GradleConstants
import java.io.File

const val CODEGEN_GRADLE_TASK_NAME = "generateApolloSources"

Expand All @@ -19,3 +25,51 @@ fun Project.getGradleRootPath(): String? {
fun GradleProject.allChildrenRecursively(): List<GradleProject> {
return listOf(this) + children.flatMap { it.allChildrenRecursively() }
}

fun runGradleBuild(
project: Project,
gradleProjectPath: String,
configureBuildLauncher: (BuildLauncher) -> BuildLauncher,
) {
val executionSettings = ExternalSystemApiUtil.getExecutionSettings<GradleExecutionSettings>(
project,
gradleProjectPath,
GradleConstants.SYSTEM_ID
)
val connection = GradleConnector.newConnector()
.forProjectDirectory(File(gradleProjectPath))
.connect()
val buildLauncher = configureBuildLauncher(
connection.newBuild()
.setJavaHome(executionSettings.javaHome?.let { File(it) })
)
try {
buildLauncher.run()
} finally {
connection.close()
}
}

inline fun <reified T> getGradleModel(
project: Project,
gradleProjectPath: String,
configureModelBuilder: (ModelBuilder<T>) -> ModelBuilder<T>,
): T? {
val executionSettings = ExternalSystemApiUtil.getExecutionSettings<GradleExecutionSettings>(
project,
gradleProjectPath,
GradleConstants.SYSTEM_ID
)
val connection = GradleConnector.newConnector()
.forProjectDirectory(File(gradleProjectPath))
.connect()
val modelBuilder = configureModelBuilder(
connection.model(T::class.java)
.setJavaHome(executionSettings.javaHome?.let { File(it) })
)
try {
return modelBuilder.get()
} finally {
connection.close()
}
}
Loading