-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Introduce builtin Gradle Sync pausing in JetBrains IDEs with GP CLI #20362
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
Changes from 3 commits
fe0428e
d17ce2c
89f998a
cdf7403
1ff3809
5317b91
66c6a0d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| // Copyright (c) 2024 Gitpod GmbH. All rights reserved. | ||
| // Licensed under the GNU Affero General Public License (AGPL). | ||
| // See License.AGPL.txt in the project root for license information. | ||
|
|
||
| package cmd | ||
|
|
||
| import ( | ||
| "os" | ||
|
|
||
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| const gradleSyncLockFile = "/tmp/gitpod-gradle.lock" | ||
|
|
||
| var jetbrainsGradlePauseCmd = &cobra.Command{ | ||
| Use: "pause", | ||
| Short: "Pause Gradle Sync in JetBrains IDEs", | ||
| Long: `Pause JetBrains IDE gradle sync to prevent performance issues on Gitpod workspace startup when there's no Prebuilds ready. | ||
|
|
||
| This command is typically used to prevent concurrent Gradle syncs between: | ||
| - Manual gradle initialization in Gitpod init tasks | ||
| - JetBrains Gateway/IDEA's automatic Gradle sync on project open | ||
|
|
||
| Typical usage in your .gitpod.yml: | ||
|
|
||
| tasks: | ||
| - init: | | ||
| ide jetbrains gradle pause # Prevent IDEA's gradle sync | ||
| ... | ||
| ./gradlew <init_service> # Run your initialization tasks | ||
| ide jetbrains gradle resume # Enable | ||
| command: ./gradlew <dev_service> | ||
|
|
||
| If you have two init tasks want to pause Gradle Sync: | ||
|
|
||
| tasks: | ||
| - name: Task 1 | ||
| init: | | ||
| ide jetbrains gradle pause # Prevent IDEA's gradle sync | ||
| ./gradlew <init_service> | ||
| gp sync-await gradle-init-1 | ||
| ide jetbrains gradle resume # Enable | ||
| - name: Task 2 | ||
| init: | | ||
| ./gradlew <init_service> | ||
| gp sync-done gradle-init-1 | ||
| `, | ||
| RunE: func(cmd *cobra.Command, args []string) error { | ||
| err := os.WriteFile(gradleSyncLockFile, []byte{}, 0644) | ||
| if err != nil && os.IsExist(err) { | ||
| return nil | ||
| } | ||
| return err | ||
| }, | ||
| } | ||
|
|
||
| func init() { | ||
| jetbrainsGradleCmd.AddCommand(jetbrainsGradlePauseCmd) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // Copyright (c) 2024 Gitpod GmbH. All rights reserved. | ||
| // Licensed under the GNU Affero General Public License (AGPL). | ||
| // See License.AGPL.txt in the project root for license information. | ||
|
|
||
| package cmd | ||
|
|
||
| import ( | ||
| "os" | ||
|
|
||
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| var jetbrainsGradleResumeCmd = &cobra.Command{ | ||
| Use: "resume", | ||
| Short: "Resume paused Gradle Sync in JetBrains IDEs", | ||
| RunE: func(cmd *cobra.Command, args []string) error { | ||
| err := os.Remove(gradleSyncLockFile) | ||
| if err != nil && os.IsNotExist(err) { | ||
| return nil | ||
| } | ||
| return err | ||
| }, | ||
| } | ||
|
|
||
| func init() { | ||
| jetbrainsGradleCmd.AddCommand(jetbrainsGradleResumeCmd) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| // Copyright (c) 2024 Gitpod GmbH. All rights reserved. | ||
| // Licensed under the GNU Affero General Public License (AGPL). | ||
| // See License.AGPL.txt in the project root for license information. | ||
|
|
||
| package cmd | ||
|
|
||
| import ( | ||
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| var jetbrainsGradleCmd = &cobra.Command{ | ||
| Use: "gradle", | ||
| Short: "Interact with JetBrains Gradle services.", | ||
| } | ||
|
|
||
| func init() { | ||
| jetbrainsCmd.AddCommand(jetbrainsGradleCmd) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| // Copyright (c) 2024 Gitpod GmbH. All rights reserved. | ||
| // Licensed under the GNU Affero General Public License (AGPL). | ||
| // See License.AGPL.txt in the project root for license information. | ||
|
|
||
| package cmd | ||
|
|
||
| import ( | ||
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| var jetbrainsCmd = &cobra.Command{ | ||
| Use: "jetbrains", | ||
| Aliases: []string{"jb"}, | ||
| Short: "Interact with JetBrains editor.", | ||
| } | ||
|
|
||
| func init() { | ||
| rootCmd.AddCommand(jetbrainsCmd) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -151,6 +151,7 @@ packages: | |
| - NO_VERIFY_JB_PLUGIN=true | ||
| config: | ||
| commands: | ||
| - ["rm", "-rf", "src/main/kotlin/io/gitpod/jetbrains/remote/listeners/GradleSyncListener.kt"] | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need this line because the file |
||
| - ["mv", "build.gradle-stable.kts", "build.gradle.kts"] | ||
| - ["./build.sh", "${__git_commit}"] | ||
| - name: plugin-latest-rider | ||
|
|
@@ -182,6 +183,7 @@ packages: | |
| - SDKMAN_DIR=/home/gitpod/.sdkman | ||
| config: | ||
| commands: | ||
| - ["rm", "-rf", "src/main/kotlin/io/gitpod/jetbrains/remote/listeners/GradleSyncListener.kt"] | ||
| # TODO(hw): remove after 2024.2.* is stable | ||
| - ["mv", "build.gradle-latest.kts", "build.gradle.kts"] | ||
| - - "bash" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| // Copyright (c) 2024 Gitpod GmbH. All rights reserved. | ||
| // Licensed under the GNU Affero General Public License (AGPL). | ||
| // See License.AGPL.txt in the project root for license information. | ||
|
|
||
| package io.gitpod.jetbrains.remote.listeners | ||
|
|
||
| import com.intellij.notification.Notification | ||
| import com.intellij.notification.NotificationAction | ||
| import com.intellij.notification.NotificationType | ||
| import com.intellij.notification.Notifications | ||
| import com.intellij.openapi.actionSystem.AnActionEvent | ||
| import com.intellij.openapi.application.ApplicationManager | ||
| import com.intellij.openapi.diagnostic.thisLogger | ||
| import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId | ||
| import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener | ||
| import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType | ||
| import java.io.File | ||
|
|
||
| class GradleSyncListener : ExternalSystemTaskNotificationListener { | ||
| override fun onStart(id: ExternalSystemTaskId, workingDir: String?) { | ||
| if (id.projectSystemId.toString() != "GRADLE" || id.type != ExternalSystemTaskType.RESOLVE_PROJECT) { | ||
| return | ||
| } | ||
| val lockFile = File("/tmp/gitpod-gradle.lock") | ||
| if (!lockFile.exists()) { | ||
| return | ||
| } | ||
|
|
||
| val notification = Notification( | ||
| "gitpod", | ||
| "Gitpod: Pause gradle sync", | ||
| "Pausing Gradle Sync, execute <code style='color: orange;'>gp jetbrains gradle resume</code> to unblock all builtin Gradle Sync <br><br>Current Task ID: ${id.id}", | ||
| NotificationType.INFORMATION | ||
| ) | ||
| var isCancelled = false | ||
| notification.addAction(object : NotificationAction("Cancel") { | ||
| override fun actionPerformed(e: AnActionEvent, notification: Notification) { | ||
| isCancelled = true | ||
| notification.expire() | ||
| } | ||
| }) | ||
|
Comment on lines
+38
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this actually cancel the sync? It looks more like it just dismisses the notification. If so, let's rename it to |
||
| Notifications.Bus.notify(notification) | ||
|
|
||
| while (lockFile.exists()) { | ||
| if (isCancelled) { | ||
| thisLogger().warn("gitpod: gradle sync pausing is cancelled") | ||
| break | ||
| } | ||
| Thread.sleep(1000) | ||
| } | ||
| thisLogger().warn("gitpod: gradle sync pausing finished") | ||
| ApplicationManager.getApplication().invokeLater { | ||
| notification.expire() | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.