diff --git a/extensions/npm/src/main.ts b/extensions/npm/src/main.ts index 29cfd32d14b..38935c2c68a 100644 --- a/extensions/npm/src/main.ts +++ b/extensions/npm/src/main.ts @@ -15,15 +15,37 @@ const localize = nls.loadMessageBundle(); import { addJSONProviders } from './features/jsonContributions'; import { NpmScriptsTreeDataProvider } from './npmView'; -import { NpmTaskDefinition, ScriptValidator } from './tasks'; +import { NpmTaskDefinition, ScriptValidator, isWorkspaceFolder } from './tasks'; type AutoDetect = 'on' | 'off'; let taskProvider: vscode.Disposable | undefined; class Validator implements ScriptValidator { - async scriptIsValid(_task: vscode.Task): Promise { - // let tasks = await provideNpmScriptsForFolder(packageUri); - return true; + async scriptIsValid(task: vscode.Task): Promise { + let uri: vscode.Uri | null = this.getPackageJsonUri(task); + if (uri) { + let tasks = await provideNpmScriptsForFolder(uri); + for (let i = 0; i < tasks.length; i++) { + const t = tasks[i]; + if (isWorkspaceFolder(task.scope) && isWorkspaceFolder(task.scope)) { + if (t.name === task.name && t.scope === task.scope && ((t.execution)).commandLine === ((task.execution)).commandLine) { + return true; + } + } + } + } + return false; + } + + getPackageJsonUri(task: vscode.Task): vscode.Uri | null { + if (isWorkspaceFolder(task.scope)) { + if (task.definition.path) { + return vscode.Uri.file(path.join(task.scope.uri.fsPath, task.definition.path, 'package.json')); + } else { + return vscode.Uri.file(path.join(task.scope.uri.fsPath, 'package.json')); + } + } + return null; } } diff --git a/extensions/npm/src/npmView.ts b/extensions/npm/src/npmView.ts index fa00617ef46..cb0f455c048 100644 --- a/extensions/npm/src/npmView.ts +++ b/extensions/npm/src/npmView.ts @@ -8,7 +8,7 @@ import { WorkspaceFolder, workspace, commands, window, EventEmitter, Event, ThemeIcon, Uri, TextDocument, TaskProvider } from 'vscode'; -import { NpmTaskDefinition, ScriptValidator } from './tasks'; +import { NpmTaskDefinition, ScriptValidator, isWorkspaceFolder } from './tasks'; import * as path from 'path'; class Folder extends TreeItem { @@ -45,7 +45,11 @@ class PackageJSON extends TreeItem { this.folder = folder; this.path = relativePath; this.contextValue = 'packageJSON'; - this.resourceUri = Uri.file(path.join(folder!.resourceUri!.fsPath, relativePath, packageName)); + if (relativePath) { + this.resourceUri = Uri.file(path.join(folder!.resourceUri!.fsPath, relativePath, packageName)); + } else { + this.resourceUri = Uri.file(path.join(folder!.resourceUri!.fsPath, packageName)); + } this.iconPath = ThemeIcon.File; } @@ -83,14 +87,15 @@ export class NpmScriptsTreeDataProvider implements TreeDataProvider { const subscriptions = context.subscriptions; this.validator = validator; this.taskProvider = taskProvider; + subscriptions.push(commands.registerCommand('npm.runScript', this.runScript, this)); subscriptions.push(commands.registerCommand('npm.openScript', this.openScript, this)); subscriptions.push(commands.registerCommand('npm.refresh', this.refresh, this)); } - private runScript(task: Task) { - if (!this.validator.scriptIsValid(task)) { - window.showErrorMessage(`Could not find script ${task.name}`); + private async runScript(task: Task) { + if (!await this.validator.scriptIsValid(task)) { + window.showErrorMessage(`Could not find script '${task.name}' or the script has changed. Try to refresh the view.`); return; } workspace.executeTask(task); @@ -147,10 +152,6 @@ export class NpmScriptsTreeDataProvider implements TreeDataProvider { return []; } - private isWorkspaceFolder(value: any): value is WorkspaceFolder { - return value && typeof value !== 'number'; - } - private buildTaskTree(tasks: Task[]): Folder[] | PackageJSON[] { let folders: Map = new Map(); let packages: Map = new Map(); @@ -159,7 +160,7 @@ export class NpmScriptsTreeDataProvider implements TreeDataProvider { let packageJson = null; tasks.forEach(each => { - if (this.isWorkspaceFolder(each.scope)) { + if (isWorkspaceFolder(each.scope)) { folder = folders.get(each.scope.name); if (!folder) { folder = new Folder(each.scope); diff --git a/extensions/npm/src/tasks.ts b/extensions/npm/src/tasks.ts index 24c4ba2e497..cb443e387b6 100644 --- a/extensions/npm/src/tasks.ts +++ b/extensions/npm/src/tasks.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { TaskDefinition, Task } from 'vscode'; +import { TaskDefinition, Task, WorkspaceFolder } from 'vscode'; export interface NpmTaskDefinition extends TaskDefinition { script: string; @@ -12,4 +12,8 @@ export interface NpmTaskDefinition extends TaskDefinition { export interface ScriptValidator { scriptIsValid(task: Task): Promise; +} + +export function isWorkspaceFolder(value: any): value is WorkspaceFolder { + return value && typeof value !== 'number'; } \ No newline at end of file