Skip to content

Commit 8d9284d

Browse files
committed
Merge remote-tracking branch 'origin/main' into manodnyb/fixThinkingBug
2 parents 7e8addd + faaa62b commit 8d9284d

File tree

7 files changed

+79
-50
lines changed

7 files changed

+79
-50
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" : "/transform: validate YAML dependency file for required fields"
4+
}

plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/constants/CodeTransformChatItems.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,9 +419,9 @@ fun buildSQLMetadataValidationErrorChatContent(errorReason: String) = CodeTransf
419419
message = errorReason,
420420
)
421421

422-
fun buildCustomDependencyVersionsFileInvalidChatContent() = CodeTransformChatMessageContent(
422+
fun buildCustomDependencyVersionsFileInvalidChatContent(missingKey: String) = CodeTransformChatMessageContent(
423423
type = CodeTransformChatMessageType.FinalizedAnswer,
424-
message = message("codemodernizer.chat.message.custom_dependency_upgrades_invalid"),
424+
message = message("codemodernizer.chat.message.custom_dependency_upgrades_invalid", missingKey),
425425
)
426426

427427
fun buildUserCancelledChatContent() = CodeTransformChatMessageContent(

plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/controller/CodeTransformChatController.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -432,9 +432,9 @@ class CodeTransformChatController(
432432
val descriptor = FileChooserDescriptorFactory.createSingleFileDescriptor()
433433
.withDescription("Select .yaml file")
434434
val selectedFile = FileChooser.chooseFile(descriptor, null, null) ?: return@withContext
435-
val isValid = validateCustomVersionsFile(selectedFile)
436-
if (!isValid) {
437-
codeTransformChatHelper.updateLastPendingMessage(buildCustomDependencyVersionsFileInvalidChatContent())
435+
val missingKey = validateCustomVersionsFile(selectedFile)
436+
if (missingKey != null) {
437+
codeTransformChatHelper.updateLastPendingMessage(buildCustomDependencyVersionsFileInvalidChatContent(missingKey))
438438
codeTransformChatHelper.addNewMessage(buildStartNewTransformFollowup())
439439
return@withContext
440440
}

plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/utils/CodeTransformFileUtils.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -196,21 +196,22 @@ fun parseXmlDependenciesReport(pathToXmlDependency: Path): DependencyUpdatesRepo
196196
return report
197197
}
198198

199-
fun validateCustomVersionsFile(file: VirtualFile): Boolean {
199+
// return the first missing key in the custom versions file, or null if all required keys are present
200+
fun validateCustomVersionsFile(file: VirtualFile): String? {
200201
val validFileEndings = listOf("yaml", "yml")
201202
if (!validFileEndings.any { file.name.lowercase().endsWith(it) }) {
202203
getLogger<CodeTransformChatController>().error { "Custom versions file is not a YAML file: ${file.name}" }
203-
return false
204+
return message("codemodernizer.chat.message.custom_dependency_upgrades_invalid_not_yaml")
204205
}
205206
val fileContents = file.readText()
206-
val requiredKeys = listOf("dependencyManagement:", "identifier:", "targetVersion:")
207+
val requiredKeys = listOf("dependencyManagement", "identifier", "targetVersion", "originType")
207208
for (key in requiredKeys) {
208209
if (!fileContents.contains(key)) {
209210
getLogger<CodeTransformChatController>().error { "Missing yaml key: $key" }
210-
return false
211+
return key
211212
}
212213
}
213-
return true
214+
return null
214215
}
215216

216217
fun validateSctMetadata(sctFile: File?): SqlMetadataValidationResult {

plugins/amazonq/codetransform/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codemodernizer/CodeWhispererCodeModernizerUtilsTest.kt

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,8 @@ dependencyManagement:
411411
""".trimIndent()
412412

413413
val virtualFile = LightVirtualFile("test-valid.yaml", YAMLFileType.YML, sampleFileContents)
414-
val isValidFile = validateCustomVersionsFile(virtualFile)
415-
assertThat(isValidFile).isTrue()
414+
val missingKey = validateCustomVersionsFile(virtualFile)
415+
assertThat(missingKey).isNull()
416416
}
417417

418418
@Test
@@ -432,8 +432,8 @@ invalidKey:
432432
""".trimIndent()
433433

434434
val virtualFile = LightVirtualFile("test-invalid.yaml", YAMLFileType.YML, sampleFileContents)
435-
val isValidFile = validateCustomVersionsFile(virtualFile)
436-
assertThat(isValidFile).isFalse()
435+
val missingKey = validateCustomVersionsFile(virtualFile)
436+
assertThat(missingKey).isEqualTo("dependencyManagement")
437437
}
438438

439439
@Test
@@ -454,7 +454,27 @@ dependencyManagement:
454454

455455
val virtualFile = LightVirtualFile("test-invalid-file-type.txt", sampleFileContents)
456456
val isValidFile = validateCustomVersionsFile(virtualFile)
457-
assertThat(isValidFile).isFalse()
457+
assertThat(isValidFile).isEqualTo(message("codemodernizer.chat.message.custom_dependency_upgrades_invalid_not_yaml"))
458+
}
459+
460+
@Test
461+
fun `WHEN validateCustomVersionsFile on yaml file missing originType THEN fails validation`() {
462+
val sampleFileContents = """name: "dependency-upgrade"
463+
description: "Custom dependency version management for Java migration from JDK 8/11/17 to JDK 17/21"
464+
dependencyManagement:
465+
dependencies:
466+
- identifier: "com.example:library1"
467+
targetVersion: "2.1.0"
468+
versionProperty: "library1.version"
469+
plugins:
470+
- identifier: "com.example:plugin"
471+
targetVersion: "1.2.0"
472+
versionProperty: "plugin.version"
473+
""".trimIndent()
474+
475+
val virtualFile = LightVirtualFile("sample.yaml", sampleFileContents)
476+
val missingKey = validateCustomVersionsFile(virtualFile)
477+
assertThat(missingKey).isEqualTo("originType")
458478
}
459479

460480
@Test

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

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -633,21 +633,23 @@ private class AmazonQServerInstance(private val project: Project, private val cs
633633
}
634634
}
635635

636-
if (Files.exists(nodePath) && Files.isExecutable(nodePath)) {
637-
resolveNodeMetric(true, true)
638-
return nodePath
639-
}
640-
641-
// use alternative node runtime if it is not found
642-
LOG.warn { "Node Runtime download failed. Fallback to user specified node runtime " }
643636
// attempt to use user provided node runtime path
644637
val nodeRuntime = LspSettings.getInstance().getNodeRuntimePath()
645638
if (!nodeRuntime.isNullOrEmpty()) {
646639
LOG.info { "Using node from $nodeRuntime " }
647640

648641
resolveNodeMetric(false, true)
649642
return Path.of(nodeRuntime)
643+
}
644+
645+
// attempt to use bundled node
646+
if (Files.exists(nodePath) && Files.isExecutable(nodePath) && validateNode(nodePath) != null) {
647+
resolveNodeMetric(true, true)
648+
return nodePath
650649
} else {
650+
// use alternative node runtime if it is not found
651+
LOG.warn { "Node Runtime download failed. Fallback to user environment search" }
652+
651653
val localNode = locateNodeCommand()
652654
if (localNode != null) {
653655
LOG.info { "Using node from ${localNode.toAbsolutePath()}" }
@@ -689,34 +691,35 @@ private class AmazonQServerInstance(private val project: Project, private val cs
689691
.asSequence()
690692
.map { it.toPath() }
691693
.filter { Files.isRegularFile(it) && Files.isExecutable(it) }
692-
.firstNotNullOfOrNull { path ->
693-
try {
694-
val process = ProcessBuilder(path.toString(), "--version")
695-
.redirectErrorStream(true)
696-
.start()
697-
698-
if (!process.waitFor(5, TimeUnit.SECONDS)) {
699-
process.destroy()
700-
null
701-
} else if (process.exitValue() == 0) {
702-
val version = process.inputStream.bufferedReader().readText().trim()
703-
val majorVersion = version.removePrefix("v").split(".")[0].toIntOrNull()
704-
705-
if (majorVersion != null && majorVersion >= 18) {
706-
path.toAbsolutePath()
707-
} else {
708-
LOG.debug { "Node version < 18 found at: $path (version: $version)" }
709-
null
710-
}
711-
} else {
712-
LOG.debug { "Failed to get version from node at: $path" }
713-
null
714-
}
715-
} catch (e: Exception) {
716-
LOG.debug(e) { "Failed to check version for node at: $path" }
717-
null
718-
}
694+
.firstNotNullOfOrNull(::validateNode)
695+
}
696+
697+
/** @return null if node is not suitable **/
698+
private fun validateNode(path: Path) = try {
699+
val process = ProcessBuilder(path.toString(), "--version")
700+
.redirectErrorStream(true)
701+
.start()
702+
703+
if (!process.waitFor(5, TimeUnit.SECONDS)) {
704+
process.destroy()
705+
null
706+
} else if (process.exitValue() == 0) {
707+
val version = process.inputStream.bufferedReader().readText().trim()
708+
val majorVersion = version.removePrefix("v").split(".")[0].toIntOrNull()
709+
710+
if (majorVersion != null && majorVersion >= 18) {
711+
path.toAbsolutePath()
712+
} else {
713+
LOG.debug { "Node version < 18 found at: $path (version: $version)" }
714+
null
719715
}
716+
} else {
717+
LOG.debug { "Failed to get version from node at: $path" }
718+
null
719+
}
720+
} catch (e: Exception) {
721+
LOG.debug(e) { "Failed to check version for node at: $path" }
722+
null
720723
}
721724

722725
override fun dispose() {

plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,8 @@ codemodernizer.chat.message.changes_applied=I applied the changes to your projec
647647
codemodernizer.chat.message.choose_objective=I can help you with the following tasks:\n- Upgrade your Java 8, Java 11, and Java 17 codebases to Java 17 or Java 21.\n- Upgrade Java 17 or Java 21 code with up-to-date libraries and other dependencies.\n- Convert embedded SQL code for Oracle to PostgreSQL database migrations in AWS DMS.\n\nWhat would you like to do? You can enter "language upgrade" or "sql conversion".
648648
codemodernizer.chat.message.choose_objective_placeholder=Enter "language upgrade" or "sql conversion"
649649
codemodernizer.chat.message.custom_dependency_upgrades_continue=Ok, I will continue the transformation without additional dependency upgrade information.
650-
codemodernizer.chat.message.custom_dependency_upgrades_invalid=I wasn't able to parse the dependency upgrade file. Check that it's configured properly and try again. For an example of the required dependency upgrade file format, see the [documentation](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/code-transformation.html#dependency-upgrade-file).
650+
codemodernizer.chat.message.custom_dependency_upgrades_invalid=The dependency upgrade file provided is missing required field `{0}`. Check that it is configured properly and try again. For an example of the required dependency upgrade file format, see the [documentation](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/code-transformation.html#dependency-upgrade-file).
651+
codemodernizer.chat.message.custom_dependency_upgrades_invalid_not_yaml=Provided file is not a YAML/YML file
651652
codemodernizer.chat.message.custom_dependency_upgrades_prompt_jdk_upgrade=Would you like to provide a dependency upgrade file? You can specify first party dependencies and their versions in a YAML file, and I will upgrade them during the JDK upgrade transformation. For an example dependency upgrade file, see the [documentation](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/code-transformation.html#dependency-upgrade-file).
652653
codemodernizer.chat.message.custom_dependency_upgrades_prompt_library_upgrade=Would you like to provide a dependency upgrade file? You can specify third party dependencies and their versions in a YAML file, and I will only upgrade these dependencies during the library upgrade transformation. For an example dependency upgrade file, see the [documentation](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/code-transformation.html#dependency-upgrade-file).
653654
codemodernizer.chat.message.custom_dependency_upgrades_valid=The dependency upgrade file looks good. I will use this information to upgrade the dependencies you specified.

0 commit comments

Comments
 (0)