aboutsummaryrefslogtreecommitdiff
path: root/editors/code/src/cargo.ts
diff options
context:
space:
mode:
authorvsrs <[email protected]>2020-04-28 15:30:49 +0100
committervsrs <[email protected]>2020-04-28 15:30:49 +0100
commit48d6e828f1878436bb8633a1e7df02a6383d991a (patch)
tree24b1795e969c9fee0899f14a7e74bdce6764594e /editors/code/src/cargo.ts
parent7a9ba1657daa9fd90c639dcd937da11b4f526675 (diff)
ms-vscode.cpptools debugger support, initial version.
Diffstat (limited to 'editors/code/src/cargo.ts')
-rw-r--r--editors/code/src/cargo.ts103
1 files changed, 103 insertions, 0 deletions
diff --git a/editors/code/src/cargo.ts b/editors/code/src/cargo.ts
new file mode 100644
index 000000000..d119b6225
--- /dev/null
+++ b/editors/code/src/cargo.ts
@@ -0,0 +1,103 @@
1import { window } from 'vscode';
2import * as cp from 'child_process';
3import * as readline from 'readline';
4
5interface CompilationArtifact {
6 fileName: string;
7 name: string;
8 kind: string;
9 isTest: boolean;
10}
11
12export class Cargo {
13 rootFolder: string;
14 env?: { [key: string]: string };
15
16 public constructor(cargoTomlFolder: string) {
17 this.rootFolder = cargoTomlFolder;
18 }
19
20 public async artifactsFromArgs(cargoArgs: string[]): Promise<CompilationArtifact[]> {
21 let artifacts: CompilationArtifact[] = [];
22
23 try {
24 await this.runCargo(cargoArgs,
25 message => {
26 if (message.reason == 'compiler-artifact' && message.executable) {
27 let isBinary = message.target.crate_types.includes('bin');
28 let isBuildScript = message.target.kind.includes('custom-build');
29 if ((isBinary && !isBuildScript) || message.profile.test) {
30 artifacts.push({
31 fileName: message.executable,
32 name: message.target.name,
33 kind: message.target.kind[0],
34 isTest: message.profile.test
35 })
36 }
37 }
38 },
39 _stderr => {
40 // TODO: to output
41 }
42 );
43 }
44 catch (err) {
45 // TODO: to output
46 throw new Error(`Cargo invocation has failed: ${err}`);
47 }
48
49 return artifacts;
50 }
51
52 public async executableFromArgs(cargoArgs: string[], extraArgs?: string[]): Promise<string> {
53 cargoArgs.push("--message-format=json");
54 if (extraArgs) {
55 cargoArgs.push('--');
56 cargoArgs.push(...extraArgs);
57 }
58
59 let artifacts = await this.artifactsFromArgs(cargoArgs);
60
61 if (artifacts.length == 0 ) {
62 throw new Error('No compilation artifacts');
63 } else if (artifacts.length > 1) {
64 throw new Error('Multiple compilation artifacts are not supported.');
65 }
66
67 return artifacts[0].fileName;
68 }
69
70 runCargo(
71 cargoArgs: string[],
72 onStdoutJson: (obj: any) => void,
73 onStderrString: (data: string) => void
74 ): Promise<number> {
75 return new Promise<number>((resolve, reject) => {
76 let cargo = cp.spawn('cargo', cargoArgs, {
77 stdio: ['ignore', 'pipe', 'pipe'],
78 cwd: this.rootFolder,
79 env: this.env,
80 });
81
82 cargo.on('error', err => {
83 reject(new Error(`could not launch cargo: ${err}`));
84 });
85 cargo.stderr.on('data', chunk => {
86 onStderrString(chunk.toString());
87 });
88
89 let rl = readline.createInterface({ input: cargo.stdout });
90 rl.on('line', line => {
91 let message = JSON.parse(line);
92 onStdoutJson(message);
93 });
94
95 cargo.on('exit', (exitCode, _) => {
96 if (exitCode == 0)
97 resolve(exitCode);
98 else
99 reject(new Error(`exit code: ${exitCode}.`));
100 });
101 });
102 }
103} \ No newline at end of file