@@ -27,6 +27,7 @@ import {
27
27
startTransformByQ ,
28
28
stopTransformByQ ,
29
29
validateCanCompileProject ,
30
+ setMaven ,
30
31
} from '../../../codewhisperer/commands/startTransformByQ'
31
32
import { JDKVersion , TransformationCandidateProject , transformByQState } from '../../../codewhisperer/models/model'
32
33
import {
@@ -53,6 +54,8 @@ import { getAuthType } from '../../../codewhisperer/service/transformByQ/transfo
53
54
import DependencyVersions from '../../models/dependencies'
54
55
import { getStringHash } from '../../../shared/utilities/textUtilities'
55
56
import { getTelemetryReasonDesc } from '../../../shared/errors'
57
+ import { getVersionData } from '../../../codewhisperer/service/transformByQ/transformMavenHandler'
58
+
56
59
// These events can be interactions within the chat,
57
60
// or elsewhere in the IDE
58
61
export interface ChatControllerEventEmitters {
@@ -179,47 +182,64 @@ export class GumbyController {
179
182
}
180
183
181
184
private async transformInitiated ( message : any ) {
182
- // check that a project is open
183
- const workspaceFolders = vscode . workspace . workspaceFolders
184
- if ( workspaceFolders === undefined || workspaceFolders . length === 0 ) {
185
- this . messenger . sendUnrecoverableErrorResponse ( 'no-project-found' , message . tabID )
186
- return
187
- }
188
-
189
- // check that the session is authenticated
185
+ // Start /transform chat flow
190
186
const session : Session = this . sessionStorage . getSession ( )
191
- try {
192
- const authState = await AuthUtil . instance . getChatAuthState ( )
193
- if ( authState . amazonQ !== 'connected' ) {
194
- void this . messenger . sendAuthNeededExceptionMessage ( authState , message . tabID )
195
- session . isAuthenticating = true
196
- return
197
- }
187
+ CodeTransformTelemetryState . instance . setSessionId ( )
198
188
199
- switch ( this . sessionStorage . getSession ( ) . conversationState ) {
200
- case ConversationState . JOB_SUBMITTED :
201
- this . messenger . sendAsyncEventProgress (
202
- message . tabID ,
203
- true ,
204
- undefined ,
205
- GumbyNamedMessages . JOB_SUBMISSION_STATUS_MESSAGE
206
- )
207
- this . messenger . sendJobSubmittedMessage ( message . tabID )
189
+ try {
190
+ await telemetry . codeTransform_initiateTransform . run ( async ( ) => {
191
+ const authType = await getAuthType ( )
192
+ telemetry . record ( {
193
+ codeTransformSessionId : CodeTransformTelemetryState . instance . getSessionId ( ) ,
194
+ credentialSourceId : authType ,
195
+ } )
196
+
197
+ // check that a project is open
198
+ const workspaceFolders = vscode . workspace . workspaceFolders
199
+ if ( workspaceFolders === undefined || workspaceFolders . length === 0 ) {
200
+ this . messenger . sendUnrecoverableErrorResponse ( 'no-project-found' , message . tabID )
201
+ telemetry . record ( { result : MetadataResult . Fail , reason : 'no-project-found' } )
208
202
return
209
- case ConversationState . COMPILING :
210
- this . messenger . sendAsyncEventProgress (
211
- message . tabID ,
212
- true ,
213
- undefined ,
214
- GumbyNamedMessages . COMPILATION_PROGRESS_MESSAGE
215
- )
216
- this . messenger . sendCompilationInProgress ( message . tabID )
203
+ }
204
+
205
+ // check that the session is authenticated
206
+ const authState = await AuthUtil . instance . getChatAuthState ( )
207
+ if ( authState . amazonQ !== 'connected' ) {
208
+ void this . messenger . sendAuthNeededExceptionMessage ( authState , message . tabID )
209
+ session . isAuthenticating = true
210
+ telemetry . record ( { result : MetadataResult . Fail , reason : 'auth-failed' } )
217
211
return
218
- }
219
- CodeTransformTelemetryState . instance . setSessionId ( )
220
- this . messenger . sendTransformationIntroduction ( message . tabID )
212
+ }
221
213
222
- // start /transform chat flow
214
+ // If previous transformation was already running
215
+ switch ( this . sessionStorage . getSession ( ) . conversationState ) {
216
+ case ConversationState . JOB_SUBMITTED :
217
+ this . messenger . sendAsyncEventProgress (
218
+ message . tabID ,
219
+ true ,
220
+ undefined ,
221
+ GumbyNamedMessages . JOB_SUBMISSION_STATUS_MESSAGE
222
+ )
223
+ this . messenger . sendJobSubmittedMessage ( message . tabID )
224
+ return
225
+ case ConversationState . COMPILING :
226
+ this . messenger . sendAsyncEventProgress (
227
+ message . tabID ,
228
+ true ,
229
+ undefined ,
230
+ GumbyNamedMessages . COMPILATION_PROGRESS_MESSAGE
231
+ )
232
+ this . messenger . sendCompilationInProgress ( message . tabID )
233
+ return
234
+ }
235
+ this . messenger . sendTransformationIntroduction ( message . tabID )
236
+ } )
237
+ } catch ( e : any ) {
238
+ // if there was an issue getting the list of valid projects, the error message will be shown here
239
+ this . messenger . sendErrorMessage ( e . message , message . tabID )
240
+ }
241
+
242
+ try {
223
243
const validProjects = await this . validateProjectsWithReplyOnError ( message )
224
244
if ( validProjects . length > 0 ) {
225
245
this . sessionStorage . getSession ( ) . updateCandidateProjects ( validProjects )
@@ -233,14 +253,30 @@ export class GumbyController {
233
253
234
254
private async validateProjectsWithReplyOnError ( message : any ) : Promise < TransformationCandidateProject [ ] > {
235
255
let telemetryJavaVersion = JDKToTelemetryValue ( JDKVersion . UNSUPPORTED ) as CodeTransformJavaSourceVersionsAllowed
256
+
236
257
let err
237
258
try {
238
- const validProjects = await getValidCandidateProjects ( )
239
- if ( validProjects . length > 0 ) {
240
- // validProjects[0].JDKVersion will be undefined if javap errors out or no .class files found, so call it UNSUPPORTED
241
- const javaVersion = validProjects [ 0 ] . JDKVersion ?? JDKVersion . UNSUPPORTED
242
- telemetryJavaVersion = JDKToTelemetryValue ( javaVersion ) as CodeTransformJavaSourceVersionsAllowed
243
- }
259
+ const validProjects = await telemetry . codeTransform_validateProject . run ( async ( ) => {
260
+ telemetry . record ( {
261
+ codeTransformBuildSystem : 'Maven' , // default for Maven until we add undefined field to CodeTransformBuildSystem
262
+ codeTransformSessionId : CodeTransformTelemetryState . instance . getSessionId ( ) ,
263
+ } )
264
+
265
+ const validProjects = await getValidCandidateProjects ( )
266
+ if ( validProjects . length > 0 ) {
267
+ // validProjects[0].JDKVersion will be undefined if javap errors out or no .class files found, so call it UNSUPPORTED
268
+ const javaVersion = validProjects [ 0 ] . JDKVersion ?? JDKVersion . UNSUPPORTED
269
+ telemetryJavaVersion = JDKToTelemetryValue ( javaVersion ) as CodeTransformJavaSourceVersionsAllowed
270
+ }
271
+ telemetry . record ( { codeTransformLocalJavaVersion : telemetryJavaVersion } )
272
+
273
+ await setMaven ( )
274
+ const versionInfo = await getVersionData ( )
275
+ const mavenVersionInfoMessage = `${ versionInfo [ 0 ] } (${ transformByQState . getMavenName ( ) } )`
276
+ telemetry . record ( { buildSystemVersion : mavenVersionInfoMessage } )
277
+
278
+ return validProjects
279
+ } )
244
280
return validProjects
245
281
} catch ( e : any ) {
246
282
if ( e instanceof NoJavaProjectsFoundError ) {
@@ -252,7 +288,7 @@ export class GumbyController {
252
288
}
253
289
err = e
254
290
} finally {
255
- // New projectDetails metric should always be fired whether the project was valid or invalid
291
+ // TODO: remove deprecated metric once BI started using new metrics
256
292
telemetry . codeTransform_projectDetails . emit ( {
257
293
passive : true ,
258
294
codeTransformSessionId : CodeTransformTelemetryState . instance . getSessionId ( ) ,
@@ -269,9 +305,14 @@ export class GumbyController {
269
305
const typedAction = MessengerUtils . stringToEnumValue ( ButtonActions , message . action as any )
270
306
switch ( typedAction ) {
271
307
case ButtonActions . CONFIRM_TRANSFORMATION_FORM :
272
- await this . initiateTransformationOnProject ( message )
308
+ await this . handleUserProjectSelection ( message )
273
309
break
274
310
case ButtonActions . CANCEL_TRANSFORMATION_FORM :
311
+ telemetry . codeTransform_submitSelection . emit ( {
312
+ codeTransformSessionId : CodeTransformTelemetryState . instance . getSessionId ( ) ,
313
+ userChoice : 'Cancel' ,
314
+ result : MetadataResult . Pass ,
315
+ } )
275
316
this . messenger . sendJobFinishedMessage ( message . tabID , CodeWhispererConstants . jobCancelledChatMessage )
276
317
break
277
318
case ButtonActions . VIEW_TRANSFORMATION_HUB :
@@ -306,27 +347,38 @@ export class GumbyController {
306
347
}
307
348
308
349
// prompt user to pick project and specify source JDK version
309
- private async initiateTransformationOnProject ( message : any ) {
310
- const authType = await getAuthType ( )
311
- telemetry . codeTransform_jobStart . emit ( {
312
- codeTransformSessionId : CodeTransformTelemetryState . instance . getSessionId ( ) ,
313
- credentialSourceId : authType ,
314
- result : MetadataResult . Pass ,
315
- } )
316
- const pathToProject : string = message . formSelectedValues [ 'GumbyTransformProjectForm' ]
317
- const toJDKVersion : JDKVersion = message . formSelectedValues [ 'GumbyTransformJdkToForm' ]
318
- const fromJDKVersion : JDKVersion = message . formSelectedValues [ 'GumbyTransformJdkFromForm' ]
350
+ private async handleUserProjectSelection ( message : any ) {
351
+ await telemetry . codeTransform_submitSelection . run ( async ( ) => {
352
+ const pathToProject : string = message . formSelectedValues [ 'GumbyTransformProjectForm' ]
353
+ const toJDKVersion : JDKVersion = message . formSelectedValues [ 'GumbyTransformJdkToForm' ]
354
+ const fromJDKVersion : JDKVersion = message . formSelectedValues [ 'GumbyTransformJdkFromForm' ]
355
+
356
+ telemetry . record ( {
357
+ codeTransformJavaSourceVersionsAllowed : JDKToTelemetryValue (
358
+ fromJDKVersion
359
+ ) as CodeTransformJavaSourceVersionsAllowed ,
360
+ codeTransformJavaTargetVersionsAllowed : JDKToTelemetryValue (
361
+ toJDKVersion
362
+ ) as CodeTransformJavaTargetVersionsAllowed ,
363
+ codeTransformProjectId : pathToProject === undefined ? telemetryUndefined : getStringHash ( pathToProject ) ,
364
+ userChoice : 'Confirm' ,
365
+ } )
319
366
320
- const projectName = path . basename ( pathToProject )
321
- this . messenger . sendProjectSelectionMessage ( projectName , fromJDKVersion , toJDKVersion , message . tabID )
367
+ const projectName = path . basename ( pathToProject )
368
+ this . messenger . sendProjectSelectionMessage ( projectName , fromJDKVersion , toJDKVersion , message . tabID )
322
369
323
- if ( fromJDKVersion === JDKVersion . UNSUPPORTED ) {
324
- this . messenger . sendUnrecoverableErrorResponse ( 'unsupported-source-jdk-version' , message . tabID )
325
- return
326
- }
370
+ if ( fromJDKVersion === JDKVersion . UNSUPPORTED ) {
371
+ this . messenger . sendUnrecoverableErrorResponse ( 'unsupported-source-jdk-version' , message . tabID )
372
+ telemetry . record ( {
373
+ result : MetadataResult . Fail ,
374
+ reason : 'unsupported-source-jdk-version' ,
375
+ } )
376
+ return
377
+ }
327
378
328
- await processTransformFormInput ( pathToProject , fromJDKVersion , toJDKVersion )
329
- await this . validateBuildWithPromptOnError ( message )
379
+ await processTransformFormInput ( pathToProject , fromJDKVersion , toJDKVersion )
380
+ await this . validateBuildWithPromptOnError ( message )
381
+ } )
330
382
}
331
383
332
384
private async prepareProjectForSubmission ( message : { pathToJavaHome : string ; tabID : string } ) : Promise < void > {
@@ -338,6 +390,7 @@ export class GumbyController {
338
390
}
339
391
340
392
const projectPath = transformByQState . getProjectPath ( )
393
+ // TODO: remove deprecated metric once BI started using new metrics
341
394
telemetry . codeTransform_jobStartedCompleteFromPopupDialog . emit ( {
342
395
codeTransformSessionId : CodeTransformTelemetryState . instance . getSessionId ( ) ,
343
396
codeTransformJavaSourceVersionsAllowed : JDKToTelemetryValue (
@@ -349,6 +402,8 @@ export class GumbyController {
349
402
codeTransformProjectId : projectPath === undefined ? telemetryUndefined : getStringHash ( projectPath ) ,
350
403
result : MetadataResult . Pass ,
351
404
} )
405
+
406
+ // Pre-build project locally
352
407
try {
353
408
this . sessionStorage . getSession ( ) . conversationState = ConversationState . COMPILING
354
409
this . messenger . sendCompilationInProgress ( message . tabID )
@@ -382,6 +437,7 @@ export class GumbyController {
382
437
383
438
private async validateBuildWithPromptOnError ( message : any | undefined = undefined ) : Promise < void > {
384
439
try {
440
+ // Check Java Home is set (not yet prebuilding)
385
441
await validateCanCompileProject ( )
386
442
} catch ( err : any ) {
387
443
if ( err instanceof JavaHomeNotSetError ) {
0 commit comments