Skip to content

Commit f6c3b2c

Browse files
elektronikworkshopadiazulay
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 7039ea8 commit f6c3b2c

File tree

5 files changed

+53
-12
lines changed

5 files changed

+53
-12
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

+10
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@
4242
"disable",
4343
"enable"
4444
]
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
4555
}
4656
}
4757
}

src/arduino/arduino.ts

+30-11
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,10 @@ export class ArduinoApp {
328328
arduinoChannel.show();
329329
arduinoChannel.start(`${buildMode} sketch '${dc.sketch}'`);
330330

331-
if (!await this.runPreBuildCommand(dc)) {
331+
// TODO EW: What should we do with pre-/post build commands when running
332+
// analysis? Some could use it to generate/manipulate code which could
333+
// be a prerequisite for a successful build
334+
if (!await this.runPrePostBuildCommand(dc, "pre")) {
332335
return false;
333336
}
334337

@@ -363,7 +366,10 @@ export class ArduinoApp {
363366
// Push sketch as last argument
364367
args.push(path.join(ArduinoWorkspace.rootPath, dc.sketch));
365368

366-
const cleanup = async () => {
369+
const cleanup = async (result: "ok" | "error") => {
370+
if (result === "ok") {
371+
await this.runPrePostBuildCommand(dc, "post");
372+
}
367373
await cocopa.conclude();
368374
if (buildMode === BuildMode.Upload || buildMode === BuildMode.UploadProgrammer) {
369375
UsbDetector.getInstance().resumeListening();
@@ -417,11 +423,11 @@ export class ArduinoApp {
417423
undefined,
418424
{ stdout: stdoutcb, stderr: stderrcb },
419425
).then(async () => {
420-
await cleanup();
426+
await cleanup("ok");
421427
arduinoChannel.end(`${buildMode} sketch '${dc.sketch}'${os.EOL}`);
422428
return true;
423429
}, async (reason) => {
424-
await cleanup();
430+
await cleanup("error");
425431
const msg = reason.code
426432
? `Exit with code=${reason.code}`
427433
: JSON.stringify(reason);
@@ -671,27 +677,40 @@ export class ArduinoApp {
671677
}
672678

673679
/**
674-
* Runs the pre build command.
680+
* Runs the pre or post build command.
675681
* Usually before one of
676682
* * verify
677683
* * upload
678684
* * upload using programmer
679685
* @param dc Device context prepared during one of the above actions
686+
* @param what "pre" if the pre-build command should be run, "post" if the
687+
* post-build command should be run.
680688
* @returns True if successful, false on error.
681689
*/
682-
protected async runPreBuildCommand(dc: DeviceContext): Promise<boolean> {
683-
const prebuildcmdline = dc.prebuild;
684-
if (prebuildcmdline) {
685-
arduinoChannel.info(`Running pre-build command: ${prebuildcmdline}`);
686-
const args = prebuildcmdline.split(/\s+/);
690+
protected async runPrePostBuildCommand(dc: DeviceContext,
691+
what: "pre" | "post"): Promise<boolean> {
692+
const cmdline = what === "pre"
693+
? dc.prebuild
694+
: dc.postbuild;
695+
696+
if (cmdline) {
697+
arduinoChannel.info(`Running ${what}-build command: "${cmdline}"`);
698+
// TODO 2020-02-27, EW: We could call bash -c "cmd" here at least for
699+
// UNIX systems. Windows users must live with their poor system :)
700+
const args = cmdline.split(/\s+/);
687701
const cmd = args.shift();
688702
try {
689703
await util.spawn(cmd,
690704
args,
691705
{ shell: true, cwd: ArduinoWorkspace.rootPath },
692706
{ channel: arduinoChannel.channel });
693707
} catch (ex) {
694-
arduinoChannel.error(`Running pre-build command failed: ${os.EOL}${ex.error}`);
708+
const msg = ex.error
709+
? `${ex.error}`
710+
: ex.code
711+
? `Exit code = ${ex.code}`
712+
: JSON.stringify(ex);
713+
arduinoChannel.error(`Running ${what}-build command failed: ${os.EOL}${msg}`);
695714
return false;
696715
}
697716
}

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 = new StrSetting();
113113
public configuration = new StrSetting();
114114
public prebuild = new StrSetting();
115+
public postbuild = new StrSetting();
115116
public programmer = 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)