Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitce3f67b

Browse files
committed
impl: support forlatest_eap,latest_release andlatest_installed placeholders
This PR adds support for the IDE placeholders in the URI build number parameter. This is a requestcoming from Netflix, the placeholders provide an easier way to fill in the build number from theweb dashboard without having to know the available versions of IDE from Toolbox.IDE launch flow is refactored to support dynamic build selectors, and it also improves theinstall/launch logic. When latest_eap or latest_release is used:- prefer the newest matching version that is available for install- install it only if it isn’t already installed- fall back to the latest available version if no match exists- show an error if none of the above happensWhen latest_installed is used:- launch the newest installed version- if none are installed, install and launch the latest available version- show an error if none of the above happens
1 parentd5bf957 commitce3f67b

File tree

1 file changed

+111
-44
lines changed

1 file changed

+111
-44
lines changed

‎src/main/kotlin/com/coder/toolbox/util/CoderProtocolHandler.kt‎

Lines changed: 111 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.coder.toolbox.util
33
importcom.coder.toolbox.CoderToolboxContext
44
importcom.coder.toolbox.cli.CoderCLIManager
55
importcom.coder.toolbox.feed.IdeFeedManager
6+
importcom.coder.toolbox.feed.IdeType
67
importcom.coder.toolbox.models.WorkspaceAndAgentStatus
78
importcom.coder.toolbox.sdk.CoderRestClient
89
importcom.coder.toolbox.sdk.v2.models.Workspace
@@ -27,7 +28,7 @@ private const val CAN_T_HANDLE_URI_TITLE = "Can't handle URI"
2728
@Suppress("UnstableApiUsage")
2829
openclassCoderProtocolHandler(
2930
privatevalcontext:CoderToolboxContext,
30-
ideFeedManager:IdeFeedManager,
31+
privatevalideFeedManager:IdeFeedManager,
3132
) {
3233
privateval settings= context.settingsStore.readOnly()
3334

@@ -236,72 +237,136 @@ open class CoderProtocolHandler(
236237
privatefunlaunchIde(
237238
environmentId:String,
238239
productCode:String,
239-
buildNumber:String,
240+
buildNumberHint:String,
240241
projectFolder:String?
241242
) {
242243
context.cs.launch(CoroutineName("Launch Remote IDE")) {
243-
val selectedIde= selectAndInstallRemoteIde(productCode, buildNumber, environmentId)?:return@launch
244-
context.logger.info("$productCode-$buildNumber is already on$environmentId. Going to launch JBClient")
244+
val selectedIde= selectAndInstallRemoteIde(productCode, buildNumberHint, environmentId)?:return@launch
245+
context.logger.info("Selected IDE$selectedIde for$productCode with hint$buildNumberHint")
246+
247+
// Ensure JBClient is prepared (installed/downloaded locally)
245248
installJBClient(selectedIde, environmentId).join()
249+
250+
// Launch
246251
launchJBClient(selectedIde, environmentId, projectFolder)
247252
}
248253
}
249254

250255
privatesuspendfunselectAndInstallRemoteIde(
251256
productCode:String,
252-
buildNumber:String,
257+
buildNumberHint:String,
253258
environmentId:String
254259
):String? {
255-
val installedIdes= context.remoteIdeOrchestrator.getInstalledRemoteTools(environmentId, productCode)
260+
val selectedIdeVersion= resolveIdeIdentifier(environmentId, productCode, buildNumberHint)?:returnnull
261+
val installedIdeVersions= context.remoteIdeOrchestrator.getInstalledRemoteTools(environmentId, productCode)
262+
263+
if (installedIdeVersions.contains(selectedIdeVersion)) {
264+
context.logger.info("$selectedIdeVersion is already installed on$environmentId")
265+
return selectedIdeVersion
266+
}
267+
268+
val selectedIde="$productCode-$selectedIdeVersion"
269+
context.logger.info("Installing$selectedIde on$environmentId...")
270+
context.remoteIdeOrchestrator.installRemoteTool(environmentId, selectedIde)
256271

257-
var selectedIde="$productCode-$buildNumber"
258-
if (installedIdes.firstOrNull { it.contains(buildNumber) }!=null) {
259-
context.logger.info("$selectedIde is already installed on$environmentId")
272+
if (context.remoteIdeOrchestrator.waitForIdeToBeInstalled(environmentId, selectedIde)) {
273+
context.logger.info("Successfully installed$selectedIdeVersion on$environmentId.")
260274
return selectedIde
275+
}else {
276+
context.ui.showSnackbar(
277+
UUID.randomUUID().toString(),
278+
context.i18n.pnotr("$selectedIde could not be installed"),
279+
context.i18n.pnotr("$selectedIde could not be installed on time. Check the logs for more details"),
280+
context.i18n.ptrl("OK")
281+
)
282+
returnnull
261283
}
284+
}
262285

263-
selectedIde= resolveAvailableIde(environmentId, productCode, buildNumber)?:returnnull
286+
/**
287+
* Resolves the full IDE identifier (e.g., "RR-241.14494.240") based on the build hint.
288+
* Supports: latest_eap, latest_release, latest_installed, or specific build number.
289+
*/
290+
internalsuspendfunresolveIdeIdentifier(
291+
environmentId:String,
292+
productCode:String,
293+
buildNumberHint:String
294+
):String? {
295+
val availableBuilds= context.remoteIdeOrchestrator.getAvailableRemoteTools(environmentId, productCode)
296+
297+
when (buildNumberHint) {
298+
"latest_eap"-> {
299+
// Use IdeFeedManager to find best EAP match from available builds
300+
val bestEap= ideFeedManager.findBestMatch(
301+
productCode,
302+
IdeType.EAP,
303+
availableBuilds
304+
)
264305

265-
// needed otherwise TBX will install it again
266-
if (!installedIdes.contains(selectedIde)) {
267-
context.logger.info("Installing$selectedIde on$environmentId...")
268-
context.remoteIdeOrchestrator.installRemoteTool(environmentId, selectedIde)
306+
returnif (bestEap!=null) {
307+
bestEap.build
308+
}else {
309+
// Fallback to latest available if valid
310+
if (availableBuilds.isEmpty()) {
311+
context.logAndShowError(
312+
CAN_T_HANDLE_URI_TITLE,
313+
"$productCode is not available on$environmentId"
314+
)
315+
returnnull
316+
}
317+
val fallback= availableBuilds.maxBy { it }
318+
context.logger.info("No EAP found for$productCode, falling back to latest available:$fallback")
319+
fallback
320+
}
321+
}
269322

270-
if (context.remoteIdeOrchestrator.waitForIdeToBeInstalled(environmentId, selectedIde)) {
271-
context.logger.info("Successfully installed$selectedIde on$environmentId...")
272-
return selectedIde
273-
}else {
274-
context.ui.showSnackbar(
275-
UUID.randomUUID().toString(),
276-
context.i18n.pnotr("$selectedIde could not be installed"),
277-
context.i18n.pnotr("$selectedIde could not be installed on time. Check the logs for more details"),
278-
context.i18n.ptrl("OK")
323+
"latest_release"-> {
324+
val bestRelease= ideFeedManager.findBestMatch(
325+
productCode,
326+
IdeType.RELEASE,
327+
availableBuilds
279328
)
280-
returnnull
329+
330+
returnif (bestRelease!=null) {
331+
bestRelease.build
332+
}else {
333+
// Fallback to latest available if valid
334+
if (availableBuilds.isEmpty()) {
335+
context.logAndShowError(
336+
CAN_T_HANDLE_URI_TITLE,
337+
"$productCode is not available on$environmentId"
338+
)
339+
returnnull
340+
}
341+
val fallback= availableBuilds.maxBy { it }
342+
context.logger.info("No Release found for$productCode, falling back to latest available:$fallback")
343+
fallback
344+
}
281345
}
282-
}else {
283-
context.logger.info("$selectedIde is already present on$environmentId...")
284-
return selectedIde
285-
}
286-
}
287346

288-
privatesuspendfunresolveAvailableIde(environmentId:String,productCode:String,buildNumber:String):String? {
289-
val availableVersions= context
290-
.remoteIdeOrchestrator
291-
.getAvailableRemoteTools(environmentId, productCode)
347+
"latest_installed"-> {
348+
val installed= context.remoteIdeOrchestrator.getInstalledRemoteTools(environmentId, productCode)
349+
if (installed.isNotEmpty()) {
350+
return installed.maxBy { it }
351+
}
352+
// Fallback to latest available if valid
353+
if (availableBuilds.isEmpty()) {
354+
context.logAndShowError(CAN_T_HANDLE_URI_TITLE,"$productCode is not available on$environmentId")
355+
returnnull
356+
}
357+
val fallback= availableBuilds.maxBy { it }
358+
context.logger.info("No installed IDE found, falling back to latest available:$fallback")
359+
return fallback
360+
}
292361

293-
if (availableVersions.isEmpty()) {
294-
context.logAndShowError(CAN_T_HANDLE_URI_TITLE,"$productCode is not available on$environmentId")
295-
returnnull
296-
}
362+
else-> {
363+
// Specific build number
364+
// Check if exact match exists in available or installed (implicitly handled by install check later)
365+
// Often the input buildNumber might be just "241" or "241.1234", but full build version is in the form of 241.1234.234"
297366

298-
val buildNumberIsNotAvailable= availableVersions.firstOrNull { it.contains(buildNumber) }==null
299-
if (buildNumberIsNotAvailable) {
300-
val selectedIde= availableVersions.maxOf { it }
301-
context.logger.info("$productCode-$buildNumber is not available, we've selected the latest$selectedIde")
302-
return selectedIde
367+
return availableBuilds.filter { it.contains(buildNumberHint) }.maxByOrNull { it }
368+
}
303369
}
304-
return"$productCode-$buildNumber"
305370
}
306371

307372
privatefuninstallJBClient(selectedIde:String,environmentId:String):Job=
@@ -340,7 +405,9 @@ open class CoderProtocolHandler(
340405
withTimeout(waitTime.toJavaDuration()) {
341406
while (!isInstalled) {
342407
delay(5.seconds)
343-
isInstalled= getInstalledRemoteTools(environmentId, ideHint).isNotEmpty()
408+
val installed= getInstalledRemoteTools(environmentId, ideHint)// Hint matching
409+
// Check if *specific* IDE is installed now
410+
isInstalled= installed.contains(ideHint)|| installed.any { it.contains(ideHint) }
344411
}
345412
}
346413
returntrue

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp