Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
629a053
initial attempt at showing multiple diff patches, need to sync chat w…
ntarakad-aws Nov 3, 2024
6ef2c1a
adding support for different json format
ntarakad-aws Nov 6, 2024
853b40c
adding new UI messaging for patch descriptions and removing redundant…
ntarakad-aws Nov 14, 2024
0429617
added in forms for one or multiple diffs and made manifest changes ac…
ntarakad-aws Nov 15, 2024
5f7c508
removing old multiple patches description
ntarakad-aws Nov 15, 2024
80e5b8f
fixing patch descriptions message
ntarakad-aws Nov 16, 2024
9b6c1d4
fixed issue with undefined in changes applied message and addressing …
ntarakad-aws Nov 17, 2024
61b088b
updated messaging for one or multiple diffs when job success/partial …
ntarakad-aws Nov 18, 2024
f89c49f
fixing one diff and off by one error for multiple diffs and addressin…
ntarakad-aws Nov 18, 2024
7c961ba
added unit tests and fixing off by one logic and detekt errors
ntarakad-aws Nov 18, 2024
89a8bb5
adding test zip
ntarakad-aws Nov 18, 2024
a667cc4
removing sample diff zip
ntarakad-aws Nov 18, 2024
1a1fdb8
adding sample diff zip
ntarakad-aws Nov 18, 2024
77fb5b9
adding simple back
ntarakad-aws Nov 18, 2024
f5bef5e
Merge branch 'main' into selective-transform
ntarakad-aws Nov 18, 2024
f2ff3d4
fixing detekt and adding patch applied notification and updating unit…
ntarakad-aws Nov 19, 2024
b07c148
addressing comments on PR, detekt issues, and adding feature flag
ntarakad-aws Nov 19, 2024
14992ff
adding feature flag and telemetry
ntarakad-aws Nov 20, 2024
6fb6f3f
fixing telemetry and readValue
ntarakad-aws Nov 20, 2024
98c9eab
fixing failed test and lint
ntarakad-aws Nov 20, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@ import com.intellij.openapi.vcs.changes.patch.ApplyPatchMode
import com.intellij.openapi.vcs.changes.patch.ImportToShelfExecutor
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import java.io.File
import java.nio.file.Files
import java.nio.file.Path
import java.time.Instant
import java.util.concurrent.atomic.AtomicBoolean
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import software.amazon.awssdk.services.codewhispererstreaming.model.TransformationDownloadArtifactType
Expand All @@ -28,6 +23,7 @@ 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
Expand Down Expand Up @@ -55,16 +51,22 @@ import software.aws.toolkits.jetbrains.services.codemodernizer.state.CodeModerni
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
import software.aws.toolkits.telemetry.CodeTransformArtifactType
import software.aws.toolkits.telemetry.CodeTransformVCSViewerSrcComponents
import java.io.File
import java.nio.file.Files
import java.nio.file.Path
import java.time.Instant
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"
val patchDescriptions: Map<String, String> = mapOf(
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.",
Expand All @@ -74,8 +76,7 @@ val patchDescriptions: Map<String, String> = mapOf(
"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.",
"Updated dependencies to latest version" to "",
"Upgrade Deprecated API" to ""
"Deprecated API replacement and dependency upgrades" to "This diff patch replaces deprecated APIs and makes additional dependency version upgrades."
)

class ArtifactHandler(
Expand All @@ -89,6 +90,7 @@ class ArtifactHandler(
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
Expand Down Expand Up @@ -277,14 +279,14 @@ class ArtifactHandler(
/**
* Opens the built-in patch dialog to display the diff and allowing users to apply the changes locally.
*/
internal fun displayDiffUsingPatch(
internal suspend fun displayDiffUsingPatch(
patchFile: VirtualFile,
totalPatchFiles: Int,
diffDescription: PatchInfo?,
jobId: JobId,
source: CodeTransformVCSViewerSrcComponents,
) {
runInEdt {
withContext(EDT) {
val dialog = ApplyPatchDifferentiatedDialog(
project,
ApplyPatchDefaultExecutor(project),
Expand All @@ -309,44 +311,41 @@ class ArtifactHandler(
dialog.isModal = true

if (dialog.showAndGet()) {
projectCoroutineScope(project).launch {
telemetry.viewArtifact(CodeTransformArtifactType.ClientInstructions, jobId, "Submit", source)
if (diffDescription == null) {
val message = "I applied the changes to your project."
val resultContent = CodeTransformChatMessageContent(
type = CodeTransformChatMessageType.PendingAnswer,
message = message,
)
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)
notifyStickyInfo(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
)
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 {
codeTransformChatHelper?.addNewMessage(buildStartNewTransformFollowup())
}
}
} else {
Expand Down Expand Up @@ -471,6 +470,12 @@ class ArtifactHandler(

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 Expand Up @@ -529,10 +534,5 @@ class ArtifactHandler(

companion object {
val LOG = getLogger<ArtifactHandler>()
private var sharedPatchIndex: Int = 0
fun getCurrentPatchIndex() = sharedPatchIndex
fun setCurrentPatchIndex(index: Int) {
sharedPatchIndex = index
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import software.aws.toolkits.jetbrains.services.codemodernizer.CodeTransformTele
import software.aws.toolkits.jetbrains.services.codemodernizer.EXPLAINABILITY_V1
import software.aws.toolkits.jetbrains.services.codemodernizer.HilTelemetryMetaData
import software.aws.toolkits.jetbrains.services.codemodernizer.InboundAppMessagesHandler
import software.aws.toolkits.jetbrains.services.codemodernizer.SELECTIVE_TRANSFORMATION_V1
import software.aws.toolkits.jetbrains.services.codemodernizer.client.GumbyClient
import software.aws.toolkits.jetbrains.services.codemodernizer.commands.CodeTransformActionMessage
import software.aws.toolkits.jetbrains.services.codemodernizer.commands.CodeTransformCommand
Expand Down Expand Up @@ -98,7 +99,6 @@ import software.aws.toolkits.jetbrains.services.codemodernizer.model.MavenDepend
import software.aws.toolkits.jetbrains.services.codemodernizer.model.UploadFailureReason
import software.aws.toolkits.jetbrains.services.codemodernizer.model.ValidationResult
import software.aws.toolkits.jetbrains.services.codemodernizer.panels.managers.CodeModernizerBottomWindowPanelManager
import software.aws.toolkits.jetbrains.services.codemodernizer.SELECTIVE_TRANSFORMATION_V1
import software.aws.toolkits.jetbrains.services.codemodernizer.session.ChatSessionStorage
import software.aws.toolkits.jetbrains.services.codemodernizer.session.Session
import software.aws.toolkits.jetbrains.services.codemodernizer.state.CodeModernizerSessionState
Expand Down Expand Up @@ -378,13 +378,20 @@ class CodeTransformChatController(
message("codemodernizer.chat.message.skip_tests_form.skip") -> MAVEN_BUILD_SKIP_UNIT_TESTS
else -> MAVEN_BUILD_RUN_UNIT_TESTS
}
//feature flag for Selective Transformation
val isSelectiveTransformationReady = false
codeTransformChatHelper.addNewMessage(buildUserSkipTestsFlagSelectionChatContent(message.skipTestsSelection))
codeModernizerManager.codeTransformationSession?.let {
it.sessionContext.customBuildCommand = customBuildCommand
if (!isSelectiveTransformationReady){
codeModernizerManager.runLocalMavenBuild(context.project, it)
}
}
codeTransformChatHelper.run {
addNewMessage(buildUserInputOneOrMultipleDiffsChatIntroContent())
addNewMessage(buildUserInputOneOrMultipleDiffsFlagChatContent())
if (isSelectiveTransformationReady){
codeTransformChatHelper.run {
addNewMessage(buildUserInputOneOrMultipleDiffsChatIntroContent())
addNewMessage(buildUserInputOneOrMultipleDiffsFlagChatContent())
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,23 +117,22 @@ open class CodeModernizerArtifact(
}
}

@OptIn(ExperimentalPathApi::class)
private fun extractPatches(manifest: CodeModernizerManifest, description: List<PatchInfo>?): List<VirtualFile> {
if (description == null) {
return extractSinglePatch(manifest)
}
val fileSystem = LocalFileSystem.getInstance()
val patchesDir = tempDir.toPath().resolve(manifest.patchesRoot)
if (!patchesDir.isDirectory()) {
throw RuntimeException("Expected root for patches was not a directory.")
error("Expected root for patches was not a directory.")
}
return description.map { patchInfo ->
val patchFile = patchesDir.resolve(patchInfo.filename)
if (patchFile.toFile().exists()) {
fileSystem.findFileByNioFile(patchFile)
?: throw RuntimeException("Could not find patch: ${patchInfo.filename}")
?: error("Could not find patch: ${patchInfo.filename}")
} else {
throw RuntimeException("Patch file not found: ${patchInfo.filename}")
error("Patch file not found: ${patchInfo.filename}")
}
}
}
Expand Down Expand Up @@ -163,7 +162,7 @@ open class CodeModernizerArtifact(
// No JSON description file found, return null
return null
}
val descriptionContent: DescriptionContent = MAPPER.readValue(descriptionFile, DescriptionContent::class.java)
val descriptionContent: DescriptionContent = MAPPER.readValue(descriptionFile)
return descriptionContent.content
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,10 @@ open class CodeWhispererCodeModernizerTestBase(
internal val minJDKUpgradePatchResource = "min_jdk_upgrade.patch".toResourceFile()
internal val minJDKUpgradePatchResourceFile = LightVirtualFile("min_jdk_upgrade.patch", minJDKUpgradePatchResource.readText())
internal val enterpriseApplicationUpgradePatchResource = "popular_enterprise_application_framework.patch".toResourceFile()
internal val enterpriseApplicationUpgradePatchResourceFile = LightVirtualFile("popular_enterprise_application_framework.patch",
enterpriseApplicationUpgradePatchResource.readText())
internal val enterpriseApplicationUpgradePatchResourceFile = LightVirtualFile(
"popular_enterprise_application_framework.patch",
enterpriseApplicationUpgradePatchResource.readText()
)
internal val testingToolPatchResource = "testing_tool.patch".toResourceFile()
internal val testingToolPatchResourceFile = LightVirtualFile("testing_tool.patch", testingToolPatchResource.readText())
internal val deprecatedAPIPatchResource = "update_deprecated_api.patch".toResourceFile()
Expand Down Expand Up @@ -299,13 +301,15 @@ open class CodeWhispererCodeModernizerTestBase(
val summaryFileMock = Mockito.mock(File::class.java)
val logFileMock = Mockito.mock(File::class.java)
doReturn("dummy/path").whenever(virtualFileMock).path
testSessionContextSpy = spy(CodeModernizerSessionContext(
project,
virtualFileMock,
JavaSdkVersion.JDK_1_8,
JavaSdkVersion.JDK_11,
listOf("EXPLAINABILITY_V1", "SELECTIVE_TRANSFORMATION_V1"),
"test")
testSessionContextSpy = spy(
CodeModernizerSessionContext(
project,
virtualFileMock,
JavaSdkVersion.JDK_1_8,
JavaSdkVersion.JDK_11,
listOf("EXPLAINABILITY_V1", "SELECTIVE_TRANSFORMATION_V1"),
"test"
)
)

testSessionSpy = spy(CodeModernizerSession(testSessionContextSpy, 0, 0))
Expand All @@ -316,8 +320,12 @@ open class CodeWhispererCodeModernizerTestBase(
CodeModernizerArtifact(
exampleZipPath.toAbsolutePath().toString(),
validManifest,
listOf(minJDKUpgradePatchResourceFile, enterpriseApplicationUpgradePatchResourceFile,
testingToolPatchResourceFile, deprecatedAPIPatchResourceFile),
listOf(
minJDKUpgradePatchResourceFile,
enterpriseApplicationUpgradePatchResourceFile,
testingToolPatchResourceFile,
deprecatedAPIPatchResourceFile
),
exampleDescriptionContent.content,
validTransformationSummary,
summaryFileMock,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,7 @@ codemodernizer.chat.message.button.view_diff=View diff
codemodernizer.chat.message.button.view_failure_build_log=View Failure Build Log
codemodernizer.chat.message.button.view_summary=View summary
codemodernizer.chat.message.choose_objective=Enter "language upgrade" or "SQL conversion"
codemodernizer.chat.message.changes_applied=I applied the changes to your project.
codemodernizer.chat.message.download_failed_client_instructions_expired=Your transformation is not available anymore. Your code and transformation summary are deleted 24 hours after the transformation completes. Please try starting the transformation again.
codemodernizer.chat.message.download_failed_invalid_artifact=Sorry, I was unable to find your {0}. Artifacts are deleted after 24 hours. Please try starting the transformation again.
codemodernizer.chat.message.download_failed_other=Sorry, I ran into an issue while trying to download your {0}. Please try again. {1}
Expand Down Expand Up @@ -617,7 +618,8 @@ I can now divide the transformation results into diff patches (if applicable to
- Popular Enterprise Specifications Application Frameworks: Popular enterprise and application frameworks like Jakarta EE, Hibernate, and Micronaut 3.\n\n\
- HTTP Client Utilities Web Frameworks: HTTP client libraries, Apache Commons utilities, and Struts frameworks.\n\n\
- Testing Tools Frameworks: Testing tools like ArchUnit, Mockito, and TestContainers and build tools like Jenkins and Maven Wrapper.\n\n\
- Miscellaneous Processing Documentation: Diverse set spanning ORMs, XML processing, and API documentation like Swagger to SpringDoc/OpenAPI.
- Miscellaneous Processing Documentation: Diverse set spanning ORMs, XML processing, and API documentation like Swagger to SpringDoc/OpenAPI.\n\n\
- Deprecated API replacement and dependency upgrades: Replaces deprecated APIs and makes additional dependency version upgrades.
codemodernizer.chat.message.one_or_multiple_diffs_form.multiple_diffs=Multiple diffs
codemodernizer.chat.message.one_or_multiple_diffs_form.one_diff=One diff
codemodernizer.chat.message.one_or_multiple_diffs_form.response=Okay, I will create {0} when providing the proposed changes.
Expand Down