Skip to content

Commit b97bcc0

Browse files
authored
Merge branch 'main' into rli/fix-prerelease
2 parents e14eddd + c8e4ee4 commit b97bcc0

File tree

15 files changed

+390
-106
lines changed

15 files changed

+390
-106
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type" : "bugfix",
3+
"description" : "Amazon Q /review: Unable to navigate to code location when selecting issues"
4+
}

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeTestChatApp.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ class CodeTestChatApp(private val scope: CoroutineScope) : AmazonQApp {
3838
"tab-was-removed" to IncomingCodeTestMessage.TabRemoved::class,
3939
"start-test-gen" to IncomingCodeTestMessage.StartTestGen::class,
4040
"response-body-link-click" to IncomingCodeTestMessage.ClickedLink::class,
41-
"button-click" to IncomingCodeTestMessage.ButtonClicked::class
41+
"button-click" to IncomingCodeTestMessage.ButtonClicked::class,
42+
"auth-follow-up-was-clicked" to IncomingCodeTestMessage.AuthFollowUpWasClicked::class
4243
)
4344

4445
scope.launch {
@@ -79,6 +80,7 @@ class CodeTestChatApp(private val scope: CoroutineScope) : AmazonQApp {
7980
is IncomingCodeTestMessage.StartTestGen -> inboundAppMessagesHandler.processStartTestGen(message)
8081
is IncomingCodeTestMessage.ClickedLink -> inboundAppMessagesHandler.processLinkClick(message)
8182
is IncomingCodeTestMessage.ButtonClicked -> inboundAppMessagesHandler.processButtonClickedMessage(message)
83+
is IncomingCodeTestMessage.AuthFollowUpWasClicked -> inboundAppMessagesHandler.processAuthFollowUpClick(message)
8284
}
8385
}
8486

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/InboundAppMessagesHandler.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,6 @@ interface InboundAppMessagesHandler {
2121
suspend fun processTabRemovedMessage(message: IncomingCodeTestMessage.TabRemoved)
2222

2323
suspend fun processButtonClickedMessage(message: IncomingCodeTestMessage.ButtonClicked)
24+
25+
suspend fun processAuthFollowUpClick(message: IncomingCodeTestMessage.AuthFollowUpWasClicked)
2426
}

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatController.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,14 @@ class CodeTestChatController(
954954
}
955955
}
956956

957+
override suspend fun processAuthFollowUpClick(message: IncomingCodeTestMessage.AuthFollowUpWasClicked) {
958+
codeTestChatHelper.sendUpdatePromptProgress(message.tabId, null)
959+
authController.handleAuth(context.project, message.authType)
960+
codeTestChatHelper.sendAuthenticationInProgressMessage(message.tabId) // show user that authentication is in progress
961+
codeTestChatHelper.sendChatInputEnabledMessage(false) // disable the input field while authentication is in progress
962+
sessionCleanUp(codeTestChatHelper.getActiveSession().tabId)
963+
}
964+
957965
private suspend fun updateBuildAndExecuteProgressCard(
958966
currentStatus: BuildAndExecuteProgressStatus,
959967
messageId: String?,
@@ -1210,6 +1218,17 @@ class CodeTestChatController(
12101218
* */
12111219
private suspend fun handleChat(tabId: String, message: String) {
12121220
val session = codeTestChatHelper.getActiveSession()
1221+
session.projectRoot
1222+
val credentialState = authController.getAuthNeededStates(context.project).amazonQ
1223+
if (credentialState != null) {
1224+
messenger.sendAuthNeededException(
1225+
tabId = tabId,
1226+
triggerId = UUID.randomUUID().toString(),
1227+
credentialState = credentialState,
1228+
)
1229+
session.isAuthenticating = true
1230+
return
1231+
}
12131232
LOG.debug {
12141233
"$FEATURE_NAME: " +
12151234
"Processing message: $message " +

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatHelper.kt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package software.aws.toolkits.jetbrains.services.amazonqCodeTest.controller
55

66
import software.aws.toolkits.jetbrains.services.amazonq.messages.MessagePublisher
7+
import software.aws.toolkits.jetbrains.services.amazonqCodeTest.messages.ChatInputEnabledMessage
78
import software.aws.toolkits.jetbrains.services.amazonqCodeTest.messages.CodeTestAddAnswerMessage
89
import software.aws.toolkits.jetbrains.services.amazonqCodeTest.messages.CodeTestChatMessage
910
import software.aws.toolkits.jetbrains.services.amazonqCodeTest.messages.CodeTestChatMessageContent
@@ -15,6 +16,8 @@ import software.aws.toolkits.jetbrains.services.amazonqCodeTest.messages.UpdateP
1516
import software.aws.toolkits.jetbrains.services.amazonqCodeTest.session.Session
1617
import software.aws.toolkits.jetbrains.services.amazonqCodeTest.storage.ChatSessionStorage
1718
import software.aws.toolkits.jetbrains.services.cwc.messages.ChatMessageType
19+
import software.aws.toolkits.jetbrains.services.cwc.messages.FollowUp
20+
import software.aws.toolkits.resources.message
1821
import java.util.UUID
1922

2023
class CodeTestChatHelper(
@@ -153,4 +156,27 @@ class CodeTestChatHelper(
153156
)
154157
)
155158
}
159+
160+
suspend fun sendChatInputEnabledMessage(isEnabled: Boolean) {
161+
if (isInvalidSession()) return
162+
messagePublisher.publish(ChatInputEnabledMessage(activeCodeTestTabId as String, enabled = isEnabled))
163+
}
164+
165+
suspend fun sendAuthenticationInProgressMessage(
166+
tabId: String,
167+
messageId: String? = null,
168+
followUp: List<FollowUp>? = null,
169+
canBeVoted: Boolean? = false,
170+
) {
171+
val chatMessage =
172+
CodeTestChatMessage(
173+
tabId = tabId,
174+
messageId = messageId ?: UUID.randomUUID().toString(),
175+
messageType = ChatMessageType.Answer,
176+
message = message("amazonqFeatureDev.follow_instructions_for_authentication"),
177+
followUps = followUp,
178+
canBeVoted = canBeVoted ?: false,
179+
)
180+
messagePublisher.publish(chatMessage)
181+
}
156182
}

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/messages/CodeTestMessage.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ sealed interface IncomingCodeTestMessage : CodeTestBaseMessage {
9494
@JsonProperty("tabID") val tabId: String,
9595
@JsonProperty("actionID") val actionID: String,
9696
) : IncomingCodeTestMessage
97+
98+
data class AuthFollowUpWasClicked(
99+
@JsonProperty("tabID") val tabId: String,
100+
val authType: AuthFollowUpType,
101+
) : IncomingCodeTestMessage
97102
}
98103

99104
data class UpdatePlaceholderMessage(

plugins/amazonq/codewhisperer/jetbrains-community/src/migration/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererModelConfigurator.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ interface CodeWhispererModelConfigurator {
1818

1919
fun switchCustomization(project: Project, newCustomization: CodeWhispererCustomization?)
2020

21+
fun switchCustomization(project: Project, newCustomization: CodeWhispererCustomization?, isOverride: Boolean)
22+
2123
/**
2224
* This method is only used for invalidate a stale customization which was previously active but was removed, it will remove all usage of this customization
2325
* but not limited to the specific connection.

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanResultsView.kt

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import com.intellij.icons.AllIcons
77
import com.intellij.openapi.actionSystem.ActionGroup
88
import com.intellij.openapi.actionSystem.ActionManager
99
import com.intellij.openapi.actionSystem.ActionToolbar
10+
import com.intellij.openapi.application.runInEdt
11+
import com.intellij.openapi.fileEditor.FileEditorManager
12+
import com.intellij.openapi.fileEditor.OpenFileDescriptor
1013
import com.intellij.openapi.project.Project
1114
import com.intellij.openapi.vfs.VirtualFile
1215
import com.intellij.ui.AnimatedIcon
13-
import com.intellij.ui.ClickListener
1416
import com.intellij.ui.OnePixelSplitter
1517
import com.intellij.ui.ScrollPaneFactory
1618
import com.intellij.ui.border.CustomLineBorder
@@ -19,7 +21,8 @@ import com.intellij.ui.treeStructure.Tree
1921
import com.intellij.util.ui.JBUI
2022
import icons.AwsIcons
2123
import kotlinx.coroutines.CoroutineScope
22-
import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.listeners.CodeWhispererCodeScanTreeMouseListener
24+
import software.aws.toolkits.core.utils.error
25+
import software.aws.toolkits.core.utils.getLogger
2326
import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.utils.IssueGroupingStrategy
2427
import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.utils.IssueSeverity
2528
import software.aws.toolkits.jetbrains.services.codewhisperer.layout.CodeWhispererLayoutConfig
@@ -31,7 +34,6 @@ import java.awt.BorderLayout
3134
import java.awt.Component
3235
import java.awt.GridBagConstraints
3336
import java.awt.GridBagLayout
34-
import java.awt.event.MouseEvent
3537
import java.time.Instant
3638
import java.time.format.DateTimeFormatter
3739
import javax.swing.BorderFactory
@@ -52,15 +54,18 @@ internal class CodeWhispererCodeScanResultsView(private val project: Project, pr
5254

5355
private val codeScanTree: Tree = Tree().apply {
5456
isRootVisible = false
55-
CodeWhispererCodeScanTreeMouseListener(project).installOn(this)
56-
object : ClickListener() {
57-
override fun onClick(event: MouseEvent, clickCount: Int): Boolean {
58-
val issueNode = (event.source as Tree).selectionPath?.lastPathComponent as? DefaultMutableTreeNode
59-
val issue = issueNode?.userObject as? CodeWhispererCodeScanIssue ?: return false
60-
showIssueDetails(issue, defaultScope)
61-
return true
57+
58+
addTreeSelectionListener { e ->
59+
val issueNode = e.path.lastPathComponent as? DefaultMutableTreeNode
60+
val issue = issueNode?.userObject as? CodeWhispererCodeScanIssue ?: return@addTreeSelectionListener
61+
62+
showIssueDetails(issue, defaultScope)
63+
64+
synchronized(issueNode) {
65+
if (issueNode.userObject !is CodeWhispererCodeScanIssue) return@addTreeSelectionListener
66+
navigateToIssue(issueNode.userObject as CodeWhispererCodeScanIssue)
6267
}
63-
}.installOn(this)
68+
}
6469
cellRenderer = ColoredTreeCellRenderer()
6570
}
6671

@@ -390,8 +395,30 @@ internal class CodeWhispererCodeScanResultsView(private val project: Project, pr
390395
}
391396
}
392397

398+
private fun navigateToIssue(codeScanIssue: CodeWhispererCodeScanIssue) {
399+
val textRange = codeScanIssue.textRange ?: return
400+
val startOffset = textRange.startOffset
401+
402+
if (codeScanIssue.isInvalid) return
403+
404+
runInEdt {
405+
val editor = FileEditorManager.getInstance(project).openTextEditor(
406+
OpenFileDescriptor(project, codeScanIssue.file, startOffset),
407+
false
408+
)
409+
if (editor == null) {
410+
LOG.error { "Cannot fetch editor for the file ${codeScanIssue.file.path}" }
411+
return@runInEdt
412+
}
413+
if (codeScanIssue.rangeHighlighter == null) {
414+
codeScanIssue.rangeHighlighter = codeScanIssue.addRangeHighlighter(editor.markupModel)
415+
}
416+
}
417+
}
418+
393419
private companion object {
394420
const val ACTION_PLACE = "CodeScanResultsPanel"
395421
const val CODE_SCAN_SPLITTER_PROPORTION_KEY = "CODE_SCAN_SPLITTER_PROPORTION"
422+
private val LOG = getLogger<CodeWhispererCodeScanResultsView>()
396423
}
397424
}

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/listeners/CodeWhispererCodeScanTreeMouseListener.kt

Lines changed: 0 additions & 53 deletions
This file was deleted.

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestSessionConfig.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.noFileOpe
2929
import software.aws.toolkits.jetbrains.services.codewhisperer.language.CodeWhispererProgrammingLanguage
3030
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererUnknownLanguage
3131
import software.aws.toolkits.jetbrains.services.codewhisperer.language.programmingLanguage
32+
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants
3233
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.CODE_SCAN_CREATE_PAYLOAD_TIMEOUT_IN_SECONDS
3334
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.DEFAULT_CODE_SCAN_TIMEOUT_IN_SECONDS
3435
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.DEFAULT_PAYLOAD_LIMIT_IN_BYTES
@@ -217,7 +218,7 @@ class CodeTestSessionConfig(
217218
for (module in project.modules) {
218219
val changeListManager = ChangeListManager.getInstance(module.project)
219220
module.guessModuleDir()?.let { moduleDir ->
220-
val gitIgnoreFilteringUtil = GitIgnoreFilteringUtil(moduleDir)
221+
val gitIgnoreFilteringUtil = GitIgnoreFilteringUtil(moduleDir, CodeWhispererConstants.FeatureName.TEST_GENERATION)
221222
stack.push(moduleDir)
222223
while (stack.isNotEmpty()) {
223224
val current = stack.pop()

0 commit comments

Comments
 (0)