From f2927ec1542ef2c5944fce0fb19b73a4ded54166 Mon Sep 17 00:00:00 2001 From: Fran Aguilera Date: Tue, 18 May 2021 19:00:46 -0400 Subject: [PATCH 1/4] Added successfulbuild and failedbuild External commands. Issue: Provide the option to run a script/command after every verify. #1266 --- README.md | 6 +++++- misc/arduinoValidator.json | 10 ++++++++++ src/arduino/arduino.ts | 33 ++++++++++++++++++++++++++++----- src/deviceContext.ts | 10 ++++++++++ src/deviceSettings.ts | 10 ++++++++++ 5 files changed, 63 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3935ca40..28a251ce 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,8 @@ The following settings are as per sketch settings of the Arduino extension. You "output": "../build", "debugger": "jlink", "prebuild": "./prebuild.sh", + "succesfullbuild": "./successfulbuild.sh", + "failedbuild": "./successfulbuild.sh", "postbuild": "./postbuild.sh", "intelliSenseGen": "global" } @@ -122,7 +124,9 @@ The following settings are as per sketch settings of the Arduino extension. You - `output` - Arduino build output path. If not set, Arduino will create a new temporary output folder each time, which means it cannot reuse the intermediate result of the previous build leading to long verify/upload time, so it is recommended to set the field. Arduino requires that the output path should not be the workspace itself or in a subfolder of the workspace, otherwise, it may not work correctly. By default, this option is not set. It's worth noting that the contents of this file could be deleted during the build process, so pick (or create) a directory that will not store files you want to keep. - `debugger` - The short name of the debugger that will be used when the board itself does not have a debugger and there is more than one debugger available. You can find the list of debuggers [here](https://github.com/Microsoft/vscode-arduino/blob/master/misc/debuggerUsbMapping.json). By default, this option is not set. - `prebuild` - External command which will be invoked before any sketch build (verify, upload, ...). For details see the [Pre- and Post-Build Commands](#Pre--and-Post-Build-Commands) section. -- `postbuild` - External command to be run after the sketch has been built successfully. See the afore mentioned section for more details. +- `successfulbuild` - External command to be run if the sketch fails to be built. +- `successfulbuild` - External command to be run after the sketch has been built successfully. See the afore mentioned section for more details. +- `postbuild` - External command to be run after every sketch build. - `intelliSenseGen` - Override the global setting for auto-generation of the IntelliSense configuration (i.e. `.vscode/c_cpp_properties.json`). Three options are available: - `"global"`: Use the global settings (default) - `"disable"`: Disable the auto-generation even if globally enabled diff --git a/misc/arduinoValidator.json b/misc/arduinoValidator.json index 5386fc4f..366e311f 100644 --- a/misc/arduinoValidator.json +++ b/misc/arduinoValidator.json @@ -48,6 +48,16 @@ "type": "string", "minLength": 1 }, + "successfulbuild": { + "description": "Command to be run after every successful build", + "type": "string", + "minLength": 1 + }, + "failedbuild": { + "description": "Command to be run after every failed build", + "type": "string", + "minLength": 1 + }, "postbuild": { "description": "Command to be run after every build", "type": "string", diff --git a/src/arduino/arduino.ts b/src/arduino/arduino.ts index 785df236..912f43ae 100644 --- a/src/arduino/arduino.ts +++ b/src/arduino/arduino.ts @@ -443,10 +443,29 @@ export class ArduinoApp { */ protected async runPrePostBuildCommand(dc: DeviceContext, environment: any, - what: "pre" | "post"): Promise { - const cmdline = what === "pre" - ? dc.prebuild - : dc.postbuild; + what: "pre" | "success" | "failed" | "post"): Promise { + let cmdline; + switch(what) { + case "pre": { + cmdline = dc.prebuild; + break; + } + case "success": { + cmdline = dc.successfulbuild; + break; + } + case "failed": { + cmdline = dc.failedbuild; + break; + } + case "post": { + cmdline = dc.postbuild; + break; + } + default: { + break; + } + } if (!cmdline) { return true; // Successfully done nothing. @@ -714,8 +733,12 @@ export class ArduinoApp { const cleanup = async (result: "ok" | "error") => { let ret = true; if (result === "ok") { - ret = await this.runPrePostBuildCommand(dc, env, "post"); + ret = await this.runPrePostBuildCommand(dc, env, "success"); + } else { + ret = await this.runPrePostBuildCommand(dc, env, "failed"); } + // Do we need to handle a return value for this case? + await this.runPrePostBuildCommand(dc, env, "post"); await cocopa.conclude(); if (buildMode === BuildMode.Upload || buildMode === BuildMode.UploadProgrammer) { UsbDetector.getInstance().resumeListening(); diff --git a/src/deviceContext.ts b/src/deviceContext.ts index 0cfaa358..372dcd98 100644 --- a/src/deviceContext.ts +++ b/src/deviceContext.ts @@ -187,6 +187,8 @@ export class DeviceContext implements IDeviceContext, vscode.Disposable { public get onChangeISAutoGen() { return this._settings.intelliSenseGen.emitter.event } public get onChangeConfiguration() { return this._settings.configuration.emitter.event } public get onChangePrebuild() { return this._settings.prebuild.emitter.event } + public get onChangeSuccessfulbuild() { return this._settings.successfulbuild.emitter.event } + public get onChangeFailedbuild() { return this._settings.failedbuild.emitter.event } public get onChangePostbuild() { return this._settings.postbuild.emitter.event } public get onChangeProgrammer() { return this._settings.programmer.emitter.event } @@ -221,6 +223,14 @@ export class DeviceContext implements IDeviceContext, vscode.Disposable { return this._settings.prebuild.value; } + public get successfulbuild() { + return this._settings.successfulbuild.value; + } + + public get failedbuild() { + return this._settings.failedbuild.value; + } + public get postbuild() { return this._settings.postbuild.value; } diff --git a/src/deviceSettings.ts b/src/deviceSettings.ts index 439c4ee0..8d115f6d 100644 --- a/src/deviceSettings.ts +++ b/src/deviceSettings.ts @@ -141,6 +141,8 @@ export class DeviceSettings { public intelliSenseGen = new StrSetting(); public configuration = new StrSetting(); public prebuild = new StrSetting(); + public successfulbuild = new StrSetting(); + public failedbuild = new StrSetting(); public postbuild = new StrSetting(); public programmer = new StrSetting(); public buildPreferences = new BuildPrefSetting(); @@ -158,6 +160,8 @@ export class DeviceSettings { this.intelliSenseGen.modified || this.configuration.modified || this.prebuild.modified || + this.successfulbuild.modified || + this.failedbuild.modified || this.postbuild.modified || this.programmer.modified || this.buildPreferences.modified; @@ -174,6 +178,8 @@ export class DeviceSettings { this.intelliSenseGen.commit(); this.configuration.commit(); this.prebuild.commit(); + this.successfulbuild.commit(); + this.failedbuild.commit(); this.postbuild.commit(); this.programmer.commit(); this.buildPreferences.commit(); @@ -192,6 +198,8 @@ export class DeviceSettings { this.intelliSenseGen.reset(); this.configuration.reset(); this.prebuild.reset(); + this.successfulbuild.reset(); + this.failedbuild.reset(); this.postbuild.reset(); this.programmer.reset(); this.buildPreferences.reset(); @@ -218,6 +226,8 @@ export class DeviceSettings { this.debugger.value = settings.debugger; this.intelliSenseGen.value = settings.intelliSenseGen; this.prebuild.value = settings.prebuild; + this.successfulbuild.value = settings.successfulbuild; + this.failedbuild.value = settings.failedbuild; this.postbuild.value = settings.postbuild; this.programmer.value = settings.programmer; this.buildPreferences.value = settings.buildPreferences; From 68e4eeb0be7048b8616de249ae142ca3aa452c86 Mon Sep 17 00:00:00 2001 From: Fran Aguilera Date: Tue, 18 May 2021 19:13:22 -0400 Subject: [PATCH 2/4] Updated README. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 28a251ce..40991f77 100644 --- a/README.md +++ b/README.md @@ -124,9 +124,9 @@ The following settings are as per sketch settings of the Arduino extension. You - `output` - Arduino build output path. If not set, Arduino will create a new temporary output folder each time, which means it cannot reuse the intermediate result of the previous build leading to long verify/upload time, so it is recommended to set the field. Arduino requires that the output path should not be the workspace itself or in a subfolder of the workspace, otherwise, it may not work correctly. By default, this option is not set. It's worth noting that the contents of this file could be deleted during the build process, so pick (or create) a directory that will not store files you want to keep. - `debugger` - The short name of the debugger that will be used when the board itself does not have a debugger and there is more than one debugger available. You can find the list of debuggers [here](https://github.com/Microsoft/vscode-arduino/blob/master/misc/debuggerUsbMapping.json). By default, this option is not set. - `prebuild` - External command which will be invoked before any sketch build (verify, upload, ...). For details see the [Pre- and Post-Build Commands](#Pre--and-Post-Build-Commands) section. -- `successfulbuild` - External command to be run if the sketch fails to be built. - `successfulbuild` - External command to be run after the sketch has been built successfully. See the afore mentioned section for more details. -- `postbuild` - External command to be run after every sketch build. +- `failedbuild` - External command to be run if the sketch fails to be built. See the afore mentioned section for more details. +- `postbuild` - External command to be run after every sketch build. See the afore mentioned section for more details. - `intelliSenseGen` - Override the global setting for auto-generation of the IntelliSense configuration (i.e. `.vscode/c_cpp_properties.json`). Three options are available: - `"global"`: Use the global settings (default) - `"disable"`: Disable the auto-generation even if globally enabled From 7dc4778689af29be44cbdcd96bb56dec6f7d5933 Mon Sep 17 00:00:00 2001 From: Fran Aguilera Date: Tue, 18 May 2021 19:41:01 -0400 Subject: [PATCH 3/4] Updated documentation again. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 40991f77..2c8878c2 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ The following settings are as per sketch settings of the Arduino extension. You } ``` -## Pre- and Post-Build Commands +## Pre-, Successful-, Failed-, and Post-Build Commands On Windows the commands run within a `cmd`-, on Linux and OSX within a `bash`-instance. Therefore your command can be anything what you can run within those shells. Instead of running a command you can invoke a script. This makes writing more complex pre-/post-build mechanisms much easier and opens up the possibility to run python or other scripting languages. The commands run within the workspace root directory and vscode-arduino sets the following environment variables: **`VSCA_BUILD_MODE`** The current build mode, one of `Verifying`, `Uploading`, `Uploading (programmer)` or `Analyzing`. This allows you to run your script on certain build modes only. From b78897ff5dc2d374d82434d25b26fa1d0ec730e3 Mon Sep 17 00:00:00 2001 From: Fran Aguilera Date: Tue, 18 May 2021 19:51:32 -0400 Subject: [PATCH 4/4] Added return. --- src/arduino/arduino.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/arduino/arduino.ts b/src/arduino/arduino.ts index 912f43ae..753de84f 100644 --- a/src/arduino/arduino.ts +++ b/src/arduino/arduino.ts @@ -737,8 +737,7 @@ export class ArduinoApp { } else { ret = await this.runPrePostBuildCommand(dc, env, "failed"); } - // Do we need to handle a return value for this case? - await this.runPrePostBuildCommand(dc, env, "post"); + ret = await this.runPrePostBuildCommand(dc, env, "post"); await cocopa.conclude(); if (buildMode === BuildMode.Upload || buildMode === BuildMode.UploadProgrammer) { UsbDetector.getInstance().resumeListening();