Skip to content
This repository was archived by the owner on Dec 22, 2024. It is now read-only.

Commit 209c9b7

Browse files
elektronikworkshophlovdal
authored andcommitted
Added post build command support:
* Added post build command support * Added validator for both pre and post build (former was missing) Yet to be decided: Solution for analysis run: with or without pre/post build? Addresses microsoft#786
1 parent 6de3054 commit 209c9b7

File tree

5 files changed

+54
-13
lines changed

5 files changed

+54
-13
lines changed

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ The following settings are as per sketch settings of the Arduino extension. You
102102
"output": "../build",
103103
"debugger": "jlink",
104104
"prebuild": "bash prebuild.sh",
105+
"postbuild": "bash postbuild.sh",
105106
"intelliSenseGen": "global"
106107
}
107108
```
@@ -110,7 +111,8 @@ The following settings are as per sketch settings of the Arduino extension. You
110111
- `board` - Currently selected Arduino board alias. Can be set by the `Arduino: Change Board Type` command. Also, you can find the board list there.
111112
- `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.
112113
- `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.
113-
- `prebuild` - External command before building the sketch file. You should only set one `prebuild` command. `command1 && command2` does not work. If you need to run multiple commands before the build, then create a script.
114+
- `prebuild` - External command which will be invoked before any sketch build (verify, upload). You must only set one `prebuild` command. `command1 && command2` does not work. If you need to run multiple commands before the build, then create a script.
115+
- `postbuild` - External command to be run after the sketch has been built successfully. Same rules as for `prebuild` apply. <!-- TODO: note about cwd would be a good thing -->
114116
- `intelliSenseGen` - Override the global setting for auto-generation of the IntelliSense configuration (i.e. `.vscode/c_cpp_properties.json`). Three options are available:
115117
- `"global"`: Use the global settings (default)
116118
- `"disable"`: Disable the auto-generation even if globally enabled

misc/arduinoValidator.json

+11-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@
4242
"disable",
4343
"enable"
4444
]
45-
}
45+
},
46+
"prebuild": {
47+
"description": "Command to be run before every build",
48+
"type": "string",
49+
"minLength": 1
50+
},
51+
"postbuild": {
52+
"description": "Command to be run after every build",
53+
"type": "string",
54+
"minLength": 1
55+
}
4656
}
4757
}

src/arduino/arduino.ts

+30-11
Original file line numberDiff line numberDiff line change
@@ -401,27 +401,40 @@ Please make sure the folder is not occupied by other procedures .`);
401401
}
402402

403403
/**
404-
* Runs the pre build command.
404+
* Runs the pre or post build command.
405405
* Usually before one of
406406
* * verify
407407
* * upload
408408
* * upload using programmer
409409
* @param dc Device context prepared during one of the above actions
410+
* @param what "pre" if the pre-build command should be run, "post" if the
411+
* post-build command should be run.
410412
* @returns True if successful, false on error.
411413
*/
412-
protected async runPreBuildCommand(dc: DeviceContext): Promise<boolean> {
413-
const prebuildcmdline = dc.prebuild;
414-
if (prebuildcmdline) {
415-
arduinoChannel.info(`Running pre-build command: ${prebuildcmdline}`);
416-
const args = prebuildcmdline.split(/\s+/);
414+
protected async runPrePostBuildCommand(dc: DeviceContext,
415+
what: "pre" | "post"): Promise<boolean> {
416+
const cmdline = what === "pre"
417+
? dc.prebuild
418+
: dc.postbuild;
419+
420+
if (cmdline) {
421+
arduinoChannel.info(`Running ${what}-build command: "${cmdline}"`);
422+
// TODO 2020-02-27, EW: We could call bash -c "cmd" here at least for
423+
// UNIX systems. Windows users must live with their poor system :)
424+
const args = cmdline.split(/\s+/);
417425
const cmd = args.shift();
418426
try {
419427
await util.spawn(cmd,
420428
args,
421429
{ shell: true, cwd: ArduinoWorkspace.rootPath },
422430
{ channel: arduinoChannel.channel });
423431
} catch (ex) {
424-
arduinoChannel.error(`Running pre-build command failed: ${os.EOL}${ex.error}`);
432+
const msg = ex.error
433+
? `${ex.error}`
434+
: ex.code
435+
? `Exit code = ${ex.code}`
436+
: JSON.stringify(ex);
437+
arduinoChannel.error(`Running ${what}-build command failed: ${os.EOL}${msg}`);
425438
return false;
426439
}
427440
}
@@ -517,7 +530,10 @@ Please make sure the folder is not occupied by other procedures .`);
517530
arduinoChannel.show();
518531
arduinoChannel.start(`${mode} sketch '${dc.sketch}'`);
519532

520-
if (!await this.runPreBuildCommand(dc)) {
533+
// TODO EW: What should we do with pre-/post build commands when running
534+
// analysis? Some could use it to generate/manipulate code which could
535+
// be a prerequisite for a successful build
536+
if (!await this.runPrePostBuildCommand(dc, "pre")) {
521537
return false;
522538
}
523539

@@ -545,7 +561,10 @@ Please make sure the folder is not occupied by other procedures .`);
545561
// Push sketch as last argument
546562
args.push(path.join(ArduinoWorkspace.rootPath, dc.sketch));
547563

548-
const cleanup = async () => {
564+
const cleanup = async (result: "ok" | "error") => {
565+
if (result === "ok") {
566+
await this.runPrePostBuildCommand(dc, "post");
567+
}
549568
await cocopa.conclude();
550569
if (mode === BuildMode.Upload || mode === BuildMode.UploadProgrammer) {
551570
UsbDetector.getInstance().resumeListening();
@@ -599,11 +618,11 @@ Please make sure the folder is not occupied by other procedures .`);
599618
undefined,
600619
{ stdout: stdoutcb, stderr: stderrcb },
601620
).then(async () => {
602-
await cleanup();
621+
await cleanup("ok");
603622
arduinoChannel.end(`${mode} sketch '${dc.sketch}${os.EOL}`);
604623
return true;
605624
}, async (reason) => {
606-
await cleanup();
625+
await cleanup("error");
607626
const msg = reason.code
608627
? `Exit with code=${reason.code}`
609628
: JSON.stringify(reason);

src/deviceContext.ts

+5
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ export class DeviceContext implements IDeviceContext, vscode.Disposable {
181181
public get onChangeISAutoGen() { return this._settings.intelliSenseGen.emitter.event }
182182
public get onChangeConfiguration() { return this._settings.configuration.emitter.event }
183183
public get onChangePrebuild() { return this._settings.prebuild.emitter.event }
184+
public get onChangePostbuild() { return this._settings.postbuild.emitter.event }
184185
public get onChangeProgrammer() { return this._settings.programmer.emitter.event }
185186

186187
public get port() {
@@ -214,6 +215,10 @@ export class DeviceContext implements IDeviceContext, vscode.Disposable {
214215
return this._settings.prebuild.value;
215216
}
216217

218+
public get postbuild() {
219+
return this._settings.postbuild.value;
220+
}
221+
217222
public get output() {
218223
return this._settings.output.value;
219224
}

src/deviceSettings.ts

+5
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ export class DeviceSettings {
112112
public intelliSenseGen: StrSetting = new StrSetting();
113113
public configuration: StrSetting = new StrSetting();
114114
public prebuild: StrSetting = new StrSetting();
115+
public postbuild: StrSetting = new StrSetting();
115116
public programmer: StrSetting = new StrSetting();
116117

117118
/**
@@ -127,6 +128,7 @@ export class DeviceSettings {
127128
this.intelliSenseGen.modified ||
128129
this.configuration.modified ||
129130
this.prebuild.modified ||
131+
this.postbuild.modified ||
130132
this.programmer.modified;
131133
}
132134
/**
@@ -141,6 +143,7 @@ export class DeviceSettings {
141143
this.intelliSenseGen.commit();
142144
this.configuration.commit();
143145
this.prebuild.commit();
146+
this.postbuild.commit();
144147
this.programmer.commit();
145148
}
146149
/**
@@ -157,6 +160,7 @@ export class DeviceSettings {
157160
this.intelliSenseGen.reset();
158161
this.configuration.reset();
159162
this.prebuild.reset();
163+
this.postbuild.reset();
160164
this.programmer.reset();
161165
if (commit) {
162166
this.commit();
@@ -181,6 +185,7 @@ export class DeviceSettings {
181185
this.debugger.value = settings.debugger;
182186
this.intelliSenseGen.value = settings.intelliSenseGen;
183187
this.prebuild.value = settings.prebuild;
188+
this.postbuild.value = settings.postbuild;
184189
this.programmer.value = settings.programmer;
185190
if (commit) {
186191
this.commit();

0 commit comments

Comments
 (0)