Skip to content

Commit 54943c3

Browse files
committed
Make notifications about open ports display localhost links when the plugin is auto-forwarding ports
1 parent 6eece7c commit 54943c3

File tree

4 files changed

+45
-8
lines changed

4 files changed

+45
-8
lines changed

components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/GitpodCLIService.kt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import org.jetbrains.io.response
2626
import java.io.OutputStreamWriter
2727
import java.nio.file.InvalidPathException
2828
import java.nio.file.Path
29+
import java.util.regex.Pattern
2930

3031
@Suppress("UnstableApiUsage")
3132
class GitpodCLIService : RestService() {
@@ -64,10 +65,30 @@ class GitpodCLIService : RestService() {
6465
}
6566
}
6667
if (operation == "preview") {
67-
val url = getStringParameter("url", urlDecoder)
68+
var url = getStringParameter("url", urlDecoder)
69+
6870
if (url.isNullOrBlank()) {
6971
return "url is missing"
7072
}
73+
74+
// When it's auto-forwarding ports, we need to consider Gitpod Tasks running "gp preview".
75+
// For example: gp preview --external $(gp url 3000)
76+
if (manager.isAutoForwardingPorts) {
77+
val isGitpodPortUrl = url.matches(
78+
Regex("^https?://([0-9]{1,5})-" + System.getenv("JETBRAINS_GITPOD_WORKSPACE_HOST") + "$")
79+
)
80+
81+
if (isGitpodPortUrl) {
82+
val portsPrefix = "://"
83+
val matcher = Pattern.compile("$portsPrefix([0-9]{1,5})").matcher(url)
84+
85+
if (matcher.find()) {
86+
val portString = matcher.group().substring(portsPrefix.length)
87+
url = "http://localhost:${portString}"
88+
}
89+
}
90+
}
91+
7192
return withClient(request, context) { project ->
7293
BrowserUtil.browse(url, project)
7394
}

components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/GitpodClientProjectSessionTracker.kt

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import org.jetbrains.ide.BuiltInServerManager
3333
import java.util.concurrent.CancellationException
3434
import java.util.concurrent.CompletableFuture
3535

36+
@Suppress("UnstableApiUsage", "OPT_IN_USAGE")
3637
class GitpodClientProjectSessionTracker(
3738
private val session: ClientProjectSession
3839
) : Disposable {
@@ -54,19 +55,26 @@ class GitpodClientProjectSessionTracker(
5455
}
5556
}
5657

57-
private fun isExposedServedPort(port: Status.PortsStatus?): Boolean {
58+
private fun isExposedServedPort(port: PortsStatus?): Boolean {
5859
if (port === null) {
5960
return false
6061
}
6162
return port.served && port.hasExposed()
6263
}
6364

65+
private fun getForwardedPortUrl(port: PortsStatus): String {
66+
return when {
67+
manager.isAutoForwardingPorts -> "http://localhost:${port.localPort}"
68+
else -> port.exposed.url
69+
}
70+
}
71+
6472
private fun showOpenServiceNotification(port: PortsStatus, offerMakePublic: Boolean = false) {
6573
val message = "A service is available on port ${port.localPort}"
6674
val notification = manager.notificationGroup.createNotification(message, NotificationType.INFORMATION)
6775

68-
val openBrowserAction = NotificationAction.createSimple("Open Browser") {
69-
openBrowser(port.exposed.url)
76+
val openBrowserAction = NotificationAction.createSimple("Open browser") {
77+
openBrowser(getForwardedPortUrl(port))
7078
}
7179
notification.addAction(openBrowserAction)
7280

@@ -76,7 +84,7 @@ class GitpodClientProjectSessionTracker(
7684
makePortPublic(info.workspaceId, port)
7785
}
7886
}
79-
val makePublicAction = NotificationAction.createSimple("Make Public", makePublicLambda)
87+
val makePublicAction = NotificationAction.createSimple("Make public", makePublicLambda)
8088
notification.addAction(makePublicAction)
8189
}
8290

@@ -113,7 +121,7 @@ class GitpodClientProjectSessionTracker(
113121
val backendPort = BuiltInServerManager.getInstance().waitForStart().port
114122
val serverPort = StartupUtil.getServerFuture().await().port
115123
val ignorePorts = listOf(backendPort, serverPort, 5990)
116-
val portsStatus = hashMapOf<Int, Status.PortsStatus>()
124+
val portsStatus = hashMapOf<Int, PortsStatus>()
117125

118126
val status = StatusServiceGrpc.newStub(GitpodManager.supervisorChannel)
119127
while (isActive) {
@@ -147,7 +155,7 @@ class GitpodClientProjectSessionTracker(
147155
}
148156

149157
if (port.exposed.onExposed.number == Status.OnPortExposedAction.open_browser_VALUE || port.exposed.onExposed.number == Status.OnPortExposedAction.open_preview_VALUE) {
150-
openBrowser(port.exposed.url)
158+
openBrowser(getForwardedPortUrl(port))
151159
continue
152160
}
153161

@@ -157,7 +165,7 @@ class GitpodClientProjectSessionTracker(
157165
}
158166

159167
if (port.exposed.onExposed.number == Status.OnPortExposedAction.notify_private_VALUE) {
160-
showOpenServiceNotification(port, port.exposed.visibilityValue !== PortVisibility.public_visibility_VALUE)
168+
showOpenServiceNotification(port, port.exposed.visibilityValue != PortVisibility.public_visibility_VALUE)
161169
continue
162170
}
163171
}

components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/GitpodManager.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class GitpodManager : Disposable {
6262
}
6363

6464
val devMode = System.getenv("JB_DEV").toBoolean()
65+
var isAutoForwardingPorts = false
6566
private val backendKind = System.getenv("JETBRAINS_GITPOD_BACKEND_KIND") ?: "unknown"
6667
private val backendQualifier = System.getenv("JETBRAINS_BACKEND_QUALIFIER") ?: "unknown"
6768

components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/latest/GitpodPortForwardingService.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
package io.gitpod.jetbrains.remote.latest
66

7+
import com.intellij.openapi.components.service
78
import com.intellij.openapi.diagnostic.thisLogger
89
import com.intellij.openapi.project.Project
910
import com.intellij.remoteDev.util.onTerminationOrNow
@@ -38,6 +39,10 @@ class GitpodPortForwardingService(private val project: Project) {
3839
}
3940

4041
private fun observePortsListWhileProjectIsOpen() = application.executeOnPooledThread {
42+
val gitpodManager = service<GitpodManager>()
43+
44+
gitpodManager.isAutoForwardingPorts = true
45+
4146
while (project.lifetime.status == LifetimeStatus.Alive) {
4247
try {
4348
observePortsList().get()
@@ -54,6 +59,8 @@ class GitpodPortForwardingService(private val project: Project) {
5459

5560
TimeUnit.SECONDS.sleep(1)
5661
}
62+
63+
gitpodManager.isAutoForwardingPorts = false
5764
}
5865

5966
private fun observePortsList(): CompletableFuture<Void> {

0 commit comments

Comments
 (0)