Skip to content

Commit

Permalink
Implement Task Provider resolveTask on grunt extension (microsoft#76731)
Browse files Browse the repository at this point in the history
* Implement Task Provider resolveTask on grunt extension

* Move find grunt command code on computeTask to findGruntCommand function

* Fix set detectors and detector dispose

* Update grunt resolve task to use same definition object

Fixes microsoft#76518
  • Loading branch information
peacemaker14 authored and alexr00 committed Aug 5, 2019
1 parent 780a508 commit d03a91e
Showing 1 changed file with 69 additions and 29 deletions.
98 changes: 69 additions & 29 deletions extensions/grunt/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,27 @@ interface GruntTaskDefinition extends vscode.TaskDefinition {
file?: string;
}

async function findGruntCommand(rootPath: string): Promise<string> {
let command: string;
let platform = process.platform;
if (platform === 'win32' && await exists(path.join(rootPath!, 'node_modules', '.bin', 'grunt.cmd'))) {
command = path.join('.', 'node_modules', '.bin', 'grunt.cmd');
} else if ((platform === 'linux' || platform === 'darwin') && await exists(path.join(rootPath!, 'node_modules', '.bin', 'grunt'))) {
command = path.join('.', 'node_modules', '.bin', 'grunt');
} else {
command = 'grunt';
}
return command;
}

class FolderDetector {

private fileWatcher: vscode.FileSystemWatcher | undefined;
private promise: Thenable<vscode.Task[]> | undefined;

constructor(private _workspaceFolder: vscode.WorkspaceFolder) {
constructor(
private _workspaceFolder: vscode.WorkspaceFolder,
private _gruntCommand: Promise<string>) {
}

public get workspaceFolder(): vscode.WorkspaceFolder {
Expand All @@ -95,10 +110,28 @@ class FolderDetector {
}

public async getTasks(): Promise<vscode.Task[]> {
if (!this.promise) {
this.promise = this.computeTasks();
if (this.isEnabled()) {
if (!this.promise) {
this.promise = this.computeTasks();
}
return this.promise;
} else {
return [];
}
return this.promise;
}

public async getTask(_task: vscode.Task): Promise<vscode.Task | undefined> {
const gruntTask = (<any>_task.definition).task;
if (gruntTask) {
let kind: GruntTaskDefinition = (<any>_task.definition);
let options: vscode.ShellExecutionOptions = { cwd: this.workspaceFolder.uri.fsPath };
let source = 'grunt';
let task = gruntTask.indexOf(' ') === -1
? new vscode.Task(kind, this.workspaceFolder, gruntTask, source, new vscode.ShellExecution(`${await this._gruntCommand} ${name}`, options))
: new vscode.Task(kind, this.workspaceFolder, gruntTask, source, new vscode.ShellExecution(`${await this._gruntCommand} "${name}"`, options));
return task;
}
return undefined;
}

private async computeTasks(): Promise<vscode.Task[]> {
Expand All @@ -111,17 +144,7 @@ class FolderDetector {
return emptyTasks;
}

let command: string;
let platform = process.platform;
if (platform === 'win32' && await exists(path.join(rootPath!, 'node_modules', '.bin', 'grunt.cmd'))) {
command = path.join('.', 'node_modules', '.bin', 'grunt.cmd');
} else if ((platform === 'linux' || platform === 'darwin') && await exists(path.join(rootPath!, 'node_modules', '.bin', 'grunt'))) {
command = path.join('.', 'node_modules', '.bin', 'grunt');
} else {
command = 'grunt';
}

let commandLine = `${command} --help --no-color`;
let commandLine = `${await this._gruntCommand} --help --no-color`;
try {
let { stdout, stderr } = await exec(commandLine, { cwd: rootPath });
if (stderr) {
Expand Down Expand Up @@ -168,8 +191,8 @@ class FolderDetector {
let source = 'grunt';
let options: vscode.ShellExecutionOptions = { cwd: this.workspaceFolder.uri.fsPath };
let task = name.indexOf(' ') === -1
? new vscode.Task(kind, this.workspaceFolder, name, source, new vscode.ShellExecution(`${command} ${name}`, options))
: new vscode.Task(kind, this.workspaceFolder, name, source, new vscode.ShellExecution(`${command} "${name}"`, options));
? new vscode.Task(kind, this.workspaceFolder, name, source, new vscode.ShellExecution(`${await this._gruntCommand} ${name}`, options))
: new vscode.Task(kind, this.workspaceFolder, name, source, new vscode.ShellExecution(`${await this._gruntCommand} "${name}"`, options));
result.push(task);
let lowerCaseTaskName = name.toLowerCase();
if (isBuildTask(lowerCaseTaskName)) {
Expand Down Expand Up @@ -239,9 +262,9 @@ class TaskDetector {
}
}
for (let add of added) {
let detector = new FolderDetector(add);
let detector = new FolderDetector(add, findGruntCommand(add.uri.fsPath));
this.detectors.set(add.uri.toString(), detector);
if (detector.isEnabled()) {
this.detectors.set(add.uri.toString(), detector);
detector.start();
}
}
Expand All @@ -250,18 +273,16 @@ class TaskDetector {

private updateConfiguration(): void {
for (let detector of this.detectors.values()) {
if (!detector.isEnabled()) {
detector.dispose();
this.detectors.delete(detector.workspaceFolder.uri.toString());
}
detector.dispose();
this.detectors.delete(detector.workspaceFolder.uri.toString());
}
let folders = vscode.workspace.workspaceFolders;
if (folders) {
for (let folder of folders) {
if (!this.detectors.has(folder.uri.toString())) {
let detector = new FolderDetector(folder);
let detector = new FolderDetector(folder, findGruntCommand(folder.uri.fsPath));
this.detectors.set(folder.uri.toString(), detector);
if (detector.isEnabled()) {
this.detectors.set(folder.uri.toString(), detector);
detector.start();
}
}
Expand All @@ -272,12 +293,13 @@ class TaskDetector {

private updateProvider(): void {
if (!this.taskProvider && this.detectors.size > 0) {
const thisCapture = this;
this.taskProvider = vscode.workspace.registerTaskProvider('grunt', {
provideTasks: () => {
return this.getTasks();
provideTasks: (): Promise<vscode.Task[]> => {
return thisCapture.getTasks();
},
resolveTask(_task: vscode.Task): vscode.Task | undefined {
return undefined;
resolveTask(_task: vscode.Task): Promise<vscode.Task | undefined> {
return thisCapture.getTask(_task);
}
});
}
Expand Down Expand Up @@ -312,6 +334,24 @@ class TaskDetector {
});
}
}

public async getTask(task: vscode.Task): Promise<vscode.Task | undefined> {
if (this.detectors.size === 0) {
return undefined;
} else if (this.detectors.size === 1) {
return this.detectors.values().next().value.getTask(task);
} else {
if ((task.scope === vscode.TaskScope.Workspace) || (task.scope === vscode.TaskScope.Global)) {
return undefined;
} else if (task.scope) {
const detector = this.detectors.get(task.scope.uri.toString());
if (detector) {
return detector.getTask(task);
}
}
return undefined;
}
}
}

let detector: TaskDetector;
Expand Down

0 comments on commit d03a91e

Please sign in to comment.