diff --git a/extensions/grunt/src/main.ts b/extensions/grunt/src/main.ts index deec1587cc249b924df6c1068f598b0e1253095c..22b6e9e41cd2ff875fe6339c8c21aef718d40e3d 100644 --- a/extensions/grunt/src/main.ts +++ b/extensions/grunt/src/main.ts @@ -70,12 +70,27 @@ interface GruntTaskDefinition extends vscode.TaskDefinition { file?: string; } +async function findGruntCommand(rootPath: string): Promise { + 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 | undefined; - constructor(private _workspaceFolder: vscode.WorkspaceFolder) { + constructor( + private _workspaceFolder: vscode.WorkspaceFolder, + private _gruntCommand: Promise) { } public get workspaceFolder(): vscode.WorkspaceFolder { @@ -95,10 +110,28 @@ class FolderDetector { } public async getTasks(): Promise { - 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 { + const gruntTask = (_task.definition).task; + if (gruntTask) { + let kind: GruntTaskDefinition = (_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 { @@ -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) { @@ -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)) { @@ -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(); } } @@ -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(); } } @@ -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 => { + return thisCapture.getTasks(); }, - resolveTask(_task: vscode.Task): vscode.Task | undefined { - return undefined; + resolveTask(_task: vscode.Task): Promise { + return thisCapture.getTask(_task); } }); } @@ -312,6 +334,24 @@ class TaskDetector { }); } } + + public async getTask(task: vscode.Task): Promise { + 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;