Skip to content

Commit 63beacc

Browse files
authored
Merge pull request #5402 from dhasani23/pomParse
feat(amazonq): parse pom.xml for absolute paths
2 parents 0c44f1e + 23f4575 commit 63beacc

File tree

7 files changed

+73
-13
lines changed

7 files changed

+73
-13
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Feature",
3+
"description": "Amazon Q Code Transformation: warn user if absolute file paths are found in the pom.xml"
4+
}

packages/core/src/amazonqGumby/chat/controller/controller.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
getValidCandidateProjects,
2323
openBuildLogFile,
2424
openHilPomFile,
25+
parseBuildFile,
2526
postTransformationJob,
2627
processTransformFormInput,
2728
startTransformByQ,
@@ -31,6 +32,7 @@ import {
3132
} from '../../../codewhisperer/commands/startTransformByQ'
3233
import { JDKVersion, TransformationCandidateProject, transformByQState } from '../../../codewhisperer/models/model'
3334
import {
35+
AbsolutePathDetectedError,
3436
AlternateDependencyVersionsNotFoundError,
3537
JavaHomeNotSetError,
3638
JobStartError,
@@ -424,6 +426,9 @@ export class GumbyController {
424426
return
425427
}
426428

429+
// give user a non-blocking warning if build file appears to contain absolute paths
430+
await parseBuildFile()
431+
427432
this.messenger.sendAsyncEventProgress(
428433
message.tabID,
429434
true,
@@ -513,7 +518,7 @@ export class GumbyController {
513518

514519
private async handleError(message: { error: Error; tabID: string }) {
515520
if (message.error instanceof AlternateDependencyVersionsNotFoundError) {
516-
this.messenger.sendKnownErrorResponse('no-alternate-dependencies-found', message.tabID)
521+
this.messenger.sendKnownErrorResponse(message.tabID, CodeWhispererConstants.dependencyVersionsErrorMessage)
517522
await this.continueTransformationWithoutHIL(message)
518523
} else if (message.error instanceof ModuleUploadError) {
519524
this.resetTransformationChatFlow()
@@ -529,6 +534,8 @@ export class GumbyController {
529534
)
530535
await openBuildLogFile()
531536
this.messenger.sendViewBuildLog(message.tabID)
537+
} else if (message.error instanceof AbsolutePathDetectedError) {
538+
this.messenger.sendKnownErrorResponse(message.tabID, message.error.message)
532539
}
533540
}
534541

packages/core/src/amazonqGumby/chat/controller/messenger/messenger.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ export type UnrecoverableErrorType =
4646
| 'upload-to-s3-failed'
4747
| 'job-start-failed'
4848

49-
export type ErrorResponseType = 'no-alternate-dependencies-found'
50-
5149
export enum GumbyNamedMessages {
5250
COMPILATION_PROGRESS_MESSAGE = 'gumbyProjectCompilationMessage',
5351
JOB_SUBMISSION_STATUS_MESSAGE = 'gumbyJobSubmissionMessage',
@@ -356,15 +354,7 @@ export class Messenger {
356354
* informational purposes, or some other error workflow is meant to contribute a
357355
* follow-up with a user action.
358356
*/
359-
public sendKnownErrorResponse(type: ErrorResponseType, tabID: string) {
360-
let message = '...'
361-
362-
switch (type) {
363-
case 'no-alternate-dependencies-found':
364-
message = `I could not find any other versions of this dependency in your local Maven repository. Try transforming the dependency to make it compatible with Java 17, and then try transforming this module again.`
365-
break
366-
}
367-
357+
public sendKnownErrorResponse(tabID: string, message: string) {
368358
this.dispatcher.sendChatMessage(
369359
new ChatMessage(
370360
{

packages/core/src/amazonqGumby/errors.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,9 @@ export class PollJobError extends Error {
7171
super('Poll job failed')
7272
}
7373
}
74+
75+
export class AbsolutePathDetectedError extends Error {
76+
constructor(message: string) {
77+
super(message)
78+
}
79+
}

packages/core/src/codewhisperer/commands/startTransformByQ.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import { MetadataResult } from '../../shared/telemetry/telemetryClient'
5050
import { submitFeedback } from '../../feedback/vue/submitFeedback'
5151
import { placeholder } from '../../shared/vscode/commands2'
5252
import {
53+
AbsolutePathDetectedError,
5354
AlternateDependencyVersionsNotFoundError,
5455
JavaHomeNotSetError,
5556
JobStartError,
@@ -235,6 +236,41 @@ export async function finalizeTransformByQ(status: string) {
235236
}
236237
}
237238

239+
export async function parseBuildFile() {
240+
try {
241+
const absolutePaths = ['users/', 'system/', 'volumes/', 'c:\\', 'd:\\']
242+
const alias = path.basename(os.homedir())
243+
absolutePaths.push(alias)
244+
const buildFilePath = path.join(transformByQState.getProjectPath(), 'pom.xml')
245+
if (fs.existsSync(buildFilePath)) {
246+
const buildFileContents = fs.readFileSync(buildFilePath).toString().toLowerCase()
247+
const detectedPaths = []
248+
for (const absolutePath of absolutePaths) {
249+
if (buildFileContents.includes(absolutePath)) {
250+
detectedPaths.push(absolutePath)
251+
}
252+
}
253+
if (detectedPaths.length > 0) {
254+
const warningMessage = CodeWhispererConstants.absolutePathDetectedMessage(
255+
detectedPaths.length,
256+
path.basename(buildFilePath),
257+
detectedPaths.join(', ')
258+
)
259+
transformByQState.getChatControllers()?.errorThrown.fire({
260+
error: new AbsolutePathDetectedError(warningMessage),
261+
tabID: ChatSessionManager.Instance.getSession().tabID,
262+
})
263+
getLogger().info('CodeTransformation: absolute path potentially in build file')
264+
return warningMessage
265+
}
266+
}
267+
} catch (err: any) {
268+
// swallow error
269+
getLogger().error(`CodeTransformation: error scanning for absolute paths, tranformation continuing: ${err}`)
270+
}
271+
return undefined
272+
}
273+
238274
export async function preTransformationUploadCode() {
239275
await vscode.commands.executeCommand('aws.amazonq.transformationHub.focus')
240276

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,9 @@ export const buildSucceededChatMessage = 'I was able to build your project and w
454454
export const buildSucceededNotification =
455455
'Amazon Q was able to build your project and will start transforming your code soon.'
456456

457+
export const absolutePathDetectedMessage = (numPaths: number, buildFile: string, listOfPaths: string) =>
458+
`I detected ${numPaths} potential absolute file path(s) in your ${buildFile} file: **${listOfPaths}**. Absolute file paths might cause issues when I build your code. Any errors will show up in the build log.`
459+
457460
export const unsupportedJavaVersionChatMessage = `Sorry, currently I can only upgrade Java 8 or Java 11 projects. For more information, see the [Amazon Q documentation](${codeTransformPrereqDoc}).`
458461

459462
export const failedToStartJobChatMessage =
@@ -528,6 +531,9 @@ export const noPomXmlFoundNotification = `None of your open projects are support
528531

529532
export const noJavaHomeFoundChatMessage = `Sorry, I couldn\'t locate your Java installation. For more information, see the [Amazon Q documentation](${codeTransformPrereqDoc}).`
530533

534+
export const dependencyVersionsErrorMessage =
535+
'I could not find any other versions of this dependency in your local Maven repository. Try transforming the dependency to make it compatible with Java 17, and then try transforming this module again.'
536+
531537
export const errorUploadingWithExpiredUrl = `The upload error may have been caused by the expiration of the S3 pre-signed URL that was used to upload code artifacts to Q Code Transformation. The S3 pre-signed URL expires in 30 minutes. This could be caused by any delays introduced by intermediate services in your network infrastructure. Please investigate your network configuration and consider allowlisting 'amazonq-code-transformation-us-east-1-c6160f047e0.s3.amazonaws.com' to skip any scanning that might delay the upload. For more information, see the [Amazon Q documentation](${codeTransformTroubleshootAllowS3Access}).`
532538

533539
export const socketConnectionFailed =

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import * as fs from 'fs-extra'
99
import * as sinon from 'sinon'
1010
import { makeTemporaryToolkitFolder } from '../../../shared/filesystemUtilities'
1111
import { transformByQState, TransformByQStoppedError } from '../../../codewhisperer/models/model'
12-
import { stopTransformByQ } from '../../../codewhisperer/commands/startTransformByQ'
12+
import { parseBuildFile, stopTransformByQ } from '../../../codewhisperer/commands/startTransformByQ'
1313
import { HttpResponse } from 'aws-sdk'
1414
import * as codeWhisperer from '../../../codewhisperer/client/codewhisperer'
1515
import * as CodeWhispererConstants from '../../../codewhisperer/models/constants'
@@ -297,4 +297,15 @@ describe('transformByQ', function () {
297297
}
298298
assert.deepStrictEqual(actual, expected)
299299
})
300+
301+
it(`WHEN parseBuildFile on pom.xml with absolute path THEN absolute path detected`, async function () {
302+
const dirPath = await createTestWorkspaceFolder()
303+
transformByQState.setProjectPath(dirPath.uri.fsPath)
304+
const pomPath = path.join(dirPath.uri.fsPath, 'pom.xml')
305+
await toFile('<project><properties><path>system/name/here</path></properties></project>', pomPath)
306+
const expectedWarning =
307+
'I detected 1 potential absolute file path(s) in your pom.xml file: **system/**. Absolute file paths might cause issues when I build your code. Any errors will show up in the build log.'
308+
const warningMessage = await parseBuildFile()
309+
assert.strictEqual(expectedWarning, warningMessage)
310+
})
300311
})

0 commit comments

Comments
 (0)