-
Notifications
You must be signed in to change notification settings - Fork 82
/
Copy pathbuild.ts
120 lines (108 loc) · 4.22 KB
/
build.ts
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
111
112
113
114
115
116
117
118
119
120
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
import { basename } from "path";
import { commands, DiagnosticSeverity, languages, QuickPickItem, Uri, window } from "vscode";
import { instrumentOperation, sendInfo, sendOperationError, setErrorCode } from "vscode-extension-telemetry-wrapper";
import { Commands, executeJavaExtensionCommand } from "./commands";
import { Jdtls } from "./java/jdtls";
import { UserError } from "./utility";
export async function buildWorkspace(): Promise<boolean> {
const buildResult = await instrumentOperation("build", async (operationId: string) => {
let error;
try {
await executeJavaExtensionCommand(Commands.JAVA_BUILD_WORKSPACE, false);
} catch (err) {
error = err;
}
return {
error,
operationId,
};
})();
if (buildResult.error) {
return handleBuildFailure(buildResult.operationId, buildResult.error);
}
return true;
}
async function handleBuildFailure(operationId: string, err: any): Promise<boolean> {
const error: Error = new UserError({
message: "Build failed",
});
setErrorCode(error, Number(err));
sendOperationError(operationId, "build", error);
// Workaround: Since VS Code 1.53, the contributed command would no longer throw exact error message when an error occurs.
// This change breaks the existing build error reporting, so we make a workaround here.
// Related issue: https://github.com/microsoft/vscode/issues/116932
if (err instanceof Error || err === Jdtls.CompileWorkspaceStatus.Witherror || err === Jdtls.CompileWorkspaceStatus.Failed) {
if (checkErrorsReportedByJavaExtension()) {
commands.executeCommand("workbench.actions.view.problems");
}
const ans = await window.showErrorMessage("Build failed, do you want to continue?",
"Proceed", "Fix...", "Cancel");
sendInfo(operationId, {
operationName: "build",
choiceForBuildError: ans || "esc",
});
if (ans === "Proceed") {
return true;
} else if (ans === "Fix...") {
showFixSuggestions(operationId);
}
return false;
}
return false;
}
export function checkErrorsReportedByJavaExtension(): boolean {
const problems = languages.getDiagnostics() || [];
for (const problem of problems) {
const fileName = basename(problem[0].fsPath || "");
if (fileName.endsWith(".java") || fileName === "pom.xml" || fileName.endsWith(".gradle")) {
if (problem[1].filter((diagnostic) => diagnostic.severity === DiagnosticSeverity.Error).length) {
return true;
}
}
}
return false;
}
async function showFixSuggestions(operationId: string) {
let buildFiles: string[] = [];
try {
buildFiles = await Jdtls.resolveBuildFiles();
} catch (error) {
// do nothing
}
const pickitems: QuickPickItem[] = [];
pickitems.push({
label: "Clean workspace cache",
detail: "Clean the stale workspace and reload the window",
});
if (buildFiles.length) {
pickitems.push({
label: "Update project configuration",
detail: "Force the language server to update the project configuration/classpath",
});
}
pickitems.push({
label: "Open log file",
detail: "Open log file to view more details for the build errors",
});
const ans = await window.showQuickPick(pickitems, {
placeHolder: "Please fix the errors in PROBLEMS first, then try the fix suggestions below.",
});
sendInfo(operationId, {
operationName: "build",
choiceForBuildFix: ans ? ans.label : "esc",
});
if (!ans) {
return;
}
if (ans.label === "Clean workspace cache") {
commands.executeCommand("java.clean.workspace");
} else if (ans.label === "Update project configuration") {
for (const buildFile of buildFiles) {
await commands.executeCommand("java.projectConfiguration.update", Uri.parse(buildFile));
}
} else if (ans.label === "Open log file") {
commands.executeCommand("java.open.serverLog");
}
}