|
1 | 1 | import * as path from 'path';
|
2 | 2 | import { promises as fs } from 'fs';
|
3 |
| -import { spawnSync } from 'child_process'; |
| 3 | +import { spawn } from 'child_process'; |
4 | 4 | import deepEqual from 'deep-equal';
|
5 | 5 | import WebRequest from 'web-request';
|
6 | 6 | import deepmerge from 'deepmerge';
|
@@ -108,37 +108,45 @@ export function activate(context: ExtensionContext) {
|
108 | 108 | );
|
109 | 109 | }
|
110 | 110 |
|
| 111 | +async function exec(command: string, args: string[]): Promise<{ stdout: string, stderr: string }> { |
| 112 | + return new Promise<{ stdout: string, stderr: string }>((resolve, reject) => { |
| 113 | + let out = ''; |
| 114 | + let err = ''; |
| 115 | + const cp = spawn(command, args); |
| 116 | + cp.stdout.on('data', data => out += data.toString()); |
| 117 | + cp.stderr.on('data', data => err += data.toString()); |
| 118 | + cp.on('error', reject); |
| 119 | + cp.on('close', (code, signal) => { |
| 120 | + const stdout = out.trim(); |
| 121 | + const stderr = err.trim(); |
| 122 | + if (code) { |
| 123 | + reject(new Error(stderr ?? `Exit code: ${code}`)); |
| 124 | + } |
| 125 | + if (signal) { |
| 126 | + reject(new Error(stderr ?? `Exit signal: ${signal}`)); |
| 127 | + } |
| 128 | + if (err.trim()) { |
| 129 | + reject(new Error(stderr)); |
| 130 | + } |
| 131 | + resolve({ stdout, stderr }); |
| 132 | + }); |
| 133 | + }); |
| 134 | +} |
| 135 | + |
111 | 136 | async function startDebug(_: ExtensionContext, config: DebugConfig): Promise<boolean> {
|
112 | 137 | let info: DebugInfo | undefined = undefined;
|
113 |
| - let rawStdout: string | undefined = undefined; |
114 |
| - let rawStdErr: string | undefined = undefined; |
115 | 138 | try {
|
116 | 139 | const args = ['debug', '-I', '-b', config.board.fqbn, config.sketchPath, '--format', 'json'];
|
117 |
| - const { stdout, stderr } = spawnSync(config?.cliPath || '.', args, { encoding: 'utf8' }); |
118 |
| - rawStdout = stdout.trim(); |
119 |
| - rawStdErr = stderr.trim(); |
120 |
| - } catch (err) { |
121 |
| - showError(err); |
122 |
| - return false; |
123 |
| - } |
124 |
| - if (!rawStdout) { |
125 |
| - if (rawStdErr) { |
126 |
| - if (rawStdErr.toLowerCase().indexOf('compiled sketch not found in') !== -1) { |
127 |
| - vscode.window.showErrorMessage(`Sketch '${path.basename(config.sketchPath)}' was not compiled. Please compile the sketch and start debugging again.`); |
128 |
| - } else { |
129 |
| - vscode.window.showErrorMessage(rawStdErr); |
130 |
| - } |
| 140 | + const { stdout, stderr } = await exec(config?.cliPath || '.', args); |
| 141 | + if (!stdout && stderr) { |
| 142 | + throw new Error(stderr); |
| 143 | + } |
| 144 | + info = JSON.parse(stdout); |
| 145 | + if (!info) { |
| 146 | + return false; |
131 | 147 | }
|
132 |
| - return false; |
133 |
| - } |
134 |
| - try { |
135 |
| - info = JSON.parse(rawStdout); |
136 | 148 | } catch (err) {
|
137 |
| - console.error(`Could not parse JSON: <${rawStdout}>`); |
138 |
| - showError(err); |
139 |
| - } |
140 |
| - if (!info) { |
141 |
| - return false; |
| 149 | + throw err; |
142 | 150 | }
|
143 | 151 | const defaultDebugConfig = {
|
144 | 152 | cwd: '${workspaceRoot}',
|
@@ -270,12 +278,6 @@ async function buildLanguageClient(config: LanguageServerConfig): Promise<Langua
|
270 | 278 | );
|
271 | 279 | }
|
272 | 280 |
|
273 |
| -function showError(err: unknown): void { |
274 |
| - console.error(err); |
275 |
| - const message = err instanceof Error ? err.message : typeof err === 'string' ? err : String(err); |
276 |
| - vscode.window.showErrorMessage(message); |
277 |
| -} |
278 |
| - |
279 | 281 | /**
|
280 | 282 | * Instead of writing the `launch.json` to the workspace, the file is written to the temporary binary output location.
|
281 | 283 | */
|
|
0 commit comments