@@ -109,10 +109,12 @@ export class ArduinoApp {
109
109
* selectable programmer
110
110
* @param {bool } [compile=true] - Indicates whether to compile the code when using the CLI to upload
111
111
*/
112
- public async build ( buildMode : BuildMode , compile : boolean = true ) {
112
+ public async build ( buildMode : BuildMode , compile : boolean , buildDir ?: string ) : Promise < boolean > {
113
113
const dc = DeviceContext . getInstance ( ) ;
114
114
const args : string [ ] = [ ] ;
115
115
let restoreSerialMonitor : boolean = false ;
116
+ let cocopa : ICoCoPaContext ;
117
+
116
118
const boardDescriptor = this . getBoardBuildString ( ) ;
117
119
if ( ! boardDescriptor ) {
118
120
return false ;
@@ -199,10 +201,26 @@ export class ArduinoApp {
199
201
}
200
202
201
203
args . push ( "--port" , dc . port ) ;
204
+ } else if ( buildMode === BuildMode . Analyze ) {
205
+ if ( ! isCompilerParserEnabled ( ) ) {
206
+ return false ;
207
+ }
208
+ cocopa = makeCompilerParserContext ( dc ) ;
209
+ if ( ! this . useArduinoCli ( ) ) {
210
+ args . push ( "--verify" , "--verbose" ) ;
211
+ } else {
212
+ args . push ( "compile" , "--verbose" , "-b" , boardDescriptor ) ;
213
+ }
214
+ } else {
215
+ if ( ! this . useArduinoCli ( ) ) {
216
+ args . push ( "--verify" ) ;
217
+ } else {
218
+ args . push ( "compile" , "-b" , boardDescriptor ) ;
219
+ }
202
220
}
203
221
204
222
const verbose = VscodeSettings . getInstance ( ) . logLevel === "verbose" ;
205
- if ( verbose ) {
223
+ if ( buildMode !== BuildMode . Analyze && verbose ) {
206
224
args . push ( "--verbose" ) ;
207
225
}
208
226
@@ -215,8 +233,8 @@ export class ArduinoApp {
215
233
return false ;
216
234
}
217
235
218
- if ( dc . output && compile ) {
219
- const outputPath = path . resolve ( ArduinoWorkspace . rootPath , dc . output ) ;
236
+ if ( ( buildDir || dc . output ) && compile ) {
237
+ const outputPath = path . resolve ( ArduinoWorkspace . rootPath , buildDir || dc . output ) ;
220
238
const dirPath = path . dirname ( outputPath ) ;
221
239
if ( ! util . directoryExistsSync ( dirPath ) ) {
222
240
logger . notifyUserError ( "InvalidOutPutPath" , new Error ( constants . messages . INVALID_OUTPUT_PATH + outputPath ) ) ;
@@ -230,9 +248,9 @@ export class ArduinoApp {
230
248
args . push ( "--pref" , `build.path=${ outputPath } ` ) ;
231
249
}
232
250
233
- arduinoChannel . info ( `Please see the build logs in Output path: ${ outputPath } ` ) ;
251
+ arduinoChannel . info ( `Please see the build logs in output path: ${ outputPath } ` ) ;
234
252
} else {
235
- const msg = "Output path is not specified. Unable to reuse previously compiled files. Upload could be slow . See README." ;
253
+ const msg = "Output path is not specified. Unable to reuse previously compiled files. Build will be slower . See README." ;
236
254
arduinoChannel . warning ( msg ) ;
237
255
}
238
256
@@ -249,6 +267,9 @@ export class ArduinoApp {
249
267
args . push ( path . join ( ArduinoWorkspace . rootPath , dc . sketch ) ) ;
250
268
251
269
const cleanup = async ( ) => {
270
+ if ( cocopa ) {
271
+ cocopa . conclude ( ) ;
272
+ }
252
273
if ( buildMode === BuildMode . Upload || buildMode === BuildMode . UploadProgrammer ) {
253
274
UsbDetector . getInstance ( ) . resumeListening ( ) ;
254
275
if ( restoreSerialMonitor ) {
@@ -260,7 +281,14 @@ export class ArduinoApp {
260
281
// TODO: Get rid of spawn's channel parameter and just support
261
282
// stdout and stderr callbacks
262
283
const stdoutCallback = ( line : string ) => {
263
- arduinoChannel . channel . append ( line ) ;
284
+ if ( cocopa ) {
285
+ cocopa . callback ( line ) ;
286
+ if ( verbose ) {
287
+ arduinoChannel . channel . append ( line ) ;
288
+ }
289
+ } else {
290
+ arduinoChannel . channel . append ( line ) ;
291
+ }
264
292
}
265
293
266
294
await util . spawn (
@@ -282,12 +310,15 @@ export class ArduinoApp {
282
310
JSON . stringify ( reason ) ;
283
311
arduinoChannel . error ( `${ buildMode } sketch '${ dc . sketch } ': ${ msg } ${ os . EOL } ` ) ;
284
312
} ) ;
313
+
285
314
return success ;
286
315
}
287
316
288
- public async verify ( buildMode : BuildMode , buildDir : string = "" ) {
317
+ public async verify ( buildMode : BuildMode , buildDir ?: string ) : Promise < boolean > {
318
+ const compile = true ;
289
319
const dc = DeviceContext . getInstance ( ) ;
290
320
const args : string [ ] = [ ] ;
321
+ let restoreSerialMonitor : boolean = false ;
291
322
let cocopa : ICoCoPaContext ;
292
323
293
324
const boardDescriptor = this . getBoardBuildString ( ) ;
@@ -307,7 +338,76 @@ export class ArduinoApp {
307
338
await this . getMainSketch ( dc ) ;
308
339
}
309
340
310
- if ( buildMode === BuildMode . Analyze ) {
341
+ const selectSerial = async ( ) => {
342
+ const choice = await vscode . window . showInformationMessage (
343
+ "Serial port is not specified. Do you want to select a serial port for uploading?" ,
344
+ "Yes" , "No" ) ;
345
+ if ( choice === "Yes" ) {
346
+ vscode . commands . executeCommand ( "arduino.selectSerialPort" ) ;
347
+ }
348
+ }
349
+
350
+ if ( buildMode === BuildMode . Upload ) {
351
+ if ( ( ! dc . configuration || ! / u p l o a d _ m e t h o d = [ ^ = , ] * s t [ ^ , ] * l i n k / i. test ( dc . configuration ) ) && ! dc . port ) {
352
+ await selectSerial ( ) ;
353
+ return false ;
354
+ }
355
+
356
+ if ( ! compile && ! this . useArduinoCli ( ) ) {
357
+ arduinoChannel . error ( "This command is only available when using the Arduino CLI" ) ;
358
+ return ;
359
+ }
360
+
361
+ if ( ! this . useArduinoCli ( ) ) {
362
+ args . push ( "--upload" ) ;
363
+ } else {
364
+ // TODO: add the --clean argument to the cli args when v 0.14 is released (this will clean up the build folder after uploading)
365
+ if ( compile ) {
366
+ args . push ( "compile" , "--upload" ) ;
367
+ } else {
368
+ args . push ( "upload" ) ;
369
+ }
370
+ args . push ( "-b" , boardDescriptor ) ;
371
+ }
372
+
373
+ if ( dc . port ) {
374
+ args . push ( "--port" , dc . port ) ;
375
+ }
376
+ } else if ( buildMode === BuildMode . UploadProgrammer ) {
377
+ const programmer = this . getProgrammerString ( ) ;
378
+ if ( ! programmer ) {
379
+ return false ;
380
+ }
381
+ if ( ! dc . port ) {
382
+ await selectSerial ( ) ;
383
+ return false ;
384
+ }
385
+
386
+ if ( ! compile && ! this . useArduinoCli ( ) ) {
387
+ arduinoChannel . error ( "This command is only available when using the Arduino CLI" ) ;
388
+ return ;
389
+ }
390
+
391
+ if ( ! this . useArduinoCli ( ) ) {
392
+ args . push ( "--upload" ) ;
393
+ } else {
394
+ // TODO: add the --clean argument to the cli args when v 0.14 is released (this will clean up the build folder after uploading)
395
+ if ( compile ) {
396
+ args . push ( "compile" , "--upload" ) ;
397
+ } else {
398
+ args . push ( "upload" ) ;
399
+ }
400
+ args . push ( "-b" , boardDescriptor ) ;
401
+ }
402
+
403
+ if ( this . useArduinoCli ( ) ) {
404
+ args . push ( "--programmer" , programmer )
405
+ } else {
406
+ args . push ( "--useprogrammer" , "--pref" , "programmer=arduino:" + programmer )
407
+ }
408
+
409
+ args . push ( "--port" , dc . port ) ;
410
+ } else if ( buildMode === BuildMode . Analyze ) {
311
411
if ( ! isCompilerParserEnabled ( ) ) {
312
412
return false ;
313
413
}
@@ -339,7 +439,7 @@ export class ArduinoApp {
339
439
return false ;
340
440
}
341
441
342
- if ( buildDir || dc . output ) {
442
+ if ( ( buildDir || dc . output ) && compile ) {
343
443
const outputPath = path . resolve ( ArduinoWorkspace . rootPath , buildDir || dc . output ) ;
344
444
const dirPath = path . dirname ( outputPath ) ;
345
445
if ( ! util . directoryExistsSync ( dirPath ) ) {
@@ -354,12 +454,19 @@ export class ArduinoApp {
354
454
args . push ( "--pref" , `build.path=${ outputPath } ` ) ;
355
455
}
356
456
357
- arduinoChannel . info ( `Please see the build logs in Output path: ${ outputPath } ` ) ;
457
+ arduinoChannel . info ( `Please see the build logs in output path: ${ outputPath } ` ) ;
358
458
} else {
359
- const msg = "Output path is not specified. Unable to reuse previously compiled files. Verify could be slow . See README." ;
459
+ const msg = "Output path is not specified. Unable to reuse previously compiled files. Build will be slower . See README." ;
360
460
arduinoChannel . warning ( msg ) ;
361
461
}
362
462
463
+ // stop serial monitor when everything is prepared and good
464
+ // what makes restoring of its previous state easier
465
+ if ( buildMode === BuildMode . Upload || buildMode === BuildMode . UploadProgrammer ) {
466
+ restoreSerialMonitor = await SerialMonitor . getInstance ( ) . closeSerialMonitor ( dc . port ) ;
467
+ UsbDetector . getInstance ( ) . pauseListening ( ) ;
468
+ }
469
+
363
470
let success = false ;
364
471
365
472
// Push sketch as last argument
@@ -369,7 +476,12 @@ export class ArduinoApp {
369
476
if ( cocopa ) {
370
477
cocopa . conclude ( ) ;
371
478
}
372
- await Promise . resolve ( ) ;
479
+ if ( buildMode === BuildMode . Upload || buildMode === BuildMode . UploadProgrammer ) {
480
+ UsbDetector . getInstance ( ) . resumeListening ( ) ;
481
+ if ( restoreSerialMonitor ) {
482
+ await SerialMonitor . getInstance ( ) . openSerialMonitor ( ) ;
483
+ }
484
+ }
373
485
}
374
486
375
487
// TODO: Get rid of spawn's channel parameter and just support
0 commit comments