From 584d00db010132d494ff47229e1f9fb5b050b3fa Mon Sep 17 00:00:00 2001 From: Erich Gamma Date: Wed, 19 Jul 2017 18:38:26 +0200 Subject: [PATCH] Added support for multi root folders --- extensions/npm/package.json | 6 ++-- extensions/npm/src/main.ts | 71 +++++++++++++++++++++++++------------ 2 files changed, 52 insertions(+), 25 deletions(-) diff --git a/extensions/npm/package.json b/extensions/npm/package.json index c3fb3e0129e..be169c559b0 100644 --- a/extensions/npm/package.json +++ b/extensions/npm/package.json @@ -49,15 +49,15 @@ "taskDefinitions": [ { "type": "npm", - "required": ["script"], + "required": ["script", "path"], "properties": { "script": { "type": "string", "description": "The npm script to customize" }, - "file": { + "path": { "type": "string", - "description": "The package.json file that provides the task. Can be omitted." + "description": "The path to the package.json file that provides the script." } } } diff --git a/extensions/npm/src/main.ts b/extensions/npm/src/main.ts index d45add60b9f..1c4386623c1 100644 --- a/extensions/npm/src/main.ts +++ b/extensions/npm/src/main.ts @@ -25,7 +25,7 @@ export function activate(_context: vscode.ExtensionContext): void { } else if (!taskProvider && autoDetect === 'on') { taskProvider = vscode.workspace.registerTaskProvider('npm', { provideTasks: () => { - return getNpmScriptsAsTasks(); + return provideNpmScripts(); }, resolveTask(_task: vscode.Task): vscode.Task | undefined { return undefined; @@ -87,27 +87,32 @@ function isTestTask(name: string): boolean { return false; } -function getNpmCommandLine(script: string): string { - if (vscode.workspace.getConfiguration('npm').get('runSilent')) { - return `npm --silent run ${script}`; - } - return `npm run ${script}`; -} - function isNotPreOrPostScript(script: string): boolean { return !(script.startsWith('pre') || script.startsWith('post')); } -async function getNpmScriptsAsTasks(): Promise { - let workspaceRoot = vscode.workspace.rootPath; - +async function provideNpmScripts(): Promise { let emptyTasks: vscode.Task[] = []; + let allTasks: vscode.Task[] = []; + let folders = vscode.workspace.workspaceFolders; - if (!workspaceRoot) { + if (!folders) { return emptyTasks; } - let packageJson = path.join(workspaceRoot, 'package.json'); + const singleRoot = allTasks.length === 1; + for (const folder of folders) { + let tasks = await provideNpmScriptsForFolder(folder, singleRoot); + allTasks.push(...tasks); + } + return allTasks; +} + +async function provideNpmScriptsForFolder(folder: vscode.WorkspaceFolder, singleRoot: boolean): Promise { + let rootPath = folder.uri.fsPath; + let emptyTasks: vscode.Task[] = []; + + let packageJson = path.join(rootPath, 'package.json'); if (!await exists(packageJson)) { return emptyTasks; } @@ -116,16 +121,12 @@ async function getNpmScriptsAsTasks(): Promise { var contents = await readFile(packageJson); var json = JSON.parse(contents); if (!json.scripts) { - return Promise.resolve(emptyTasks); + return emptyTasks; } const result: vscode.Task[] = []; Object.keys(json.scripts).filter(isNotPreOrPostScript).forEach(each => { - const kind: NpmTaskDefinition = { - type: 'npm', - script: each - }; - const task = new vscode.Task(kind, `run ${each}`, 'npm', new vscode.ShellExecution(getNpmCommandLine(each))); + const task = createTask(each, `run ${each}`, rootPath, singleRoot); const lowerCaseTaskName = each.toLowerCase(); if (isBuildTask(lowerCaseTaskName)) { task.group = vscode.TaskGroup.Build; @@ -135,9 +136,35 @@ async function getNpmScriptsAsTasks(): Promise { result.push(task); }); // always add npm install (without a problem matcher) - result.push(new vscode.Task({ type: 'npm', script: 'install' } as NpmTaskDefinition, `install`, 'npm', new vscode.ShellExecution(`npm install`), [])); - return Promise.resolve(result); + result.push(createTask('install', 'install', rootPath, singleRoot, [])); + return result; } catch (e) { - return Promise.resolve(emptyTasks); + return emptyTasks; } +} + +function createTask(script: string, cmd: string, rootPath: string, singleRoot: boolean, matcher?: any): vscode.Task { + + function getTaskName(script: string, rootPath: string, singleRoot: boolean) { + if (singleRoot) { + return script; + } + return `${script} - ${rootPath}`; + } + + function getNpmCommandLine(cmd: string): string { + if (vscode.workspace.getConfiguration('npm').get('runSilent')) { + return `npm --silent ${cmd}`; + } + return `npm ${cmd}`; + } + + let kind: NpmTaskDefinition = { + type: 'npm', + script: script, + path: rootPath + }; + let taskName = getTaskName(script, rootPath, singleRoot); + + return new vscode.Task(kind, taskName, 'npm', new vscode.ShellExecution(getNpmCommandLine(cmd), { cwd: rootPath }), matcher); } \ No newline at end of file