Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changes/3.74.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"date" : "2025-06-05",
"version" : "3.74",
"entries" : [ {
"type" : "feature",
"description" : "Agentic coding experience: Amazon Q can now write code and run shell commands on your behalf"
}, {
"type" : "bugfix",
"description" : "Support full Unicode range in inline chat panel on Windows"
} ]
}

This file was deleted.

4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# _3.74_ (2025-06-05)
- **(Feature)** Agentic coding experience: Amazon Q can now write code and run shell commands on your behalf
- **(Bug Fix)** Support full Unicode range in inline chat panel on Windows

# _3.73_ (2025-05-29)
- **(Bug Fix)** /transform: handle InvalidGrantException properly when polling job status

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: Apache-2.0

# Toolkit Version
toolkitVersion=3.74-SNAPSHOT
toolkitVersion=3.75-SNAPSHOT

# Publish Settings
publishToken=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import software.aws.toolkits.jetbrains.services.amazonq.apps.AmazonQAppInitContext
import software.aws.toolkits.jetbrains.services.amazonq.apps.AppConnection
import software.aws.toolkits.jetbrains.services.amazonq.commands.MessageTypeRegistry
import software.aws.toolkits.jetbrains.services.amazonq.isQSupportedInThisVersion
import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.AsyncChatUiListener
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.FlareUiMessage
Expand All @@ -41,6 +42,7 @@
import software.aws.toolkits.jetbrains.services.amazonqDoc.auth.isDocAvailable
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.auth.isFeatureDevAvailable
import software.aws.toolkits.jetbrains.services.codemodernizer.utils.isCodeTransformAvailable
import software.aws.toolkits.resources.message
import java.nio.file.Paths
import java.util.concurrent.CompletableFuture
import javax.swing.JButton
Expand Down Expand Up @@ -102,6 +104,9 @@
webviewContainer.add(JBTextArea("JCEF not supported"))
}
browser.complete(null)
} else if (!isQSupportedInThisVersion()) {
webviewContainer.add(JBTextArea("${message("q.unavailable")}\n ${message("q.unavailable.node")}"))
browser.complete(null)

Check warning on line 109 in plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/toolwindow/AmazonQPanel.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/toolwindow/AmazonQPanel.kt#L108-L109

Added lines #L108 - L109 were not covered by tests
} else {
val loadingPanel = JBLoadingPanel(null, this)
val wrapper = Wrapper()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@
)

val serializedEnrichmentParams = serializer.objectMapper.valueToTree<ObjectNode>(enrichmentParams)
val chatParams: ObjectNode = (node as ObjectNode)
val chatParams: ObjectNode = (node.params as ObjectNode)

Check warning on line 227 in plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/BrowserConnector.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/BrowserConnector.kt#L227

Added line #L227 was not covered by tests
.setAll(serializedEnrichmentParams)

val tabId = requestFromUi.params.tabId
Expand All @@ -235,7 +235,7 @@
val result = AmazonQLspService.executeIfRunning(project) { server ->
encryptionManager = this.encryptionManager

val encryptedParams = EncryptedChatParams(this.encryptionManager.encrypt(chatParams.params), partialResultToken)
val encryptedParams = EncryptedChatParams(this.encryptionManager.encrypt(chatParams), partialResultToken)

Check warning on line 238 in plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/BrowserConnector.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/BrowserConnector.kt#L238

Added line #L238 was not covered by tests
rawEndpoint.request(SEND_CHAT_COMMAND_PROMPT, encryptedParams) as CompletableFuture<String>
} ?: (CompletableFuture.failedFuture(IllegalStateException("LSP Server not running")))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

fun reportMessageClick(command: EditorContextCommand, project: Project) {
if (command == EditorContextCommand.GenerateUnitTests) {
AsyncChatUiListener.notifyPartialMessageUpdate(Gson().toJson(TestCommandMessage()))
AsyncChatUiListener.notifyPartialMessageUpdate(project, Gson().toJson(TestCommandMessage()))

Check warning on line 32 in plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/ActionRegistrar.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/ActionRegistrar.kt#L32

Added line #L32 was not covered by tests
} else {
// new agentic chat route
ApplicationManager.getApplication().executeOnPooledThread {
Expand All @@ -45,7 +45,7 @@
val params = SendToPromptParams(selection = codeSelection, triggerType = TriggerType.CONTEXT_MENU)
uiMessage = FlareUiMessage(command = SEND_TO_PROMPT, params = params)
}
AsyncChatUiListener.notifyPartialMessageUpdate(uiMessage)
AsyncChatUiListener.notifyPartialMessageUpdate(project, uiMessage)

Check warning on line 48 in plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/ActionRegistrar.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/ActionRegistrar.kt#L48

Added line #L48 was not covered by tests
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package software.aws.toolkits.jetbrains.services.cwc.commands.codescan.actions

import com.intellij.openapi.actionSystem.ActionManager
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.DataKey
Expand All @@ -18,7 +19,14 @@
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.TriggerType

class ExplainCodeIssueAction : AnAction(), DumbAware {
override fun getActionUpdateThread() = ActionUpdateThread.BGT

Check warning on line 22 in plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/codescan/actions/ExplainCodeIssueAction.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/codescan/actions/ExplainCodeIssueAction.kt#L22

Added line #L22 was not covered by tests

override fun update(e: AnActionEvent) {
e.presentation.isEnabledAndVisible = e.project != null
}

Check warning on line 26 in plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/codescan/actions/ExplainCodeIssueAction.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/codescan/actions/ExplainCodeIssueAction.kt#L26

Added line #L26 was not covered by tests

override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return
val issueDataKey = DataKey.create<MutableMap<String, String>>("amazonq.codescan.explainissue")
val issueContext = e.getData(issueDataKey) ?: return

Expand Down Expand Up @@ -50,7 +58,7 @@
)

val uiMessage = FlareUiMessage(SEND_TO_PROMPT, params)
AsyncChatUiListener.notifyPartialMessageUpdate(uiMessage)
AsyncChatUiListener.notifyPartialMessageUpdate(project, uiMessage)

Check warning on line 61 in plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/codescan/actions/ExplainCodeIssueAction.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/codescan/actions/ExplainCodeIssueAction.kt#L61

Added line #L61 was not covered by tests
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

package software.aws.toolkits.jetbrains.services.amazonq

import com.intellij.openapi.application.ApplicationInfo
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.BuildNumber
import com.intellij.openapi.util.SystemInfo
import software.amazon.awssdk.services.codewhispererruntime.model.IdeCategory
import software.amazon.awssdk.services.codewhispererruntime.model.OperatingSystem
Expand Down Expand Up @@ -52,3 +54,12 @@
.ideVersion(it.awsVersion)
.build()
}

fun isQSupportedInThisVersion(): Boolean {
val currentBuild = ApplicationInfo.getInstance().build.withoutProductCode()

Check warning on line 59 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/QUtils.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/QUtils.kt#L59

Added line #L59 was not covered by tests

return !(

Check warning on line 61 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/QUtils.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/QUtils.kt#L61

Added line #L61 was not covered by tests
currentBuild.baselineVersion == 242 &&
BuildNumber.fromString("242.22855.74")?.let { currentBuild < it } == true
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -158,18 +158,21 @@
// The filepath sent by the server contains unicode characters which need to be
// decoded for JB file handling APIs to be handle to handle file operations
val fileToOpen = URLDecoder.decode(params.uri, StandardCharsets.UTF_8.name())
ApplicationManager.getApplication().invokeLater {
try {
val virtualFile = VirtualFileManager.getInstance().findFileByUrl(fileToOpen)
?: throw IllegalArgumentException("Cannot find file: $fileToOpen")

FileEditorManager.getInstance(project).openFile(virtualFile, true)
} catch (e: Exception) {
LOG.warn { "Failed to show document: $fileToOpen" }
}
}
return CompletableFuture.supplyAsync(

Check warning on line 161 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L161

Added line #L161 was not covered by tests
{
try {

Check warning on line 163 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L163

Added line #L163 was not covered by tests
val virtualFile = VirtualFileManager.getInstance().refreshAndFindFileByUrl(fileToOpen)
?: throw IllegalArgumentException("Cannot find file: $fileToOpen")

Check warning on line 165 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L165

Added line #L165 was not covered by tests

return CompletableFuture.completedFuture(ShowDocumentResult(true))
FileEditorManager.getInstance(project).openFile(virtualFile, true)
ShowDocumentResult(true)
} catch (e: Exception) {
LOG.warn { "Failed to show document: $fileToOpen" }
ShowDocumentResult(false)
}

Check warning on line 172 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L167-L172

Added lines #L167 - L172 were not covered by tests
},
ApplicationManager.getApplication()::invokeLater

Check warning on line 174 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L174

Added line #L174 was not covered by tests
)
} catch (e: Exception) {
LOG.warn { "Error showing document" }
return CompletableFuture.completedFuture(ShowDocumentResult(false))
Expand Down Expand Up @@ -312,6 +315,7 @@

override fun sendChatUpdate(params: LSPAny): CompletableFuture<Unit> {
AsyncChatUiListener.notifyPartialMessageUpdate(
project,

Check warning on line 318 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageClientImpl.kt#L318

Added line #L318 was not covered by tests
FlareUiMessage(
command = CHAT_SEND_UPDATE,
params = params,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,12 @@
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.WorkspaceFolderUtil.createWorkspaceFolders
import software.aws.toolkits.jetbrains.services.amazonq.lsp.workspace.WorkspaceServiceHandler
import software.aws.toolkits.jetbrains.services.amazonq.profile.QDefaultServiceConfig
import software.aws.toolkits.jetbrains.services.cwc.controller.chat.telemetry.getStartUrl
import software.aws.toolkits.jetbrains.services.telemetry.ClientMetadata
import software.aws.toolkits.jetbrains.settings.LspSettings
import software.aws.toolkits.jetbrains.utils.notifyInfo
import software.aws.toolkits.resources.message
import software.aws.toolkits.telemetry.Telemetry
import java.io.IOException
import java.io.OutputStreamWriter
import java.io.PipedInputStream
Expand Down Expand Up @@ -528,20 +530,36 @@
* may fail to start in that case. The caller should handle potential runtime initialization failures.
*/
private fun getNodeRuntimePath(nodePath: Path): Path {
val resolveNodeMetric = { isBundled: Boolean, success: Boolean ->
Telemetry.languageserver.setup.use {
it.id("q")
it.metadata("languageServerSetupStage", "resolveNode")
it.metadata("credentialStartUrl", getStartUrl(project))
it.setAttribute("isBundledNode", isBundled)
it.success(success)
}

Check warning on line 540 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt#L533-L540

Added lines #L533 - L540 were not covered by tests
}

if (Files.exists(nodePath) && Files.isExecutable(nodePath)) {
resolveNodeMetric(true, true)

Check warning on line 544 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt#L544

Added line #L544 was not covered by tests
return nodePath
}

// use alternative node runtime if it is not found
LOG.warn { "Node Runtime download failed. Fallback to user specified node runtime " }
// attempt to use user provided node runtime path
val nodeRuntime = LspSettings.getInstance().getNodeRuntimePath()
if (!nodeRuntime.isNullOrEmpty()) {
LOG.info { "Using node from $nodeRuntime " }

resolveNodeMetric(false, true)

Check warning on line 555 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt#L555

Added line #L555 was not covered by tests
return Path.of(nodeRuntime)
} else {
val localNode = locateNodeCommand()
if (localNode != null) {
LOG.info { "Using node from ${localNode.toAbsolutePath()}" }

resolveNodeMetric(false, true)

Check warning on line 562 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt#L562

Added line #L562 was not covered by tests
return localNode
}
notifyInfo(
Expand All @@ -559,6 +577,8 @@
) { _, notification -> notification.expire() }
)
)

resolveNodeMetric(false, false)

Check warning on line 581 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt#L581

Added line #L581 was not covered by tests
return nodePath
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
import software.aws.toolkits.core.utils.info
import software.aws.toolkits.core.utils.warn
import software.aws.toolkits.jetbrains.core.saveFileFromUrl
import software.aws.toolkits.jetbrains.services.cwc.controller.chat.telemetry.getStartUrl
import software.aws.toolkits.resources.AwsCoreBundle
import software.aws.toolkits.telemetry.LanguageServerSetupStage
import software.aws.toolkits.telemetry.Telemetry
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
Expand Down Expand Up @@ -106,33 +109,33 @@
}

suspend fun tryDownloadLspArtifacts(project: Project, targetVersion: Version, target: VersionTarget): Path? {
val temporaryDownloadPath = Files.createTempDirectory("lsp-dl")
val downloadPath = lspArtifactsPath.resolve(targetVersion.serverVersion.toString())
val destinationPath = lspArtifactsPath.resolve(targetVersion.serverVersion.toString())

Check warning on line 112 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt#L112

Added line #L112 was not covered by tests

while (currentAttempt.get() < maxDownloadAttempts) {
currentAttempt.incrementAndGet()
logger.info { "Attempt ${currentAttempt.get()} of $maxDownloadAttempts to download LSP artifacts" }
val temporaryDownloadPath = Files.createTempDirectory("lsp-dl")

Check warning on line 117 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt#L117

Added line #L117 was not covered by tests

try {
return withBackgroundProgress(
project,
AwsCoreBundle.message("amazonqFeatureDev.placeholder.downloading_and_extracting_lsp_artifacts"),
cancellable = true
) {
if (downloadLspArtifacts(temporaryDownloadPath, target) && !target.contents.isNullOrEmpty()) {
moveFilesFromSourceToDestination(temporaryDownloadPath, downloadPath)
if (downloadLspArtifacts(project, temporaryDownloadPath, target) && !target.contents.isNullOrEmpty()) {
moveFilesFromSourceToDestination(temporaryDownloadPath, destinationPath)

Check warning on line 126 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt#L126

Added line #L126 was not covered by tests
target.contents
.mapNotNull { it.filename }
.forEach { filename -> extractZipFile(downloadPath.resolve(filename), downloadPath) }
logger.info { "Successfully downloaded and moved LSP artifacts to $downloadPath" }
.forEach { filename -> extractZipFile(destinationPath.resolve(filename), destinationPath) }
logger.info { "Successfully downloaded and moved LSP artifacts to $destinationPath" }

Check warning on line 130 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt#L129-L130

Added lines #L129 - L130 were not covered by tests

val thirdPartyLicenses = targetVersion.thirdPartyLicenses
logger.info {
"Installing Amazon Q Language Server v${targetVersion.serverVersion} to: $downloadPath. " +
"Installing Amazon Q Language Server v${targetVersion.serverVersion} to: $destinationPath. " +

Check warning on line 134 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt#L134

Added line #L134 was not covered by tests
if (thirdPartyLicenses == null) "" else "Attribution notice can be found at $thirdPartyLicenses"
}

return@withBackgroundProgress downloadPath
return@withBackgroundProgress destinationPath

Check warning on line 138 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt#L138

Added line #L138 was not covered by tests
}

return@withBackgroundProgress null
Expand All @@ -146,15 +149,15 @@
else -> { logger.error(e) { "Failed to download/move LSP artifacts on attempt ${currentAttempt.get()}" } }
}
temporaryDownloadPath.toFile().deleteRecursively()
downloadPath.toFile().deleteRecursively()
destinationPath.toFile().deleteRecursively()

Check warning on line 152 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt#L152

Added line #L152 was not covered by tests
}
}
logger.error { "Failed to download LSP artifacts after $maxDownloadAttempts attempts" }
return null
}

@VisibleForTesting
internal fun downloadLspArtifacts(downloadPath: Path, target: VersionTarget?): Boolean {
internal fun downloadLspArtifacts(project: Project, downloadPath: Path, target: VersionTarget?): Boolean {
if (target == null || target.contents.isNullOrEmpty()) {
logger.warn { "No target contents available for download" }
return false
Expand All @@ -171,7 +174,7 @@
logger.warn { "No hash available for ${content.filename}" }
return@forEach
}
downloadAndValidateFile(content.url, filePath, contentHash)
downloadAndValidateFile(project, content.url, filePath, contentHash)

Check warning on line 177 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt#L177

Added line #L177 was not covered by tests
}
validateDownloadedFiles(downloadPath, target.contents)
} catch (e: Exception) {
Expand All @@ -182,18 +185,46 @@
return true
}

private fun downloadAndValidateFile(url: String, filePath: Path, expectedHash: String) {
private fun downloadAndValidateFile(project: Project, url: String, filePath: Path, expectedHash: String) {
val recordDownload = { runnable: () -> Unit ->
Telemetry.languageserver.setup.use { telemetry ->
telemetry.id("q")
telemetry.languageServerSetupStage(LanguageServerSetupStage.GetServer)
telemetry.metadata("credentialStartUrl", getStartUrl(project))
telemetry.success(true)

Check warning on line 194 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt#L189-L194

Added lines #L189 - L194 were not covered by tests

try {
runnable()
} catch (t: Throwable) {
telemetry.success(false)
telemetry.recordException(t)
}
}

Check warning on line 202 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt#L196-L202

Added lines #L196 - L202 were not covered by tests
}

try {
if (!filePath.exists()) {
logger.info { "Downloading file: ${filePath.fileName}" }
saveFileFromUrl(url, filePath, ProgressManager.getInstance().progressIndicator)
recordDownload { saveFileFromUrl(url, filePath, ProgressManager.getInstance().progressIndicator) }

Check warning on line 208 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt#L208

Added line #L208 was not covered by tests
}
if (!validateFileHash(filePath, expectedHash)) {
logger.warn { "Hash mismatch for ${filePath.fileName}, re-downloading" }
filePath.deleteIfExists()
saveFileFromUrl(url, filePath)
if (!validateFileHash(filePath, expectedHash)) {
throw LspException("Hash mismatch after re-download for ${filePath.fileName}", LspException.ErrorCode.HASH_MISMATCH)
recordDownload { saveFileFromUrl(url, filePath) }

Check warning on line 213 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt#L213

Added line #L213 was not covered by tests

Telemetry.languageserver.setup.use {
it.id("q")
it.languageServerSetupStage(LanguageServerSetupStage.Validate)
it.metadata("credentialStartUrl", getStartUrl(project))
it.success(true)

Check warning on line 219 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt#L215-L219

Added lines #L215 - L219 were not covered by tests

if (!validateFileHash(filePath, expectedHash)) {
it.success(false)

Check warning on line 222 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt#L222

Added line #L222 was not covered by tests

val exception = LspException("Hash mismatch after re-download for ${filePath.fileName}", LspException.ErrorCode.HASH_MISMATCH)
it.recordException(exception)
throw exception

Check warning on line 226 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt#L224-L226

Added lines #L224 - L226 were not covered by tests
}
}
}
} catch (e: Exception) {
Expand Down
Loading
Loading