Skip to content

Commit

Permalink
Merge main into feature/q-mega
Browse files Browse the repository at this point in the history
  • Loading branch information
aws-toolkit-automation authored Nov 20, 2024
2 parents 5d9b765 + 8fe9d5b commit 71c98ed
Show file tree
Hide file tree
Showing 27 changed files with 1,414 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,35 @@ import software.aws.toolkits.core.utils.error
import software.aws.toolkits.core.utils.exists
import software.aws.toolkits.core.utils.getLogger
import software.aws.toolkits.core.utils.info
import software.aws.toolkits.jetbrains.core.coroutines.EDT
import software.aws.toolkits.jetbrains.core.coroutines.getCoroutineBgContext
import software.aws.toolkits.jetbrains.core.coroutines.projectCoroutineScope
import software.aws.toolkits.jetbrains.core.credentials.sso.bearer.NoTokenInitializedException
import software.aws.toolkits.jetbrains.services.amazonq.CODE_TRANSFORM_TROUBLESHOOT_DOC_DOWNLOAD_ERROR_OVERVIEW
import software.aws.toolkits.jetbrains.services.amazonq.CODE_TRANSFORM_TROUBLESHOOT_DOC_DOWNLOAD_EXPIRED
import software.aws.toolkits.jetbrains.services.codemodernizer.client.GumbyClient
import software.aws.toolkits.jetbrains.services.codemodernizer.commands.CodeTransformMessageListener
import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildStartNewTransformFollowup
import software.aws.toolkits.jetbrains.services.codemodernizer.constants.createViewDiffButton
import software.aws.toolkits.jetbrains.services.codemodernizer.constants.getDownloadedArtifactTextFromType
import software.aws.toolkits.jetbrains.services.codemodernizer.constants.viewSummaryButton
import software.aws.toolkits.jetbrains.services.codemodernizer.controller.CodeTransformChatHelper
import software.aws.toolkits.jetbrains.services.codemodernizer.messages.CodeTransformChatMessageContent
import software.aws.toolkits.jetbrains.services.codemodernizer.messages.CodeTransformChatMessageType
import software.aws.toolkits.jetbrains.services.codemodernizer.model.CodeModernizerArtifact
import software.aws.toolkits.jetbrains.services.codemodernizer.model.CodeTransformFailureBuildLog
import software.aws.toolkits.jetbrains.services.codemodernizer.model.CodeTransformHilDownloadArtifact
import software.aws.toolkits.jetbrains.services.codemodernizer.model.DownloadArtifactResult
import software.aws.toolkits.jetbrains.services.codemodernizer.model.DownloadFailureReason
import software.aws.toolkits.jetbrains.services.codemodernizer.model.JobId
import software.aws.toolkits.jetbrains.services.codemodernizer.model.ParseZipFailureReason
import software.aws.toolkits.jetbrains.services.codemodernizer.model.PatchInfo
import software.aws.toolkits.jetbrains.services.codemodernizer.model.UnzipFailureReason
import software.aws.toolkits.jetbrains.services.codemodernizer.state.CodeModernizerSessionState
import software.aws.toolkits.jetbrains.services.codemodernizer.utils.getPathToHilArtifactDir
import software.aws.toolkits.jetbrains.services.codemodernizer.utils.isValidCodeTransformConnection
import software.aws.toolkits.jetbrains.services.codemodernizer.utils.openTroubleshootingGuideNotificationAction
import software.aws.toolkits.jetbrains.utils.notifyInfo
import software.aws.toolkits.jetbrains.utils.notifyStickyInfo
import software.aws.toolkits.jetbrains.utils.notifyStickyWarn
import software.aws.toolkits.resources.message
Expand All @@ -57,20 +66,44 @@ import java.util.concurrent.atomic.AtomicBoolean
const val DOWNLOAD_PROXY_WILDCARD_ERROR: String = "Dangling meta character '*' near index 0"
const val DOWNLOAD_SSL_HANDSHAKE_ERROR: String = "Unable to execute HTTP request: javax.net.ssl.SSLHandshakeException"
const val INVALID_ARTIFACT_ERROR: String = "Invalid artifact"

class ArtifactHandler(private val project: Project, private val clientAdaptor: GumbyClient) {
val patchDescriptions = mapOf(
"Prepare minimal upgrade to Java 17" to "This diff patch covers the set of upgrades for Springboot, JUnit, and PowerMockito frameworks.",
"Popular Enterprise Specifications and Application Frameworks upgrade" to "This diff patch covers the set of upgrades for Jakarta EE 10, Hibernate 6.2, " +
"and Micronaut 3.",
"HTTP Client Utilities, Apache Commons Utilities, and Web Frameworks" to "This diff patch covers the set of upgrades for Apache HTTP Client 5, Apache " +
"Commons utilities (Collections, IO, Lang, Math), Struts 6.0.",
"Testing Tools and Frameworks upgrade" to "This diff patch covers the set of upgrades for ArchUnit, Mockito, TestContainers, Cucumber, and additionally, " +
"Jenkins plugins and the Maven Wrapper.",
"Miscellaneous Processing Documentation upgrade" to "This diff patch covers a diverse set of upgrades spanning ORMs, XML processing, API documentation, " +
"and more.",
"Deprecated API replacement and dependency upgrades" to "This diff patch replaces deprecated APIs and makes additional dependency version upgrades."
)

class ArtifactHandler(
private val project: Project,
private val clientAdaptor: GumbyClient,
private val codeTransformChatHelper: CodeTransformChatHelper? = null,
) {
private val telemetry = CodeTransformTelemetryManager.getInstance(project)
private val downloadedArtifacts = mutableMapOf<JobId, Path>()
private val downloadedSummaries = mutableMapOf<JobId, TransformationSummary>()
private val downloadedBuildLogPath = mutableMapOf<JobId, Path>()
private var isCurrentlyDownloading = AtomicBoolean(false)
private var totalPatchFiles: Int = 0
private var sharedPatchIndex: Int = 0

internal suspend fun displayDiff(job: JobId, source: CodeTransformVCSViewerSrcComponents) {
if (isCurrentlyDownloading.get()) return
when (val result = downloadArtifact(job, TransformationDownloadArtifactType.CLIENT_INSTRUCTIONS)) {
is DownloadArtifactResult.Success -> {
if (result.artifact !is CodeModernizerArtifact) return notifyUnableToApplyPatch("")
displayDiffUsingPatch(result.artifact.patch, job, source)
totalPatchFiles = result.artifact.patches.size
if (result.artifact.description == null) {
displayDiffUsingPatch(result.artifact.patches.first(), totalPatchFiles, null, job, source)
} else {
val diffDescription = result.artifact.description[getCurrentPatchIndex()]
displayDiffUsingPatch(result.artifact.patches[getCurrentPatchIndex()], totalPatchFiles, diffDescription, job, source)
}
}
is DownloadArtifactResult.ParseZipFailure -> notifyUnableToApplyPatch(result.failureReason.errorMessage)
is DownloadArtifactResult.UnzipFailure -> notifyUnableToApplyPatch(result.failureReason.errorMessage)
Expand Down Expand Up @@ -246,8 +279,14 @@ class ArtifactHandler(private val project: Project, private val clientAdaptor: G
/**
* Opens the built-in patch dialog to display the diff and allowing users to apply the changes locally.
*/
internal fun displayDiffUsingPatch(patchFile: VirtualFile, jobId: JobId, source: CodeTransformVCSViewerSrcComponents) {
runInEdt {
internal suspend fun displayDiffUsingPatch(
patchFile: VirtualFile,
totalPatchFiles: Int,
diffDescription: PatchInfo?,
jobId: JobId,
source: CodeTransformVCSViewerSrcComponents,
) {
withContext(EDT) {
val dialog = ApplyPatchDifferentiatedDialog(
project,
ApplyPatchDefaultExecutor(project),
Expand All @@ -256,7 +295,14 @@ class ArtifactHandler(private val project: Project, private val clientAdaptor: G
patchFile,
null,
ChangeListManager.getInstance(project)
.addChangeList(message("codemodernizer.patch.name"), ""),
.addChangeList(
if (diffDescription != null) {
"${diffDescription.name} (${if (diffDescription.isSuccessful) "Success" else "Failure"})"
} else {
patchFile.name
},
""
),
null,
null,
null,
Expand All @@ -265,7 +311,44 @@ class ArtifactHandler(private val project: Project, private val clientAdaptor: G
dialog.isModal = true

if (dialog.showAndGet()) {
telemetry.submitSelection("Submit-${diffDescription?.name}")
telemetry.viewArtifact(CodeTransformArtifactType.ClientInstructions, jobId, "Submit", source)
if (diffDescription == null) {
val resultContent = CodeTransformChatMessageContent(
type = CodeTransformChatMessageType.PendingAnswer,
message = message("codemodernizer.chat.message.changes_applied"),
)
codeTransformChatHelper?.updateLastPendingMessage(resultContent)
codeTransformChatHelper?.addNewMessage(buildStartNewTransformFollowup())
} else {
if (getCurrentPatchIndex() < totalPatchFiles) {
val message = "I applied the changes in diff patch ${getCurrentPatchIndex() + 1} of $totalPatchFiles. " +
"${patchDescriptions[diffDescription.name]}"
val notificationMessage = "Amazon Q applied the changes in diff patch ${getCurrentPatchIndex() + 1} of $totalPatchFiles " +
"to your project."
val notificationTitle = "Diff patch ${getCurrentPatchIndex() + 1} of $totalPatchFiles applied"
setCurrentPatchIndex(getCurrentPatchIndex() + 1)
notifyInfo(notificationTitle, notificationMessage, project)
if (getCurrentPatchIndex() == totalPatchFiles) {
codeTransformChatHelper?.updateLastPendingMessage(
CodeTransformChatMessageContent(type = CodeTransformChatMessageType.PendingAnswer, message = message)
)
} else {
codeTransformChatHelper?.updateLastPendingMessage(
CodeTransformChatMessageContent(
type = CodeTransformChatMessageType.PendingAnswer,
message = message,
buttons = listOf(
createViewDiffButton("View diff ${getCurrentPatchIndex() + 1}/$totalPatchFiles"),
viewSummaryButton
)
)
)
}
} else {
codeTransformChatHelper?.addNewMessage(buildStartNewTransformFollowup())
}
}
} else {
telemetry.viewArtifact(CodeTransformArtifactType.ClientInstructions, jobId, "Cancel", source)
}
Expand Down Expand Up @@ -388,6 +471,12 @@ class ArtifactHandler(private val project: Project, private val clientAdaptor: G

fun getSummary(job: JobId) = downloadedSummaries[job]

private fun getCurrentPatchIndex() = sharedPatchIndex

private fun setCurrentPatchIndex(index: Int) {
sharedPatchIndex = index
}

private fun showSummaryFromFile(summaryFile: File) {
val summaryMarkdownVirtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(summaryFile)
if (summaryMarkdownVirtualFile != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -576,12 +576,6 @@ class CodeModernizerManager(private val project: Project) : PersistentStateCompo
resumeJob(session, lastJobId, currentJobResult)
}

private fun displayDiffNotificationAction(jobId: JobId): NotificationAction = NotificationAction.createSimple(
message("codemodernizer.notification.info.modernize_complete.view_diff")
) {
artifactHandler.displayDiffAction(jobId, CodeTransformVCSViewerSrcComponents.ToastNotification)
}

private fun displaySummaryNotificationAction(jobId: JobId) =
NotificationAction.createSimple(message("codemodernizer.notification.info.modernize_complete.view_summary")) {
artifactHandler.showTransformationSummary(jobId)
Expand Down Expand Up @@ -638,7 +632,7 @@ class CodeModernizerManager(private val project: Project) : PersistentStateCompo
message("codemodernizer.notification.info.modernize_partial_complete.title"),
message("codemodernizer.notification.info.modernize_partial_complete.content", result.targetJavaVersion.description),
project,
listOf(displayDiffNotificationAction(result.jobId), displaySummaryNotificationAction(result.jobId), displayFeedbackNotificationAction()),
listOf(displaySummaryNotificationAction(result.jobId), displayFeedbackNotificationAction()),
)
jobId = result.jobId
}
Expand All @@ -648,7 +642,7 @@ class CodeModernizerManager(private val project: Project) : PersistentStateCompo
message("codemodernizer.notification.info.modernize_complete.title"),
message("codemodernizer.notification.info.modernize_complete.content"),

Check warning on line 643 in plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/CodeModernizerManager.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Usage of redundant or deprecated syntax or deprecated symbols

'message(String, vararg Any): String' is deprecated. Use extension-specific localization bundle instead
project,
listOf(displayDiffNotificationAction(result.jobId), displaySummaryNotificationAction(result.jobId)),
listOf(displaySummaryNotificationAction(result.jobId)),
)
jobId = result.jobId
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ import java.util.concurrent.atomic.AtomicBoolean
import javax.net.ssl.SSLHandshakeException

const val MAX_ZIP_SIZE = 2000000000 // 2GB
const val EXPLAINABILITY_V1 = "EXPLAINABILITY_V1"
const val SELECTIVE_TRANSFORMATION_V1 = "SELECTIVE_TRANSFORMATION_V1"

// constants for handling SDKClientException
const val CONNECTION_REFUSED_ERROR: String = "Connection refused"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ private enum class CodeTransformMessageTypes(val type: String) {
CodeTransformStop("codetransform-stop"),
CodeTransformCancel("codetransform-cancel"),
CodeTransformConfirmSkipTests("codetransform-confirm-skip-tests"),
CodeTransformConfirmOneOrMultipleDiffs("codetransform-confirm-one-or-multiple-diffs"),
CodeTransformNew("codetransform-new"),
CodeTransformOpenTransformHub("codetransform-open-transform-hub"),
CodeTransformOpenMvnBuild("codetransform-open-mvn-build"),
Expand Down Expand Up @@ -72,6 +73,7 @@ class CodeTransformChatApp : AmazonQApp {
CodeTransformMessageTypes.CodeTransformCancel.type to IncomingCodeTransformMessage.CodeTransformCancel::class,
CodeTransformMessageTypes.ChatPrompt.type to IncomingCodeTransformMessage.ChatPrompt::class,
CodeTransformMessageTypes.CodeTransformConfirmSkipTests.type to IncomingCodeTransformMessage.CodeTransformConfirmSkipTests::class,
CodeTransformMessageTypes.CodeTransformConfirmOneOrMultipleDiffs.type to IncomingCodeTransformMessage.CodeTransformConfirmOneOrMultipleDiffs::class,
CodeTransformMessageTypes.CodeTransformNew.type to IncomingCodeTransformMessage.CodeTransformNew::class,
CodeTransformMessageTypes.CodeTransformOpenTransformHub.type to IncomingCodeTransformMessage.CodeTransformOpenTransformHub::class,
CodeTransformMessageTypes.CodeTransformOpenMvnBuild.type to IncomingCodeTransformMessage.CodeTransformOpenMvnBuild::class,
Expand Down Expand Up @@ -166,6 +168,7 @@ class CodeTransformChatApp : AmazonQApp {
is IncomingCodeTransformMessage.CodeTransformStop -> inboundAppMessagesHandler.processCodeTransformStopAction(message.tabId)
is IncomingCodeTransformMessage.ChatPrompt -> inboundAppMessagesHandler.processChatPromptMessage(message)
is IncomingCodeTransformMessage.CodeTransformConfirmSkipTests -> inboundAppMessagesHandler.processCodeTransformConfirmSkipTests(message)
is IncomingCodeTransformMessage.CodeTransformConfirmOneOrMultipleDiffs -> inboundAppMessagesHandler.processCodeTransformOneOrMultipleDiffs(message)
is IncomingCodeTransformMessage.CodeTransformNew -> inboundAppMessagesHandler.processCodeTransformNewAction(message)
is IncomingCodeTransformMessage.CodeTransformOpenTransformHub -> inboundAppMessagesHandler.processCodeTransformOpenTransformHub(message)
is IncomingCodeTransformMessage.CodeTransformOpenMvnBuild -> inboundAppMessagesHandler.processCodeTransformOpenMvnBuild(message)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ interface InboundAppMessagesHandler {

suspend fun processCodeTransformConfirmSkipTests(message: IncomingCodeTransformMessage.CodeTransformConfirmSkipTests)

suspend fun processCodeTransformOneOrMultipleDiffs(message: IncomingCodeTransformMessage.CodeTransformConfirmOneOrMultipleDiffs)

suspend fun processCodeTransformOpenTransformHub(message: IncomingCodeTransformMessage.CodeTransformOpenTransformHub)

suspend fun processCodeTransformOpenMvnBuild(message: IncomingCodeTransformMessage.CodeTransformOpenMvnBuild)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ class GumbyClient(private val project: Project) {
it.timestamp(Instant.now())
it.ideCategory(IdeCategory.JETBRAINS)
it.programmingLanguage { language ->
language.languageName(metrics.programmingLanguage)
language.languageName(metrics.programmingLanguage?.lowercase())
}
it.linesOfCodeChanged(metrics.linesOfCodeChanged)
it.charsOfCodeChanged(metrics.charactersOfCodeChanged)
Expand Down
Loading

0 comments on commit 71c98ed

Please sign in to comment.