Skip to content

Commit 973cff3

Browse files
authored
fix: Make export jar task unblock fetch task process (#722)
1 parent 26c2ca1 commit 973cff3

File tree

4 files changed

+82
-53
lines changed

4 files changed

+82
-53
lines changed

extension.bundle.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,8 @@ export { DependencyExplorer } from "./src/views/dependencyExplorer";
2323
export { Commands } from "./src/commands";
2424
export { LanguageServerMode } from "./src/languageServerApi/LanguageServerMode";
2525

26+
// language server api
27+
export { languageServerApiManager } from "./src/languageServerApi/languageServerApiManager";
28+
2629
// tasks
2730
export { BuildTaskProvider, categorizePaths, getFinalPaths } from "./src/tasks/build/buildTaskProvider";

src/languageServerApi/languageServerApiManager.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ import { LanguageServerMode } from "./LanguageServerMode";
1212
class LanguageServerApiManager {
1313
private extensionApi: any;
1414

15-
private isReady: boolean = false;
15+
private isServerReady: boolean = false;
1616

1717
public async ready(): Promise<boolean> {
18-
if (this.isReady) {
18+
if (this.isServerReady) {
1919
return true;
2020
}
2121

@@ -29,7 +29,7 @@ class LanguageServerApiManager {
2929
}
3030

3131
await this.extensionApi.serverReady();
32-
this.isReady = true;
32+
this.isServerReady = true;
3333
return true;
3434
}
3535

@@ -81,6 +81,15 @@ class LanguageServerApiManager {
8181
private isApiInitialized(): boolean {
8282
return this.extensionApi !== undefined;
8383
}
84+
85+
/**
86+
* Check if the language server is ready in the given timeout.
87+
* @param timeout the timeout in milliseconds to wait
88+
* @returns false if the language server is not ready in the given timeout, otherwise true
89+
*/
90+
public isReady(timeout: number): Promise<boolean> {
91+
return Promise.race([this.ready(), new Promise<boolean>((resolve) => setTimeout(() => resolve(false), timeout))]);
92+
}
8493
}
8594

8695
export const languageServerApiManager: LanguageServerApiManager = new LanguageServerApiManager();

src/tasks/buildArtifact/BuildArtifactTaskProvider.ts

Lines changed: 59 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -99,30 +99,35 @@ export class BuildArtifactTaskProvider implements TaskProvider {
9999
}
100100

101101
public static async resolveExportTask(task: Task, type: string): Promise<Task> {
102-
if (!await languageServerApiManager.ready()) {
102+
if (!await languageServerApiManager.isReady(1000)) {
103103
return task;
104104
}
105105
const definition: IExportJarTaskDefinition = <IExportJarTaskDefinition>task.definition;
106106
const folder: WorkspaceFolder = <WorkspaceFolder>task.scope;
107-
const resolvedTask: Task = new Task(definition, folder, task.name, type,
108-
new CustomExecution(async (resolvedDefinition: IExportJarTaskDefinition): Promise<Pseudoterminal> => {
109-
const stepMetadata: IStepMetadata = {
110-
entry: undefined,
111-
taskLabel: resolvedDefinition.label || folder.name,
112-
workspaceFolder: folder,
113-
projectList: await Jdtls.getProjects(folder.uri.toString()),
114-
steps: [],
115-
elements: [],
116-
classpaths: [],
117-
};
118-
return new ExportJarTaskTerminal(resolvedDefinition, stepMetadata);
119-
}));
120-
resolvedTask.presentationOptions.reveal = TaskRevealKind.Never;
121-
return resolvedTask;
107+
try {
108+
const projectList = await Jdtls.getProjects(folder.uri.toString());
109+
const resolvedTask: Task = new Task(definition, folder, task.name, type,
110+
new CustomExecution(async (resolvedDefinition: IExportJarTaskDefinition): Promise<Pseudoterminal> => {
111+
const stepMetadata: IStepMetadata = {
112+
entry: undefined,
113+
taskLabel: resolvedDefinition.label || folder.name,
114+
workspaceFolder: folder,
115+
projectList: projectList,
116+
steps: [],
117+
elements: [],
118+
classpaths: [],
119+
};
120+
return new ExportJarTaskTerminal(resolvedDefinition, stepMetadata);
121+
}));
122+
resolvedTask.presentationOptions.reveal = TaskRevealKind.Never;
123+
return resolvedTask;
124+
} catch (e) {
125+
return task;
126+
}
122127
}
123128

124129
public async provideTasks(): Promise<Task[] | undefined> {
125-
if (!await languageServerApiManager.ready()) {
130+
if (!await languageServerApiManager.isReady(1000)) {
126131
return undefined;
127132
}
128133
const folders: readonly WorkspaceFolder[] = workspace.workspaceFolders || [];
@@ -134,41 +139,45 @@ export class BuildArtifactTaskProvider implements TaskProvider {
134139
}
135140
this.tasks = [];
136141
for (const folder of folders) {
137-
const projectList: INodeData[] = await Jdtls.getProjects(folder.uri.toString());
138-
const elementList: string[] = [];
139-
if (_.isEmpty(projectList)) {
140-
continue;
141-
} else if (projectList.length === 1) {
142-
elementList.push("${" + ExportJarConstants.COMPILE_OUTPUT + "}",
143-
"${" + ExportJarConstants.DEPENDENCIES + "}");
144-
} else {
145-
for (const project of projectList) {
146-
elementList.push("${" + ExportJarConstants.COMPILE_OUTPUT + ":" + project.name + "}",
147-
"${" + ExportJarConstants.DEPENDENCIES + ":" + project.name + "}");
142+
try {
143+
const projectList: INodeData[] = await Jdtls.getProjects(folder.uri.toString());
144+
const elementList: string[] = [];
145+
if (_.isEmpty(projectList)) {
146+
continue;
147+
} else if (projectList.length === 1) {
148+
elementList.push("${" + ExportJarConstants.COMPILE_OUTPUT + "}",
149+
"${" + ExportJarConstants.DEPENDENCIES + "}");
150+
} else {
151+
for (const project of projectList) {
152+
elementList.push("${" + ExportJarConstants.COMPILE_OUTPUT + ":" + project.name + "}",
153+
"${" + ExportJarConstants.DEPENDENCIES + ":" + project.name + "}");
154+
}
148155
}
156+
const mainClasses: IMainClassInfo[] = await Jdtls.getMainClasses(folder.uri.toString());
157+
const defaultDefinition: IExportJarTaskDefinition = {
158+
type: BuildArtifactTaskProvider.exportJarType,
159+
mainClass: (mainClasses.length === 1) ? mainClasses[0].name : undefined,
160+
targetPath: Settings.getExportJarTargetPath(),
161+
elements: elementList,
162+
};
163+
const defaultTask: Task = new Task(defaultDefinition, folder, folder.name, BuildArtifactTaskProvider.exportJarType,
164+
new CustomExecution(async (resolvedDefinition: IExportJarTaskDefinition): Promise<Pseudoterminal> => {
165+
const stepMetadata: IStepMetadata = {
166+
entry: undefined,
167+
taskLabel: resolvedDefinition.label || folder.name,
168+
workspaceFolder: folder,
169+
projectList: projectList,
170+
steps: [],
171+
elements: [],
172+
classpaths: [],
173+
};
174+
return new ExportJarTaskTerminal(resolvedDefinition, stepMetadata);
175+
}), undefined);
176+
defaultTask.presentationOptions.reveal = TaskRevealKind.Never;
177+
this.tasks.push(defaultTask);
178+
} catch (e) {
179+
continue;
149180
}
150-
const mainClasses: IMainClassInfo[] = await Jdtls.getMainClasses(folder.uri.toString());
151-
const defaultDefinition: IExportJarTaskDefinition = {
152-
type: BuildArtifactTaskProvider.exportJarType,
153-
mainClass: (mainClasses.length === 1) ? mainClasses[0].name : undefined,
154-
targetPath: Settings.getExportJarTargetPath(),
155-
elements: elementList,
156-
};
157-
const defaultTask: Task = new Task(defaultDefinition, folder, folder.name, BuildArtifactTaskProvider.exportJarType,
158-
new CustomExecution(async (resolvedDefinition: IExportJarTaskDefinition): Promise<Pseudoterminal> => {
159-
const stepMetadata: IStepMetadata = {
160-
entry: undefined,
161-
taskLabel: resolvedDefinition.label || folder.name,
162-
workspaceFolder: folder,
163-
projectList: await Jdtls.getProjects(folder.uri.toString()),
164-
steps: [],
165-
elements: [],
166-
classpaths: [],
167-
};
168-
return new ExportJarTaskTerminal(resolvedDefinition, stepMetadata);
169-
}), undefined);
170-
defaultTask.presentationOptions.reveal = TaskRevealKind.Never;
171-
this.tasks.push(defaultTask);
172181
}
173182
return this.tasks;
174183
}

test/maven-suite/buildArtifact.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import * as fse from "fs-extra";
77
import { suiteTeardown } from "mocha";
88
import * as path from "path";
99
import { Task, TaskEndEvent, tasks, workspace } from "vscode";
10+
import { languageServerApiManager } from "../../extension.bundle";
1011
import { setupTestEnv } from "../shared";
1112

1213
// tslint:disable: only-arrow-functions
@@ -18,7 +19,14 @@ suite("Build Artifact Tests", () => {
1819

1920
suiteSetup(setupTestEnv);
2021

22+
test("Should bypass buildArtifact tasks before language server is ready", async function() {
23+
const vscodeTasks: Task[] = await tasks.fetchTasks();
24+
const buildJarTask: Task | undefined = vscodeTasks.find((t: Task) => t.name === "java (buildArtifact): maven");
25+
assert.ok(buildJarTask === undefined);
26+
});
27+
2128
test("Can build jar correctly", async function() {
29+
await languageServerApiManager.ready();
2230
const vscodeTasks: Task[] = await tasks.fetchTasks();
2331
const buildJarTask: Task | undefined = vscodeTasks.find((t: Task) => t.name === "java (buildArtifact): maven");
2432
assert.ok(buildJarTask !== undefined);

0 commit comments

Comments
 (0)