Skip to content

Commit 65a3ba9

Browse files
author
David Hasani
committed
parse plan
1 parent ea593e2 commit 65a3ba9

File tree

3 files changed

+127
-32
lines changed

3 files changed

+127
-32
lines changed

packages/core/src/codewhisperer/models/model.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,9 @@ export class ZipManifest {
686686
version: string = '1.0'
687687
hilCapabilities: string[] = ['HIL_1pDependency_VersionUpgrade']
688688
// TO-DO: add 'CLIENT_SIDE_BUILD' here when releasing
689+
690+
// TO-DO: add a new capability here for AGENTIC_PLAN_V1?
691+
689692
transformCapabilities: string[] = ['EXPLAINABILITY_V1']
690693
customBuildCommand: string = 'clean test'
691694
requestedConversions?: {

packages/core/src/codewhisperer/service/transformByQ/transformApiHandler.ts

Lines changed: 114 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -521,51 +521,65 @@ export function getFormattedString(s: string) {
521521
return CodeWhispererConstants.formattedStringMap.get(s) ?? s
522522
}
523523

524-
export function addTableMarkdown(plan: string, stepId: string, tableMapping: { [key: string]: string }) {
525-
const tableObj = tableMapping[stepId]
526-
if (!tableObj) {
527-
// no table present for this step
524+
export function addTableMarkdown(plan: string, stepId: string, tableMapping: { [key: string]: string[] }) {
525+
const tableObjects = tableMapping[stepId]
526+
if (!tableObjects || tableObjects.length === 0 || tableObjects.every((table: string) => table === '')) {
527+
// no tables for this stepId
528528
return plan
529529
}
530-
const table = JSON.parse(tableObj)
531-
if (table.rows.length === 0) {
532-
// empty table
533-
plan += `\n\nThere are no ${table.name.toLowerCase()} to display.\n\n`
530+
const tables: any[] = []
531+
tableObjects.forEach((tableObj: string) => {
532+
try {
533+
const table = JSON.parse(tableObj)
534+
if (table) {
535+
tables.push(table)
536+
}
537+
} catch (e) {
538+
getLogger().error(`CodeTransformation: Failed to parse table JSON, skipping: ${e}`)
539+
}
540+
})
541+
542+
if (tables.every((table: any) => table.rows.length === 0)) {
543+
// empty tables for this stepId
544+
plan += `\n\nThere are no ${tables[0].name.toLowerCase()} to display.\n\n`
534545
return plan
535546
}
536-
plan += `\n\n\n${table.name}\n|`
537-
const columns = table.columnNames
538-
// eslint-disable-next-line unicorn/no-array-for-each
547+
// table name and columns are shared, so only add to plan once
548+
plan += `\n\n\n${tables[0].name}\n|`
549+
const columns = tables[0].columnNames
539550
columns.forEach((columnName: string) => {
540551
plan += ` ${getFormattedString(columnName)} |`
541552
})
542553
plan += '\n|'
543-
// eslint-disable-next-line unicorn/no-array-for-each
544554
columns.forEach((_: any) => {
545555
plan += '-----|'
546556
})
547-
// eslint-disable-next-line unicorn/no-array-for-each
548-
table.rows.forEach((row: any) => {
549-
plan += '\n|'
550-
// eslint-disable-next-line unicorn/no-array-for-each
551-
columns.forEach((columnName: string) => {
552-
if (columnName === 'relativePath') {
553-
plan += ` [${row[columnName]}](${row[columnName]}) |` // add MD link only for files
554-
} else {
555-
plan += ` ${row[columnName]} |`
556-
}
557+
// add all rows of all tables
558+
tables.forEach((table: any) => {
559+
table.rows.forEach((row: any) => {
560+
plan += '\n|'
561+
columns.forEach((columnName: string) => {
562+
if (columnName === 'relativePath') {
563+
// add markdown link only for file paths
564+
plan += ` [${row[columnName]}](${row[columnName]}) |`
565+
} else {
566+
plan += ` ${row[columnName]} |`
567+
}
568+
})
557569
})
558570
})
559571
plan += '\n\n'
560572
return plan
561573
}
562574

563575
export function getTableMapping(stepZeroProgressUpdates: ProgressUpdates) {
564-
const map: { [key: string]: string } = {}
576+
const map: { [key: string]: string[] } = {}
565577
for (const update of stepZeroProgressUpdates) {
566-
// description should never be undefined since even if no data we show an empty table
567-
// but just in case, empty string allows us to skip this table without errors when rendering
568-
map[update.name] = update.description ?? ''
578+
if (!map[update.name]) {
579+
map[update.name] = []
580+
}
581+
// empty string allows us to skip this table when rendering
582+
map[update.name].push(update.description ?? '')
569583
}
570584
return map
571585
}
@@ -594,6 +608,78 @@ export async function getTransformationPlan(jobId: string, profile: RegionProfil
594608
profileArn: profile?.arn,
595609
})
596610

611+
// TO-DO: remove this mocked API response
612+
response = {
613+
transformationPlan: {
614+
transformationSteps: [
615+
{
616+
id: '0',
617+
name: 'Supplement Info',
618+
status: 'COMPLETED',
619+
progressUpdates: [
620+
{
621+
name: '0',
622+
status: 'COMPLETED',
623+
description:
624+
'{"type":"STATISTICS","name":"Plan Statistics","description":null,"columnNames":["name","value"],"rows":[{"name":"linesOfCode","value":"2532"},{"name":"plannedDependencyChanges","value":"4"},{"name":"plannedDeprecatedApiChanges","value":"0"},{"name":"plannedFileChanges","value":"7"}]}',
625+
},
626+
{
627+
name: '1',
628+
status: 'COMPLETED',
629+
description:
630+
'{"type":"DEPENDENCIES","name":"Dependency Changes","description":null,"columnNames":["dependencyName","action","currentVersion","targetVersion"],"rows":[]}',
631+
},
632+
{
633+
name: '1',
634+
status: 'COMPLETED',
635+
description:
636+
'{"type":"DEPENDENCIES","name":"Dependency Changes","description":null,"columnNames":["dependencyName","action","currentVersion","targetVersion"],"rows":[{"dependencyName":"junit:junit","action":"REMOVE","currentVersion":"4.12","targetVersion":"-"},{"dependencyName":"org.apache.logging.log4j:log4j-slf4j-impl","action":"ADD","currentVersion":"-","targetVersion":"2.x"},{"dependencyName":"org.apache.maven.plugins:maven-surefire-plugin","action":"UPDATE","currentVersion":"2.18.1","targetVersion":"3.1.x"},{"dependencyName":"org.slf4j:slf4j-log4j12","action":"REMOVE","currentVersion":"1.8.0-beta0","targetVersion":"-"}]}',
637+
},
638+
{
639+
name: '1',
640+
status: 'FAILED',
641+
description:
642+
'{"type":"DEPENDENCIES","name":"Dependency Changes","description":null,"columnNames":["dependencyName","action","currentVersion","targetVersion"],"rows":[{"dependencyName":"com.squareup.okio:okio","action":"UPDATE","currentVersion":"4.12","targetVersion":"-"},{"dependencyName":"org.apache.logging.log4j:log4j-slf4j-impl","action":"ADD","currentVersion":"-","targetVersion":"2.x"},{"dependencyName":"org.apache.maven.plugins:maven-surefire-plugin","action":"UPDATE","currentVersion":"2.18.1","targetVersion":"3.1.x"},{"dependencyName":"org.slf4j:slf4j-log4j12","action":"REMOVE","currentVersion":"1.8.0-beta0","targetVersion":"-"}]}',
643+
},
644+
{
645+
name: '1',
646+
status: 'FAILED',
647+
description:
648+
'{"type":"DEPENDENCIES","name":"Dependency Changes","description":null,"columnNames":["dependencyName","action","currentVersion","targetVersion"],"rows":[{"dependencyName":"com.squareup.okio:okio","action":"UPDATE","currentVersion":"4.12","targetVersion":"-"},{"dependencyName":"org.apache.logging.log4j:log4j-slf4j-impl","action":"ADD","currentVersion":"-","targetVersion":"2.x"},{"dependencyName":"org.apache.maven.plugins:maven-surefire-plugin","action":"UPDATE","currentVersion":"2.18.1","targetVersion":"3.1.x"},{"dependencyName":"org.slf4j:slf4j-log4j12","action":"REMOVE","currentVersion":"1.8.0-beta0","targetVersion":"-"}]}',
649+
},
650+
{
651+
name: '1',
652+
status: 'COMPLETED',
653+
description:
654+
'{"type":"DEPENDENCIES","name":"Dependency Changes","description":null,"columnNames":["dependencyName","action","currentVersion","targetVersion"],"rows":[{"dependencyName":"com.squareup.okio:okio","action":"UPDATE","currentVersion":"4.12","targetVersion":"-"},{"dependencyName":"org.apache.logging.log4j:log4j-slf4j-impl","action":"ADD","currentVersion":"-","targetVersion":"2.x"},{"dependencyName":"org.apache.maven.plugins:maven-surefire-plugin","action":"UPDATE","currentVersion":"2.18.1","targetVersion":"3.1.x"},{"dependencyName":"org.slf4j:slf4j-log4j12","action":"REMOVE","currentVersion":"1.8.0-beta0","targetVersion":"-"}]}',
655+
},
656+
{
657+
name: '-1',
658+
status: 'COMPLETED',
659+
description:
660+
'{"type":"FILES","name":"File Changes","description":null,"columnNames":["relativePath","action"],"rows":[{"relativePath":"src/main/test/com/nxllxn/plantuml/java/TopLevelInterfaceTest.java","action":"UPDATE"},{"relativePath":"src/main/test/com/nxllxn/plantuml/java/TopLevelEnumerationTest.java","action":"UPDATE"},{"relativePath":"src/main/test/com/nxllxn/plantuml/java/TopLevelClassTest.java","action":"UPDATE"},{"relativePath":"src/main/test/com/nxllxn/plantuml/java/TopLevelAnnotationTest.java","action":"UPDATE"},{"relativePath":"src/main/test/com/nxllxn/plantuml/java/ParameterTest.java","action":"UPDATE"},{"relativePath":"src/main/test/com/nxllxn/plantuml/java/MethodTest.java","action":"UPDATE"},{"relativePath":"src/main/test/com/nxllxn/plantuml/java/FieldTest.java","action":"UPDATE"}]}',
661+
},
662+
],
663+
},
664+
{
665+
id: '1',
666+
name: 'Step 1 - Update JDK version, dependencies and related code (David)',
667+
description:
668+
'Amazon Q will attempt to update the JDK version and change the following dependencies and related code.',
669+
status: 'CREATED',
670+
progressUpdates: [],
671+
},
672+
{
673+
id: '2',
674+
name: 'Step 2 - Finalize code changes',
675+
description: 'Amazon Q will attempt to replace the following instances of deprecated code.',
676+
status: 'CREATED',
677+
progressUpdates: [],
678+
},
679+
],
680+
},
681+
}
682+
597683
const stepZeroProgressUpdates = response.transformationPlan.transformationSteps[0].progressUpdates
598684

599685
if (!stepZeroProgressUpdates || stepZeroProgressUpdates.length === 0) {
@@ -604,7 +690,7 @@ export async function getTransformationPlan(jobId: string, profile: RegionProfil
604690
// gets a mapping between the ID ('name' field) of each progressUpdate (substep) and the associated table
605691
const tableMapping = getTableMapping(stepZeroProgressUpdates)
606692

607-
const jobStatistics = JSON.parse(tableMapping['0']).rows // ID of '0' reserved for job statistics table
693+
const jobStatistics = JSON.parse(tableMapping['0'][0]).rows // ID of '0' reserved for job statistics table; only 1 table there
608694

609695
// get logo directly since we only use one logo regardless of color theme
610696
const logoIcon = getTransformationIcon('transformLogo')
@@ -631,7 +717,7 @@ export async function getTransformationPlan(jobId: string, profile: RegionProfil
631717
}
632718
plan += `</div><br>`
633719
plan += `<p style="font-size: 18px; margin-bottom: 4px;"><b>Appendix</b><br><a href="#top" style="float: right; font-size: 14px;">Scroll to top <img src="${arrowIcon}" style="vertical-align: middle;"></a></p><br>`
634-
plan = addTableMarkdown(plan, '-1', tableMapping) // ID of '-1' reserved for appendix table
720+
plan = addTableMarkdown(plan, '-1', tableMapping) // ID of '-1' reserved for appendix table; only 1 table there
635721
return plan
636722
} catch (e: any) {
637723
const errorMessage = (e as Error).message

packages/core/src/test/codewhisperer/commands/transformByQ.test.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -488,12 +488,18 @@ dependencyManagement:
488488

489489
const actual = getTableMapping(stepZeroProgressUpdates)
490490
const expected = {
491-
'0': '{"columnNames":["name","value"],"rows":[{"name":"Lines of code in your application","value":"3000"},{"name":"Dependencies to be replaced","value":"5"},{"name":"Deprecated code instances to be replaced","value":"10"},{"name":"Files to be updated","value":"7"}]}',
492-
'1-dependency-change-abc':
491+
'0': [
492+
'{"columnNames":["name","value"],"rows":[{"name":"Lines of code in your application","value":"3000"},{"name":"Dependencies to be replaced","value":"5"},{"name":"Deprecated code instances to be replaced","value":"10"},{"name":"Files to be updated","value":"7"}]}',
493+
],
494+
'1-dependency-change-abc': [
493495
'{"columnNames":["dependencyName","action","currentVersion","targetVersion"],"rows":[{"dependencyName":"org.springboot.com","action":"Update","currentVersion":"2.1","targetVersion":"2.4"}, {"dependencyName":"com.lombok.java","action":"Remove","currentVersion":"1.7","targetVersion":"-"}]}',
494-
'2-deprecated-code-xyz':
496+
],
497+
'2-deprecated-code-xyz': [
495498
'{"columnNames":["apiFullyQualifiedName","numChangedFiles"],“rows”:[{"apiFullyQualifiedName":"java.lang.Thread.stop()","numChangedFiles":"6"}, {"apiFullyQualifiedName":"java.math.bad()","numChangedFiles":"3"}]}',
496-
'-1': '{"columnNames":["relativePath","action"],"rows":[{"relativePath":"pom.xml","action":"Update"}, {"relativePath":"src/main/java/com/bhoruka/bloodbank/BloodbankApplication.java","action":"Update"}]}',
499+
],
500+
'-1': [
501+
'{"columnNames":["relativePath","action"],"rows":[{"relativePath":"pom.xml","action":"Update"}, {"relativePath":"src/main/java/com/bhoruka/bloodbank/BloodbankApplication.java","action":"Update"}]}',
502+
],
497503
}
498504
assert.deepStrictEqual(actual, expected)
499505
})

0 commit comments

Comments
 (0)