-
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 all 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,63 @@ | ||
| // 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" | ||
| ) | ||
|
|
||
| // Note: This location is used on GradleSyncListener.kt | ||
| // https://github.com/gitpod-io/gitpod/blob/5317b915e409968af72bd857aa69b3ebf10b6698/components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/listeners/GradleSyncListener.kt#L24 | ||
| const gradleSyncLockFile = "/tmp/gitpod-gradle.lock" | ||
|
|
||
| var jetbrainsGradlePauseCmd = &cobra.Command{ | ||
| Use: "pause", | ||
| Short: "Pause JetBrains' builtin automatic Gradle Sync", | ||
| Long: `Pause JetBrains' builtin automatic 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 IDEs' (IDEA) automatic Gradle sync on project open | ||
|
|
||
| Typical usage in your .gitpod.yml: | ||
|
|
||
| tasks: | ||
| - init: | | ||
| gp jetbrains gradle pause # Prevent JetBrains' auto gradle sync at beginning | ||
| ... | ||
| ./gradlew <init_service> # Run your initialization tasks | ||
| gp jetbrains gradle resume # Enable | ||
| command: ./gradlew <dev_service> | ||
|
|
||
| If you have two init tasks want to pause Gradle Sync: | ||
|
|
||
| tasks: | ||
| - name: Task 1 | ||
| init: | | ||
| gp jetbrains gradle pause # Prevent JetBrains' auto gradle sync | ||
| ./gradlew <init_service> | ||
| gp sync-await gradle-init-1 | ||
| gp jetbrains gradle resume # Enable | ||
| - name: Task 2 | ||
| init: | | ||
| ./gradlew <init_service> | ||
| gp sync-done gradle-init-1 | ||
| - name: Task 3 | ||
| command: echo hi there | ||
| `, | ||
| 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", | ||
| 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,58 @@ | ||||||||||
| // 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 | ||||||||||
| } | ||||||||||
| // Note: This file is written by the GP CLI | ||||||||||
| // https://github.com/gitpod-io/gitpod/blob/5317b915e409968af72bd857aa69b3ebf10b6698/components/gitpod-cli/cmd/jetbrains-gradle-pause.go#L1 | ||||||||||
| 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", | ||||||||||
|
Comment on lines
+33
to
+34
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.
Suggested change
|
||||||||||
| 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.