@@ -11,6 +11,7 @@ import com.coder.toolbox.sdk.v2.models.WorkspaceAgent
1111import com.coder.toolbox.sdk.v2.models.WorkspaceStatus
1212import com.jetbrains.toolbox.api.localization.LocalizableString
1313import com.jetbrains.toolbox.api.remoteDev.connection.RemoteToolsHelper
14+ import kotlinx.coroutines.Job
1415import kotlinx.coroutines.TimeoutCancellationException
1516import kotlinx.coroutines.delay
1617import kotlinx.coroutines.flow.StateFlow
@@ -80,7 +81,7 @@ open class CoderProtocolHandler(
8081 val projectFolder = params.projectFolder()
8182
8283 if (! productCode.isNullOrBlank() && ! buildNumber.isNullOrBlank()) {
83- launchIde(productCode, buildNumber, environmentId , projectFolder)
84+ launchIde(environmentId, productCode, buildNumber , projectFolder)
8485 }
8586 }
8687
@@ -303,73 +304,87 @@ open class CoderProtocolHandler(
303304 }
304305
305306 private fun launchIde (
307+ environmentId : String ,
306308 productCode : String ,
307309 buildNumber : String ,
308- environmentId : String ,
309310 projectFolder : String?
310311 ) {
311- var selectedIde = " $productCode -$buildNumber "
312312 context.cs.launch {
313- val installedIdes = context.remoteIdeOrchestrator.getInstalledRemoteTools(environmentId, productCode)
314- val alreadyInstalled = installedIdes.firstOrNull { it.contains(buildNumber) } != null
315- if (alreadyInstalled) {
316- context.logger.info(" $productCode -$buildNumber is already on $environmentId . Going to launch JBClient" )
317- } else {
318- val availableVersions =
319- context.remoteIdeOrchestrator.getAvailableRemoteTools(environmentId, productCode)
320- if (availableVersions.isEmpty()) {
321- val error = IllegalArgumentException (" $productCode is not available on $environmentId " )
322- context.logger.error(error, " Error encountered while handling Coder URI" )
323- context.ui.showSnackbar(
324- UUID .randomUUID().toString(),
325- context.i18n.ptrl(" Error encountered while handling Coder URI" ),
326- context.i18n.pnotr(" $productCode is not available on $environmentId " ),
327- context.i18n.ptrl(" OK" )
328- )
329- return @launch
330- }
313+ val selectedIde = selectAndInstallRemoteIde(productCode, buildNumber, environmentId) ? : return @launch
314+ context.logger.info(" $productCode -$buildNumber is already on $environmentId . Going to launch JBClient" )
315+ installJBClient(selectedIde, environmentId).join()
316+ launchJBClient(selectedIde, environmentId, projectFolder)
317+ }
318+ }
331319
332- val matchingBuildNumber = availableVersions.firstOrNull { it.contains(buildNumber) } != null
333- if (! matchingBuildNumber) {
334- selectedIde = availableVersions.maxOf { it }
335- val msg =
336- " $productCode -$buildNumber is not available, we've selected the latest $selectedIde "
337- context.logger.info(msg)
338- context.ui.showSnackbar(
339- UUID .randomUUID().toString(),
340- context.i18n.pnotr(" $productCode -$buildNumber not available" ),
341- context.i18n.pnotr(msg),
342- context.i18n.ptrl(" OK" )
343- )
344- }
320+ private suspend fun selectAndInstallRemoteIde (
321+ productCode : String ,
322+ buildNumber : String ,
323+ environmentId : String
324+ ): String? {
325+ val installedIdes = context.remoteIdeOrchestrator.getInstalledRemoteTools(environmentId, productCode)
345326
346- // needed otherwise TBX will install it again
347- if (! installedIdes.contains(selectedIde)) {
348- context.logger.info(" Installing $selectedIde on $environmentId ..." )
349- context.remoteIdeOrchestrator.installRemoteTool(environmentId, selectedIde)
350- if (context.remoteIdeOrchestrator.waitForIdeToBeInstalled(environmentId, selectedIde)) {
351- context.logger.info(" Successfully installed $selectedIde on $environmentId ..." )
352- } else {
353- context.ui.showSnackbar(
354- UUID .randomUUID().toString(),
355- context.i18n.pnotr(" $selectedIde could not be installed" ),
356- context.i18n.pnotr(" $selectedIde could not be installed on time. Check the logs for more details" ),
357- context.i18n.ptrl(" OK" )
358- )
359- }
360- } else {
361- context.logger.info(" $selectedIde is already present on $environmentId ..." )
362- }
363- }
327+ var selectedIde = " $productCode -$buildNumber "
328+ if (installedIdes.firstOrNull { it.contains(buildNumber) } != null ) {
329+ context.logger.info(" $selectedIde is already installed on $environmentId " )
330+ return selectedIde
331+ }
332+
333+ selectedIde = resolveAvailableIde(environmentId, productCode, buildNumber) ? : return null
364334
365- val job = context.cs.launch {
366- context.logger.info(" Downloading and installing JBClient counterpart to $selectedIde locally" )
367- context.jbClientOrchestrator.prepareClient(environmentId, selectedIde)
335+ // needed otherwise TBX will install it again
336+ if (! installedIdes.contains(selectedIde)) {
337+ context.logger.info(" Installing $selectedIde on $environmentId ..." )
338+ context.remoteIdeOrchestrator.installRemoteTool(environmentId, selectedIde)
339+
340+ if (context.remoteIdeOrchestrator.waitForIdeToBeInstalled(environmentId, selectedIde)) {
341+ context.logger.info(" Successfully installed $selectedIde on $environmentId ..." )
342+ return selectedIde
343+ } else {
344+ context.ui.showSnackbar(
345+ UUID .randomUUID().toString(),
346+ context.i18n.pnotr(" $selectedIde could not be installed" ),
347+ context.i18n.pnotr(" $selectedIde could not be installed on time. Check the logs for more details" ),
348+ context.i18n.ptrl(" OK" )
349+ )
350+ return null
368351 }
369- job.join()
370- context.logger.info(" Launching $selectedIde on $environmentId " )
371- context.jbClientOrchestrator.connectToIde(environmentId, selectedIde, projectFolder)
352+ } else {
353+ context.logger.info(" $selectedIde is already present on $environmentId ..." )
354+ return selectedIde
355+ }
356+ }
357+
358+ private suspend fun resolveAvailableIde (environmentId : String , productCode : String , buildNumber : String ): String? {
359+ val availableVersions = context
360+ .remoteIdeOrchestrator
361+ .getAvailableRemoteTools(environmentId, productCode)
362+
363+ if (availableVersions.isEmpty()) {
364+ context.logAndShowError(CAN_T_HANDLE_URI_TITLE , " $productCode is not available on $environmentId " )
365+ return null
366+ }
367+
368+ val matchingBuildNumber = availableVersions.firstOrNull { it.contains(buildNumber) } != null
369+ if (! matchingBuildNumber) {
370+ val selectedIde = availableVersions.maxOf { it }
371+ context.logAndShowInfo(
372+ " $productCode -$buildNumber not available" ,
373+ " $productCode -$buildNumber is not available, we've selected the latest $selectedIde "
374+ )
375+ return selectedIde
372376 }
377+ return null
378+ }
379+
380+ private fun installJBClient (selectedIde : String , environmentId : String ): Job = context.cs.launch {
381+ context.logger.info(" Downloading and installing JBClient counterpart to $selectedIde locally" )
382+ context.jbClientOrchestrator.prepareClient(environmentId, selectedIde)
383+ }
384+
385+ private fun launchJBClient (selectedIde : String , environmentId : String , projectFolder : String? ) {
386+ context.logger.info(" Launching $selectedIde on $environmentId " )
387+ context.jbClientOrchestrator.connectToIde(environmentId, selectedIde, projectFolder)
373388 }
374389
375390 private suspend fun CoderRestClient.waitForReady (workspace : Workspace ): Boolean {
0 commit comments