-
-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathmake-runner.ts
More file actions
110 lines (92 loc) · 3.71 KB
/
Copy pathmake-runner.ts
File metadata and controls
110 lines (92 loc) · 3.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import { ProcessExecution, Task, tasks, TaskScope, window, workspace } from "vscode";
import { Configuration } from "./configuration";
import { File } from "./models/file";
import { Runner } from "./runner";
import { commandExists } from "./utils/common-utils";
import { isStringNullOrWhiteSpace } from "./utils/string-utils";
import { Notification } from "./notification";
import { terminal } from "./terminal";
import { getCommand, currentShell } from "./utils/shell-utils";
import { existsSync } from "fs";
import { join } from "path";
export class MakeRunner {
private file: File;
constructor(file: File) {
this.file = file;
}
async build(runCallback: (() => Promise<void>) | null = null): Promise<void> {
const makePath = Configuration.makePath();
if (!await this.isMakeValid(makePath)) {
Notification.showErrorMessage(
`Make executable not found at "${makePath}". Please check the make-path setting.`
);
return;
}
if (Configuration.saveBeforeCompile()) {
await window.activeTextEditor?.document.save();
}
const buildTarget = Configuration.makeBuildTarget();
const makeArgs = buildTarget ? [buildTarget] : [];
const cwd = this.getMakeDirectory();
const processExecution = new ProcessExecution(
makePath,
makeArgs,
{ cwd }
);
const task = new Task(
{ type: "process" },
TaskScope.Workspace,
"C/C++ Compile Run: Make Build",
"C/C++ Compile Run",
processExecution,
["$gcc"]
);
const executionPromise = tasks.executeTask(task);
const endListener = tasks.onDidEndTaskProcess(async e => {
const execution = await executionPromise;
if (e.execution === execution) {
endListener.dispose();
if (e.exitCode === 0) {
Notification.showInformationMessage("Make build successful.");
if (runCallback) { await runCallback(); }
} else {
Notification.showErrorMessage("Make build failed. Please check the output for errors.");
}
}
});
await executionPromise;
}
async run(shouldRunInExternalTerminal = false): Promise<void> {
const runTarget = Configuration.makeRunTarget();
if (runTarget) {
const makePath = Configuration.makePath();
if (!await this.isMakeValid(makePath)) {
Notification.showErrorMessage(
`Make executable not found at "${makePath}". Please check the make-path setting.`
);
return;
}
const cwd = this.getMakeDirectory();
const shell = currentShell();
const makeCommand = getCommand(`${makePath} ${runTarget}`, shell);
await terminal.runInTerminal(makeCommand, {
name: "C/C++ Compile Run",
cwd
});
} else {
const runner = new Runner(this.file);
await runner.run(shouldRunInExternalTerminal);
}
}
async isMakeValid(makePath: string): Promise<boolean> {
return !isStringNullOrWhiteSpace(makePath) && await commandExists(makePath);
}
private getMakeDirectory(): string {
// Prefer the file's own directory if it contains a Makefile
if (existsSync(join(this.file.directory, "Makefile")) ||
existsSync(join(this.file.directory, "makefile"))) {
return this.file.directory;
}
return workspace.workspaceFolders?.[0]?.uri.fsPath ?? this.file.directory;
}
}