Skip to content

Commit 42babb4

Browse files
committed
Exit Gitpod Task when terminal widget is closed, close terminal widget when Gitpod Task exits, and update terminal widget when Gitpod Task title changes
1 parent 074d984 commit 42babb4

File tree

1 file changed

+54
-8
lines changed

1 file changed

+54
-8
lines changed

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

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ import com.intellij.openapi.client.ClientProjectSession
88
import com.intellij.openapi.diagnostic.thisLogger
99
import com.intellij.util.application
1010
import com.jetbrains.rdserver.terminal.BackendTerminalManager
11-
import io.gitpod.jetbrains.remote.GitpodManager
1211
import io.gitpod.supervisor.api.Status
1312
import io.gitpod.supervisor.api.StatusServiceGrpc
1413
import io.gitpod.supervisor.api.TerminalOuterClass
1514
import io.gitpod.supervisor.api.TerminalServiceGrpc
15+
import io.grpc.StatusRuntimeException
1616
import io.grpc.stub.ClientCallStreamObserver
1717
import io.grpc.stub.ClientResponseObserver
18+
import io.grpc.stub.StreamObserver
1819
import org.jetbrains.plugins.terminal.ShellTerminalWidget
1920
import org.jetbrains.plugins.terminal.TerminalView
2021
import java.util.*
@@ -30,6 +31,7 @@ class GitpodTerminalService(session: ClientProjectSession) {
3031
private val terminalView = TerminalView.getInstance(session.project)
3132
private val backendTerminalManager = BackendTerminalManager.getInstance(session.project)
3233
private val terminalServiceFutureStub = TerminalServiceGrpc.newFutureStub(GitpodManager.supervisorChannel)
34+
private val terminalServiceStub = TerminalServiceGrpc.newStub(GitpodManager.supervisorChannel)
3335
private val statusServiceStub = StatusServiceGrpc.newStub(GitpodManager.supervisorChannel)
3436

3537
init { start() }
@@ -49,7 +51,7 @@ class GitpodTerminalService(session: ClientProjectSession) {
4951
}
5052
}
5153

52-
private fun createSharedTerminalAndExecuteCommand(title: String, command: String) {
54+
private fun createSharedTerminalAndExecuteCommand(title: String, command: String): ShellTerminalWidget? {
5355
val registeredTerminals = terminalView.widgets.toMutableList()
5456

5557
backendTerminalManager.createNewSharedTerminal(UUID.randomUUID().toString(), title)
@@ -59,8 +61,14 @@ class GitpodTerminalService(session: ClientProjectSession) {
5961

6062
widget.terminalTitle.change { applicationTitle = title }
6163

62-
(widget as ShellTerminalWidget).executeCommand(command)
64+
val shellTerminalWidget = widget as ShellTerminalWidget
65+
66+
shellTerminalWidget.executeCommand(command)
67+
68+
return shellTerminalWidget
6369
}
70+
71+
return null
6472
}
6573

6674
private fun createTerminalsAttachedToTasks(
@@ -120,8 +128,9 @@ class GitpodTerminalService(session: ClientProjectSession) {
120128
}
121129

122130
thisLogger().error(
123-
"gitpod: Got an error while trying to get tasks list from Supervisor. Trying again in on second.",
124-
throwable
131+
"gitpod: Got an error while trying to get tasks list from Supervisor. " +
132+
"Trying again in one second.",
133+
throwable
125134
)
126135
}
127136

@@ -150,8 +159,9 @@ class GitpodTerminalService(session: ClientProjectSession) {
150159
}
151160

152161
thisLogger().error(
153-
"gitpod: Got an error while trying to get terminals list from Supervisor. Trying again in on second.",
154-
throwable
162+
"gitpod: Got an error while trying to get terminals list from Supervisor. " +
163+
"Trying again in one second.",
164+
throwable
155165
)
156166
}
157167

@@ -164,9 +174,45 @@ class GitpodTerminalService(session: ClientProjectSession) {
164174
}
165175

166176
private fun createAttachedSharedTerminal(supervisorTerminal: TerminalOuterClass.Terminal) {
167-
createSharedTerminalAndExecuteCommand(
177+
val shellTerminalWidget = createSharedTerminalAndExecuteCommand(
168178
supervisorTerminal.title,
169179
"gp tasks attach ${supervisorTerminal.alias}"
180+
) ?: return
181+
182+
shellTerminalWidget.addListener {
183+
terminalServiceFutureStub.shutdown(
184+
TerminalOuterClass.ShutdownTerminalRequest.newBuilder()
185+
.setAlias(supervisorTerminal.alias)
186+
.build()
187+
)
188+
}
189+
190+
terminalServiceStub.listen(
191+
TerminalOuterClass.ListenTerminalRequest.newBuilder()
192+
.setAlias(supervisorTerminal.alias)
193+
.build(),
194+
object : StreamObserver<TerminalOuterClass.ListenTerminalResponse> {
195+
override fun onNext(response: TerminalOuterClass.ListenTerminalResponse) {
196+
when {
197+
response.hasTitle() -> shellTerminalWidget.terminalTitle.change {
198+
applicationTitle = response.title
199+
}
200+
response.hasExitCode() -> shellTerminalWidget.close()
201+
}
202+
}
203+
204+
override fun onCompleted() = Unit
205+
206+
override fun onError(throwable: Throwable) {
207+
if (throwable is StatusRuntimeException &&
208+
(throwable.status.description == "signal: terminated" ||
209+
throwable.status.description == "signal: killed")) return
210+
211+
thisLogger()
212+
.error("gitpod: Got an error while listening to " +
213+
"'${supervisorTerminal.title}' terminal.", throwable)
214+
}
215+
}
170216
)
171217
}
172218
}

0 commit comments

Comments
 (0)