Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
@@ -0,0 +1,4 @@
{
"type": "Feature",
"description": "Q CodeTransformation: add more job metadata to history table"
}
Original file line number Diff line number Diff line change
Expand Up @@ -403,9 +403,11 @@ export class GumbyController {
await vscode.commands.executeCommand('aws.amazonq.transformationHub.summary.reveal')
break
case ButtonActions.STOP_TRANSFORMATION_JOB:
await stopTransformByQ(transformByQState.getJobId())
await postTransformationJob()
await cleanupTransformationJob()
if (transformByQState.isRunning() || transformByQState.isRefreshInProgress()) {
await stopTransformByQ(transformByQState.getJobId())
await postTransformationJob()
await cleanupTransformationJob()
}
break
case ButtonActions.CONFIRM_START_TRANSFORMATION_FLOW:
this.resetTransformationChatFlow()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,11 +400,22 @@ export class Messenger {
}

public sendJobRefreshInProgressMessage(tabID: string, jobId: string) {
this.dispatcher.sendAsyncEventProgress(
new AsyncEventProgressMessage(tabID, {
inProgress: true,
message: CodeWhispererConstants.refreshingJobChatMessage(jobId),
})
const buttons: ChatItemButton[] = []
buttons.push({
keepCardAfterClick: true,
text: CodeWhispererConstants.stopTransformationButtonText,
id: ButtonActions.STOP_TRANSFORMATION_JOB,
disabled: false,
})
this.dispatcher.sendChatMessage(
new ChatMessage(
{
message: CodeWhispererConstants.refreshingJobChatMessage(jobId),
messageType: 'ai-prompt',
buttons: buttons,
},
tabID
)
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,12 @@ export async function postTransformationJob() {
latest.status,
latest.duration,
transformByQState.getJobId(),
transformByQState.getJobHistoryPath()
transformByQState.getJobHistoryPath(),
latest.transformationType,
latest.sourceJDKVersion,
latest.targetJDKVersion,
latest.customDependencyVersionsFilePath,
latest.customBuildCommand
)
}
}
Expand Down
12 changes: 11 additions & 1 deletion packages/core/src/codewhisperer/models/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,17 @@ export const jobPlanProgress: {
}

export let sessionJobHistory: {
[jobId: string]: { startTime: string; projectName: string; status: string; duration: string }
[jobId: string]: {
startTime: string
projectName: string
status: string
duration: string
transformationType: string
sourceJDKVersion: string
targetJDKVersion: string
customDependencyVersionsFilePath: string
customBuildCommand: string
}
} = {}

export class TransformByQState {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,29 @@ export function throwIfCancelled() {
}

export function updateJobHistory() {
if (transformByQState.getJobId() !== '') {
if (transformByQState.getJobId() !== '' && transformByQState.getSourceJDKVersion() !== undefined) {
sessionJobHistory[transformByQState.getJobId()] = {
startTime: transformByQState.getStartTime(),
projectName: transformByQState.getProjectName(),
status: transformByQState.getPolledJobStatus(),
duration: convertToTimeString(calculateTotalLatency(CodeTransformTelemetryState.instance.getStartTime())),
transformationType: transformByQState.getTransformationType() ?? 'N/A',
sourceJDKVersion:
transformByQState.getTransformationType() === TransformationType.LANGUAGE_UPGRADE
? (transformByQState.getSourceJDKVersion() ?? 'N/A')
: 'N/A',
targetJDKVersion:
transformByQState.getTransformationType() === TransformationType.LANGUAGE_UPGRADE
? (transformByQState.getTargetJDKVersion() ?? 'N/A')
: 'N/A',
customDependencyVersionsFilePath:
transformByQState.getTransformationType() === TransformationType.LANGUAGE_UPGRADE
? transformByQState.getCustomDependencyVersionFilePath() || 'N/A'
: 'N/A',
customBuildCommand:
transformByQState.getTransformationType() === TransformationType.LANGUAGE_UPGRADE
? transformByQState.getCustomBuildCommand() || 'N/A'
: 'N/A',
}
}
return sessionJobHistory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ export interface HistoryObject {
diffPath: string
summaryPath: string
jobId: string
transformationType: string
sourceJDKVersion: string
targetJDKVersion: string
customDependencyVersionFilePath: string
customBuildCommand: string
}

export interface JobMetadata {
Expand Down Expand Up @@ -71,6 +76,11 @@ export async function readHistoryFile(): Promise<HistoryObject[]> {
diffPath: jobInfo[4],
summaryPath: jobInfo[5],
jobId: jobInfo[6],
transformationType: jobInfo[7],
sourceJDKVersion: jobInfo[8],
targetJDKVersion: jobInfo[9],
customDependencyVersionFilePath: jobInfo[10],
customBuildCommand: jobInfo[11],
})
}
}
Expand Down Expand Up @@ -125,14 +135,22 @@ export async function writeToHistoryFile(
status: string,
duration: string,
jobId: string,
jobHistoryPath: string
jobHistoryPath: string,
transformationType: string,
sourceJDKVersion: string,
targetJDKVersion: string,
customDependencyVersionFilePath: string,
customBuildCommand: string
) {
const historyLogFilePath = path.join(os.homedir(), '.aws', 'transform', 'transformation_history.tsv')
// create transform folder if necessary
if (!(await fs.existsFile(historyLogFilePath))) {
await fs.mkdir(path.dirname(historyLogFilePath))
// create headers of new transformation history file
await fs.writeFile(historyLogFilePath, 'date\tproject_name\tstatus\tduration\tdiff_patch\tsummary\tjob_id\n')
await fs.writeFile(
historyLogFilePath,
'date\tproject_name\tstatus\tduration\tdiff_patch\tsummary\tjob_id\ttransformation_type\tsource_jdk_version\ttarget_jdk_version\tcustom_dependency_version_file_path\tcustom_build_command\n'
)
}
const artifactsExist = status === 'COMPLETED' || status === 'PARTIALLY_COMPLETED'
const fields = [
Expand All @@ -143,6 +161,11 @@ export async function writeToHistoryFile(
artifactsExist ? path.join(jobHistoryPath, 'diff.patch') : '',
artifactsExist ? path.join(jobHistoryPath, 'summary', 'summary.md') : '',
jobId,
transformationType,
sourceJDKVersion,
targetJDKVersion,
customDependencyVersionFilePath,
customBuildCommand,
]

const jobDetails = fields.join('\t') + '\n'
Expand Down Expand Up @@ -318,7 +341,8 @@ async function updateHistoryFile(status: string, duration: string, jobHistoryPat
for (const job of jobs) {
if (job) {
const jobInfo = job.split('\t')
// startTime: jobInfo[0], projectName: jobInfo[1], status: jobInfo[2], duration: jobInfo[3], diffPath: jobInfo[4], summaryPath: jobInfo[5], jobId: jobInfo[6]
// 0: startTime, 1: projectName, 2: status, 3: duration, 4: diffPath, 5: summaryPath, 6: jobId
// 7: transformationType, 8: sourceJDKVersion, 9: targetJDKVersion, 10: customDependencyVersionFilePath, 11: customBuildCommand
if (jobInfo[6] === jobId) {
// update any values if applicable
jobInfo[2] = status
Expand All @@ -341,7 +365,10 @@ async function updateHistoryFile(status: string, duration: string, jobHistoryPat
}

// rewrite file
await fs.writeFile(historyLogFilePath, 'date\tproject_name\tstatus\tduration\tdiff_patch\tsummary\tjob_id\n')
await fs.writeFile(
historyLogFilePath,
'date\tproject_name\tstatus\tduration\tdiff_patch\tsummary\tjob_id\ttransformation_type\tsource_jdk_version\ttarget_jdk_version\tcustom_dependency_version_file_path\tcustom_build_command\n'
)
const tsvContent = history.map((row) => row.join('\t')).join('\n') + '\n'
await fs.appendFile(historyLogFilePath, tsvContent)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ export class TransformationHubViewProvider implements vscode.WebviewViewProvider
diffPath: '',
summaryPath: '',
jobId: transformByQState.getJobId(),
transformationType: current.transformationType,
sourceJDKVersion: current.sourceJDKVersion,
targetJDKVersion: current.targetJDKVersion,
customDependencyVersionFilePath: current.customDependencyVersionsFilePath,
customBuildCommand: current.customBuildCommand,
})
}
return `<!DOCTYPE html>
Expand Down Expand Up @@ -208,6 +213,11 @@ export class TransformationHubViewProvider implements vscode.WebviewViewProvider
<th>Summary File</th>
<th>Job Id</th>
<th>Refresh Job</th>
<th>Transformation Type</th>
<th>Source JDK Version</th>
<th>Target JDK Version</th>
<th>Custom Dependency Version File Path</th>
<th>Custom Build Command</th>
</tr>
</thead>
<tbody>
Expand Down Expand Up @@ -242,6 +252,11 @@ export class TransformationHubViewProvider implements vscode.WebviewViewProvider
</button>
</td>
<td>${job.transformationType ?? ''}</td>
<td>${job.sourceJDKVersion ?? ''}</td>
<td>${job.targetJDKVersion ?? ''}</td>
<td>${job.customDependencyVersionFilePath ?? ''}</td>
<td>${job.customBuildCommand ? `mvn ${job.customBuildCommand}` : ''}</td>
</tr>
`
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,23 +98,51 @@ describe('Transformation History Handler', function () {

it('Creates history file with headers when it does not exist', async function () {
sinon.stub(fs, 'existsFile').resolves(false)
await writeToHistoryFile('01/01/25, 10:00 AM', 'test-project', 'COMPLETED', '5 min', 'job-123', '/job/path')
await writeToHistoryFile(
'01/01/25, 10:00 AM',
'test-project',
'COMPLETED',
'5 min',
'job-123',
'/job/path',
'LANGUAGE_UPGRADE',
'JDK8',
'JDK17',
'/path/here',
'clean test-compile'
)

const expectedPath = path.join(os.homedir(), '.aws', 'transform', 'transformation_history.tsv')
const fileContent = writtenFiles.get(expectedPath)

assert(fileContent)
assert(fileContent.includes('date\tproject_name\tstatus\tduration\tdiff_patch\tsummary\tjob_id\n'))
assert(
fileContent.includes(
`01/01/25, 10:00 AM\ttest-project\tCOMPLETED\t5 min\t${path.join('/job/path', 'diff.patch')}\t${path.join('/job/path', 'summary', 'summary.md')}\tjob-123\n`
'date\tproject_name\tstatus\tduration\tdiff_patch\tsummary\tjob_id\ttransformation_type\tsource_jdk_version\ttarget_jdk_version\tcustom_dependency_version_file_path\tcustom_build_command\n'
)
)
assert(
fileContent.includes(
`01/01/25, 10:00 AM\ttest-project\tCOMPLETED\t5 min\t${path.join('/job/path', 'diff.patch')}\t${path.join('/job/path', 'summary', 'summary.md')}\tjob-123\tLANGUAGE_UPGRADE\tJDK8\tJDK17\t/path/here\tclean test-compile\n`
)
)
})

it('Excludes artifact paths for failed jobs', async function () {
sinon.stub(fs, 'existsFile').resolves(false)
await writeToHistoryFile('01/01/25, 10:00 AM', 'test-project', 'FAILED', '5 min', 'job-123', '/job/path')
await writeToHistoryFile(
'01/01/25, 10:00 AM',
'test-project',
'FAILED',
'5 min',
'job-123',
'/job/path',
'LANGUAGE_UPGRADE',
'JDK8',
'JDK17',
'/path/here',
'clean test-compile'
)

const expectedPath = path.join(os.homedir(), '.aws', 'transform', 'transformation_history.tsv')
const fileContent = writtenFiles.get(expectedPath)
Expand All @@ -130,7 +158,7 @@ describe('Transformation History Handler', function () {
it('Appends new job to existing history file', async function () {
const existingContent =
'date\tproject_name\tstatus\tduration\tdiff_patch\tsummary\tjob_id\n' +
'12/31/24, 09:00 AM\told-project\tCOMPLETED\t3 min\t/old/diff.patch\t/old/summary.md\told-job-456\n'
'12/31/24, 09:00 AM\told-project\tCOMPLETED\t3 min\t/old/diff.patch\t/old/summary.md\told-job-456\t/old/path\tLANGUAGE_UPGRADE\tJDK8\tJDK17\t/old/path2\tclean test-compile\n'

writtenFiles.set(
path.join(os.homedir(), '.aws', 'transform', 'transformation_history.tsv'),
Expand All @@ -139,14 +167,28 @@ describe('Transformation History Handler', function () {

sinon.stub(fs, 'existsFile').resolves(true)

await writeToHistoryFile('01/01/25, 10:00 AM', 'new-project', 'FAILED', '2 min', 'new-job-789', '/new/path')
await writeToHistoryFile(
'01/01/25, 10:00 AM',
'new-project',
'FAILED',
'2 min',
'new-job-789',
'/new/path',
'LANGUAGE_UPGRADE',
'JDK8',
'JDK17',
'/path/here',
'clean test-compile'
)

const expectedPath = path.join(os.homedir(), '.aws', 'transform', 'transformation_history.tsv')
const fileContent = writtenFiles.get(expectedPath)

// Verify old data is preserved
assert(
fileContent?.includes('old-project\tCOMPLETED\t3 min\t/old/diff.patch\t/old/summary.md\told-job-456')
fileContent?.includes(
'old-project\tCOMPLETED\t3 min\t/old/diff.patch\t/old/summary.md\told-job-456\t/old/path\tLANGUAGE_UPGRADE\tJDK8\tJDK17\t/old/path2\tclean test-compile\n'
)
)

// Verify new data is added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import assert, { fail } from 'assert'
import * as vscode from 'vscode'
import * as sinon from 'sinon'
import { DB, transformByQState, TransformByQStoppedError } from '../../../codewhisperer/models/model'
import { DB, JDKVersion, transformByQState, TransformByQStoppedError } from '../../../codewhisperer/models/model'
import { stopTransformByQ, finalizeTransformationJob } from '../../../codewhisperer/commands/startTransformByQ'
import { HttpResponse } from 'aws-sdk'
import * as codeWhisperer from '../../../codewhisperer/client/codewhisperer'
Expand Down Expand Up @@ -283,6 +283,8 @@ dependencyManagement:

it(`WHEN update job history called THEN returns details of last run job`, async function () {
transformByQState.setJobId('abc-123')
transformByQState.setSourceJDKVersion(JDKVersion.JDK8)
transformByQState.setTargetJDKVersion(JDKVersion.JDK17)
transformByQState.setProjectName('test-project')
transformByQState.setPolledJobStatus('COMPLETED')
transformByQState.setStartTime('05/03/24, 11:35 AM')
Expand Down
Loading