diff --git a/src/vs/workbench/api/electron-browser/mainThreadTask.ts b/src/vs/workbench/api/electron-browser/mainThreadTask.ts index 4eca89008716ac1c1139115908ea8581b2e92afc..bd4901b72ada45dcf210e3bba68d26081507a4ba 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadTask.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadTask.ts @@ -12,6 +12,7 @@ import URI from 'vs/base/common/uri'; import * as Objects from 'vs/base/common/objects'; import { TPromise } from 'vs/base/common/winjs.base'; import * as Types from 'vs/base/common/types'; +import * as Platform from 'vs/base/common/platform'; import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; @@ -21,12 +22,11 @@ import { } from 'vs/workbench/parts/tasks/common/tasks'; import { ITaskService, TaskFilter } from 'vs/workbench/parts/tasks/common/taskService'; - import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { ExtHostContext, MainThreadTaskShape, ExtHostTaskShape, MainContext, IExtHostContext } from 'vs/workbench/api/node/extHost.protocol'; import { TaskDefinitionDTO, TaskExecutionDTO, ProcessExecutionOptionsDTO, TaskPresentationOptionsDTO, - ProcessExecutionDTO, ShellExecutionDTO, ShellExecutionOptionsDTO, TaskDTO, TaskSourceDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO + ProcessExecutionDTO, ShellExecutionDTO, ShellExecutionOptionsDTO, TaskDTO, TaskSourceDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO, TaskSystemInfoDTO } from 'vs/workbench/api/shared/tasks'; export { TaskDTO, TaskHandleDTO, TaskExecutionDTO, TaskFilterDTO }; @@ -357,6 +357,7 @@ namespace TaskFilterDTO { @extHostNamedCustomer(MainContext.MainThreadTask) export class MainThreadTask implements MainThreadTaskShape { + private _extHostContext: IExtHostContext; private _proxy: ExtHostTaskShape; private _activeHandles: { [handle: number]: boolean; }; @@ -471,4 +472,26 @@ export class MainThreadTask implements MainThreadTaskShape { }); }); } + + public $registerTaskSystem(key: string, info: TaskSystemInfoDTO): void { + let platform: Platform.Platform; + switch (info.platform) { + case 'win32': + platform = Platform.Platform.Windows; + break; + case 'darwin': + platform = Platform.Platform.Mac; + break; + case 'linux': + platform = Platform.Platform.Linux; + break; + default: + platform = Platform.platform; + } + this._taskService.registerTaskSystem(key, { + platform: platform, + fileSystemScheme: key, + context: this._extHostContext + }); + } } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 5b9aa6c7d13e2b9d6d4328dc72c6bf02f368f058..0cd457bec02435a805d86fe7a36e13737de01289 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -48,7 +48,7 @@ import { CommentRule, CharacterPair, EnterAction } from 'vs/editor/common/modes/ import { ISingleEditOperation } from 'vs/editor/common/model'; import { IPatternInfo, IRawSearchQuery, IRawFileMatch2, ISearchCompleteStats } from 'vs/platform/search/common/search'; import { LogLevel } from 'vs/platform/log/common/log'; -import { TaskExecutionDTO, TaskDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO } from 'vs/workbench/api/shared/tasks'; +import { TaskExecutionDTO, TaskDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO, TaskSystemInfoDTO } from 'vs/workbench/api/shared/tasks'; export interface IEnvironment { isExtensionDevelopmentDebug: boolean; @@ -410,10 +410,11 @@ export interface MainThreadSearchShape extends IDisposable { export interface MainThreadTaskShape extends IDisposable { $registerTaskProvider(handle: number): TPromise; + $unregisterTaskProvider(handle: number): TPromise; $fetchTasks(filter?: TaskFilterDTO): TPromise; $executeTask(task: TaskHandleDTO | TaskDTO): TPromise; $terminateTask(id: string): TPromise; - $unregisterTaskProvider(handle: number): TPromise; + $registerTaskSystem(scheme: string, info: TaskSystemInfoDTO): void; } export interface MainThreadExtensionServiceShape extends IDisposable { diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index 3e0d3320e611ce95aac8e604e98dfe138ced160b..40a0d5789980df8eaf4534a87c14d57b356ea3e3 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -12,7 +12,7 @@ import { asWinJsPromise } from 'vs/base/common/async'; import { Event, Emitter } from 'vs/base/common/event'; import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; -import * as TaskSystem from 'vs/workbench/parts/tasks/common/tasks'; +import * as tasks from 'vs/workbench/parts/tasks/common/tasks'; import { MainContext, MainThreadTaskShape, ExtHostTaskShape, IMainContext } from 'vs/workbench/api/node/extHost.protocol'; @@ -21,7 +21,7 @@ import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; import * as vscode from 'vscode'; import { TaskDefinitionDTO, TaskExecutionDTO, TaskPresentationOptionsDTO, ProcessExecutionOptionsDTO, ProcessExecutionDTO, - ShellExecutionOptionsDTO, ShellExecutionDTO, TaskDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO + ShellExecutionOptionsDTO, ShellExecutionDTO, TaskDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO, TaskSystemInfoDTO } from '../shared/tasks'; export { TaskExecutionDTO }; @@ -197,40 +197,40 @@ namespace ProblemMatcher { */ namespace TaskRevealKind { - export function from(value: vscode.TaskRevealKind): TaskSystem.RevealKind { + export function from(value: vscode.TaskRevealKind): tasks.RevealKind { if (value === void 0 || value === null) { - return TaskSystem.RevealKind.Always; + return tasks.RevealKind.Always; } switch (value) { case types.TaskRevealKind.Silent: - return TaskSystem.RevealKind.Silent; + return tasks.RevealKind.Silent; case types.TaskRevealKind.Never: - return TaskSystem.RevealKind.Never; + return tasks.RevealKind.Never; } - return TaskSystem.RevealKind.Always; + return tasks.RevealKind.Always; } } namespace TaskPanelKind { - export function from(value: vscode.TaskPanelKind): TaskSystem.PanelKind { + export function from(value: vscode.TaskPanelKind): tasks.PanelKind { if (value === void 0 || value === null) { - return TaskSystem.PanelKind.Shared; + return tasks.PanelKind.Shared; } switch (value) { case types.TaskPanelKind.Dedicated: - return TaskSystem.PanelKind.Dedicated; + return tasks.PanelKind.Dedicated; case types.TaskPanelKind.New: - return TaskSystem.PanelKind.New; + return tasks.PanelKind.New; default: - return TaskSystem.PanelKind.Shared; + return tasks.PanelKind.Shared; } } } namespace PresentationOptions { - export function from(value: vscode.TaskPresentationOptions): TaskSystem.PresentationOptions { + export function from(value: vscode.TaskPresentationOptions): tasks.PresentationOptions { if (value === void 0 || value === null) { - return { reveal: TaskSystem.RevealKind.Always, echo: true, focus: false, panel: TaskSystem.PanelKind.Shared }; + return { reveal: tasks.RevealKind.Always, echo: true, focus: false, panel: tasks.PanelKind.Shared }; } return { reveal: TaskRevealKind.from(value.reveal), @@ -259,11 +259,11 @@ namespace CommandOptions { function isShellConfiguration(value: any): value is { executable: string; shellArgs?: string[] } { return value && typeof value.executable === 'string'; } - export function from(value: vscode.ShellExecutionOptions | vscode.ProcessExecutionOptions): TaskSystem.CommandOptions { + export function from(value: vscode.ShellExecutionOptions | vscode.ProcessExecutionOptions): tasks.CommandOptions { if (value === void 0 || value === null) { return undefined; } - let result: TaskSystem.CommandOptions = { + let result: tasks.CommandOptions = { }; if (typeof value.cwd === 'string') { result.cwd = value.cwd; @@ -285,7 +285,7 @@ namespace CommandOptions { } namespace ShellQuoteOptions { - export function from(value: vscode.ShellQuotingOptions): TaskSystem.ShellQuotingOptions { + export function from(value: vscode.ShellQuotingOptions): tasks.ShellQuotingOptions { if (value === void 0 || value === null) { return undefined; } @@ -298,12 +298,12 @@ namespace ShellQuoteOptions { } namespace ShellConfiguration { - export function from(value: { executable?: string, shellArgs?: string[], quotes?: vscode.ShellQuotingOptions }): TaskSystem.ShellConfiguration { + export function from(value: { executable?: string, shellArgs?: string[], quotes?: vscode.ShellQuotingOptions }): tasks.ShellConfiguration { if (value === void 0 || value === null || !value.executable) { return undefined; } - let result: TaskSystem.ShellConfiguration = { + let result: tasks.ShellConfiguration = { executable: value.executable, args: Strings.from(value.shellArgs), quoting: ShellQuoteOptions.from(value.quotes) @@ -313,7 +313,7 @@ namespace ShellConfiguration { } namespace ShellString { - export function from(value: (string | vscode.ShellQuotedString)[]): TaskSystem.CommandString[] { + export function from(value: (string | vscode.ShellQuotedString)[]): tasks.CommandString[] { if (value === void 0 || value === null) { return undefined; } @@ -323,11 +323,11 @@ namespace ShellString { namespace Tasks { - export function from(tasks: vscode.Task[], rootFolder: vscode.WorkspaceFolder, extension: IExtensionDescription): TaskSystem.ContributedTask[] { + export function from(tasks: vscode.Task[], rootFolder: vscode.WorkspaceFolder, extension: IExtensionDescription): tasks.ContributedTask[] { if (tasks === void 0 || tasks === null) { return []; } - let result: TaskSystem.ContributedTask[] = []; + let result: tasks.ContributedTask[] = []; for (let task of tasks) { let converted = fromSingle(task, rootFolder, extension); if (converted) { @@ -337,11 +337,11 @@ namespace Tasks { return result; } - function fromSingle(task: vscode.Task, rootFolder: vscode.WorkspaceFolder, extension: IExtensionDescription): TaskSystem.ContributedTask { + function fromSingle(task: vscode.Task, rootFolder: vscode.WorkspaceFolder, extension: IExtensionDescription): tasks.ContributedTask { if (typeof task.name !== 'string') { return undefined; } - let command: TaskSystem.CommandConfiguration; + let command: tasks.CommandConfiguration; let execution = task.execution; if (execution instanceof types.ProcessExecution) { command = getProcessCommand(execution); @@ -357,21 +357,21 @@ namespace Tasks { let taskScope: types.TaskScope.Global | types.TaskScope.Workspace | vscode.WorkspaceFolder | undefined = task.scope; let workspaceFolder: vscode.WorkspaceFolder | undefined; - let scope: TaskSystem.TaskScope; + let scope: tasks.TaskScope; // For backwards compatibility if (taskScope === void 0) { - scope = TaskSystem.TaskScope.Folder; + scope = tasks.TaskScope.Folder; workspaceFolder = rootFolder; } else if (taskScope === types.TaskScope.Global) { - scope = TaskSystem.TaskScope.Global; + scope = tasks.TaskScope.Global; } else if (taskScope === types.TaskScope.Workspace) { - scope = TaskSystem.TaskScope.Workspace; + scope = tasks.TaskScope.Workspace; } else { - scope = TaskSystem.TaskScope.Folder; + scope = tasks.TaskScope.Folder; workspaceFolder = taskScope; } - let source: TaskSystem.ExtensionTaskSource = { - kind: TaskSystem.TaskSourceKind.Extension, + let source: tasks.ExtensionTaskSource = { + kind: tasks.TaskSourceKind.Extension, label: typeof task.source === 'string' ? task.source : extension.name, extension: extension.id, scope: scope, @@ -380,17 +380,17 @@ namespace Tasks { // We can't transfer a workspace folder object from the extension host to main since they differ // in shape and we don't have backwards converting function. So transfer the URI and resolve the // workspace folder on the main side. - (source as any as TaskSystem.ExtensionTaskSourceTransfer).__workspaceFolder = workspaceFolder ? workspaceFolder.uri as URI : undefined; + (source as any as tasks.ExtensionTaskSourceTransfer).__workspaceFolder = workspaceFolder ? workspaceFolder.uri as URI : undefined; let label = nls.localize('task.label', '{0}: {1}', source.label, task.name); let key = (task as types.Task).definitionKey; let kind = (task as types.Task).definition; let id = `${extension.id}.${key}`; - let taskKind: TaskSystem.TaskIdentifier = { + let taskKind: tasks.TaskIdentifier = { _key: key, type: kind.type }; Objects.assign(taskKind, kind); - let result: TaskSystem.ContributedTask = { + let result: tasks.ContributedTask = { _id: id, // uuidMap.getUUID(identifier), _source: source, _label: label, @@ -407,14 +407,14 @@ namespace Tasks { return result; } - function getProcessCommand(value: vscode.ProcessExecution): TaskSystem.CommandConfiguration { + function getProcessCommand(value: vscode.ProcessExecution): tasks.CommandConfiguration { if (typeof value.process !== 'string') { return undefined; } - let result: TaskSystem.CommandConfiguration = { + let result: tasks.CommandConfiguration = { name: value.process, args: Strings.from(value.args), - runtime: TaskSystem.RuntimeType.Process, + runtime: tasks.RuntimeType.Process, suppressTaskName: true, presentation: undefined }; @@ -424,15 +424,15 @@ namespace Tasks { return result; } - function getShellCommand(value: vscode.ShellExecution): TaskSystem.CommandConfiguration { + function getShellCommand(value: vscode.ShellExecution): tasks.CommandConfiguration { if (value.args) { if (typeof value.command !== 'string' && typeof value.command.value !== 'string') { return undefined; } - let result: TaskSystem.CommandConfiguration = { + let result: tasks.CommandConfiguration = { name: value.command, args: ShellString.from(value.args), - runtime: TaskSystem.RuntimeType.Shell, + runtime: tasks.RuntimeType.Shell, presentation: undefined }; if (value.options) { @@ -443,9 +443,9 @@ namespace Tasks { if (typeof value.commandLine !== 'string') { return undefined; } - let result: TaskSystem.CommandConfiguration = { + let result: tasks.CommandConfiguration = { name: value.commandLine, - runtime: TaskSystem.RuntimeType.Shell, + runtime: tasks.RuntimeType.Shell, presentation: undefined }; if (value.options) { @@ -728,7 +728,7 @@ interface HandlerData { export class ExtHostTask implements ExtHostTaskShape { private _proxy: MainThreadTaskShape; - private _extHostWorkspace: ExtHostWorkspace; + private _workspaceService: ExtHostWorkspace; private _handleCounter: number; private _handlers: Map; private _taskExecutions: Map; @@ -739,16 +739,16 @@ export class ExtHostTask implements ExtHostTaskShape { private readonly _onDidTaskProcessStarted: Emitter = new Emitter(); private readonly _onDidTaskProcessEnded: Emitter = new Emitter(); - constructor(mainContext: IMainContext, extHostWorkspace: ExtHostWorkspace) { + constructor(mainContext: IMainContext, workspaceService: ExtHostWorkspace) { this._proxy = mainContext.getProxy(MainContext.MainThreadTask); - this._extHostWorkspace = extHostWorkspace; + this._workspaceService = workspaceService; this._handleCounter = 0; this._handlers = new Map(); this._taskExecutions = new Map(); } public get extHostWorkspace(): ExtHostWorkspace { - return this._extHostWorkspace; + return this._workspaceService; } public registerTaskProvider(extension: IExtensionDescription, provider: vscode.TaskProvider): vscode.Disposable { @@ -764,11 +764,15 @@ export class ExtHostTask implements ExtHostTaskShape { }); } + public registerTaskSystem(scheme: string, info: TaskSystemInfoDTO): void { + this._proxy.$registerTaskSystem(scheme, info); + } + public fetchTasks(filter?: vscode.TaskFilter): Thenable { return this._proxy.$fetchTasks(TaskFilterDTO.from(filter)).then((values) => { let result: vscode.Task[] = []; for (let value of values) { - let task = TaskDTO.to(value, this._extHostWorkspace); + let task = TaskDTO.to(value, this._workspaceService); if (task) { result.push(task); } @@ -854,13 +858,13 @@ export class ExtHostTask implements ExtHostTaskShape { } } - public $provideTasks(handle: number): TPromise { + public $provideTasks(handle: number): TPromise { let handler = this._handlers.get(handle); if (!handler) { - return TPromise.wrapError(new Error('no handler found')); + return TPromise.wrapError(new Error('no handler found')); } return asWinJsPromise(token => handler.provider.provideTasks(token)).then(value => { - let workspaceFolders = this._extHostWorkspace.getWorkspaceFolders(); + let workspaceFolders = this._workspaceService.getWorkspaceFolders(); return { tasks: Tasks.from(value, workspaceFolders && workspaceFolders.length > 0 ? workspaceFolders[0] : undefined, handler.extension), extension: handler.extension @@ -881,7 +885,7 @@ export class ExtHostTask implements ExtHostTaskShape { if (result) { return result; } - result = new TaskExecutionImpl(this, execution.id, task ? task : TaskDTO.to(execution.task, this._extHostWorkspace)); + result = new TaskExecutionImpl(this, execution.id, task ? task : TaskDTO.to(execution.task, this._workspaceService)); this._taskExecutions.set(execution.id, result); return result; } diff --git a/src/vs/workbench/api/shared/tasks.ts b/src/vs/workbench/api/shared/tasks.ts index 29ac9b413ecf6fc5c8f29e668b8a99baa3b77cef..eb07410791267963f798659c3b2df703e1c579c2 100644 --- a/src/vs/workbench/api/shared/tasks.ts +++ b/src/vs/workbench/api/shared/tasks.ts @@ -102,4 +102,8 @@ export interface TaskProcessEndedDTO { export interface TaskFilterDTO { version?: string; type?: string; +} + +export interface TaskSystemInfoDTO { + platform: string; } \ No newline at end of file diff --git a/src/vs/workbench/parts/tasks/common/problemMatcher.ts b/src/vs/workbench/parts/tasks/common/problemMatcher.ts index 9c471739990fc461dbf5d7fd56ba0fcf5ad4ad52..b2b792cfe023f302995330f8018f2b7056db863e 100644 --- a/src/vs/workbench/parts/tasks/common/problemMatcher.ts +++ b/src/vs/workbench/parts/tasks/common/problemMatcher.ts @@ -134,6 +134,7 @@ export interface ProblemMatcher { pattern: ProblemPattern | ProblemPattern[]; severity?: Severity; watching?: WatchingMatcher; + fileSystemScheme?: string; } export interface NamedProblemMatcher extends ProblemMatcher { @@ -195,7 +196,11 @@ export function getResource(filename: string, matcher: ProblemMatcher): URI { if (fullPath[0] !== '/') { fullPath = '/' + fullPath; } - return URI.parse('file://' + fullPath); + if (matcher.fileSystemScheme !== void 0) { + return URI.parse(`${matcher.fileSystemScheme}://${fullPath}`); + } else { + return URI.file(fullPath); + } } export interface ILineMatcher { diff --git a/src/vs/workbench/parts/tasks/common/taskService.ts b/src/vs/workbench/parts/tasks/common/taskService.ts index 4a889b479eb776b726356a9f5b12f3fd1fc7db0e..0ec754fd1c73fdd7d2d6789888ee89b5838bde13 100644 --- a/src/vs/workbench/parts/tasks/common/taskService.ts +++ b/src/vs/workbench/parts/tasks/common/taskService.ts @@ -12,7 +12,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { Task, ContributedTask, CustomTask, TaskSet, TaskSorter, TaskEvent } from 'vs/workbench/parts/tasks/common/tasks'; -import { ITaskSummary, TaskTerminateResponse } from 'vs/workbench/parts/tasks/common/taskSystem'; +import { ITaskSummary, TaskTerminateResponse, TaskSystemInfo } from 'vs/workbench/parts/tasks/common/taskSystem'; export { ITaskSummary, Task, TaskTerminateResponse }; @@ -66,4 +66,6 @@ export interface ITaskService { registerTaskProvider(handle: number, taskProvider: ITaskProvider): void; unregisterTaskProvider(handle: number): boolean; + + registerTaskSystem(scheme: string, taskSystemInfo: TaskSystemInfo): void; } \ No newline at end of file diff --git a/src/vs/workbench/parts/tasks/common/taskSystem.ts b/src/vs/workbench/parts/tasks/common/taskSystem.ts index d88cca89e951e82521bab74e6f4a4aa280dd8b26..764f5e052acfa95c23f3db0d51ebddd4b0fc1a56 100644 --- a/src/vs/workbench/parts/tasks/common/taskSystem.ts +++ b/src/vs/workbench/parts/tasks/common/taskSystem.ts @@ -8,6 +8,7 @@ import Severity from 'vs/base/common/severity'; import { TPromise } from 'vs/base/common/winjs.base'; import { TerminateResponse } from 'vs/base/common/processes'; import { Event } from 'vs/base/common/event'; +import { Platform } from 'vs/base/common/platform'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; @@ -101,6 +102,16 @@ export interface TaskTerminateResponse extends TerminateResponse { task: Task | undefined; } +export interface TaskSystemInfo { + fileSystemScheme: string; + platform: Platform; + context: any; +} + +export interface TaskSystemInfoResovler { + (workspaceFolder: IWorkspaceFolder): TaskSystemInfo; +} + export interface ITaskSystem { onDidStateChange: Event; run(task: Task, resolver: ITaskResolver): ITaskExecuteResult; diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts index c065df2638260e34e9dd868f5364a999db15ed4d..76796568a072a4871563d0af54454c3951ff18b8 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -25,6 +25,7 @@ import { TerminateResponseCode } from 'vs/base/common/processes'; import * as strings from 'vs/base/common/strings'; import { ValidationStatus, ValidationState } from 'vs/base/common/parsers'; import * as UUID from 'vs/base/common/uuid'; +import * as Platform from 'vs/base/common/platform'; import { LinkedMap, Touch } from 'vs/base/common/map'; import { OcticonLabel } from 'vs/base/browser/ui/octiconLabel/octiconLabel'; @@ -70,7 +71,7 @@ import { Scope, IActionBarRegistry, Extensions as ActionBarExtensions } from 'vs import { ITerminalService } from 'vs/workbench/parts/terminal/common/terminal'; -import { ITaskSystem, ITaskResolver, ITaskSummary, TaskExecuteKind, TaskError, TaskErrors, TaskTerminateResponse } from 'vs/workbench/parts/tasks/common/taskSystem'; +import { ITaskSystem, ITaskResolver, ITaskSummary, TaskExecuteKind, TaskError, TaskErrors, TaskTerminateResponse, TaskSystemInfo } from 'vs/workbench/parts/tasks/common/taskSystem'; import { Task, CustomTask, ConfiguringTask, ContributedTask, InMemoryTask, TaskEvent, TaskEventKind, TaskSet, TaskGroup, GroupType, ExecutionEngine, JsonSchemaVersion, TaskSourceKind, @@ -442,12 +443,13 @@ class TaskService implements ITaskService { public static OutputChannelLabel: string = nls.localize('tasks', "Tasks"); private _configHasErrors: boolean; - private __schemaVersion: JsonSchemaVersion; - private __executionEngine: ExecutionEngine; - private __workspaceFolders: IWorkspaceFolder[]; - private __ignoredWorkspaceFolders: IWorkspaceFolder[]; - private __showIgnoreMessage: boolean; + private _schemaVersion: JsonSchemaVersion; + private _executionEngine: ExecutionEngine; + private _workspaceFolders: IWorkspaceFolder[]; + private _ignoredWorkspaceFolders: IWorkspaceFolder[]; + private _showIgnoreMessage: boolean; private _providers: Map; + private _taskSystemInfos: Map; private _workspaceTasksPromise: TPromise>; @@ -486,6 +488,7 @@ class TaskService implements ITaskService { this._taskSystemListener = undefined; this._outputChannel = this.outputService.getChannel(TaskService.OutputChannelId); this._providers = new Map(); + this._taskSystemInfos = new Map(); this.configurationService.onDidChangeConfiguration(() => { if (!this._taskSystem && !this._workspaceTasksPromise) { return; @@ -584,62 +587,62 @@ class TaskService implements ITaskService { } private get workspaceFolders(): IWorkspaceFolder[] { - if (!this.__workspaceFolders) { + if (!this._workspaceFolders) { this.updateSetup(); } - return this.__workspaceFolders; + return this._workspaceFolders; } private get ignoredWorkspaceFolders(): IWorkspaceFolder[] { - if (!this.__ignoredWorkspaceFolders) { + if (!this._ignoredWorkspaceFolders) { this.updateSetup(); } - return this.__ignoredWorkspaceFolders; + return this._ignoredWorkspaceFolders; } private get executionEngine(): ExecutionEngine { - if (this.__executionEngine === void 0) { + if (this._executionEngine === void 0) { this.updateSetup(); } - return this.__executionEngine; + return this._executionEngine; } private get schemaVersion(): JsonSchemaVersion { - if (this.__schemaVersion === void 0) { + if (this._schemaVersion === void 0) { this.updateSetup(); } - return this.__schemaVersion; + return this._schemaVersion; } private get showIgnoreMessage(): boolean { - if (this.__showIgnoreMessage === void 0) { - this.__showIgnoreMessage = !this.storageService.getBoolean(TaskService.IgnoreTask010DonotShowAgain_key, StorageScope.WORKSPACE, false); + if (this._showIgnoreMessage === void 0) { + this._showIgnoreMessage = !this.storageService.getBoolean(TaskService.IgnoreTask010DonotShowAgain_key, StorageScope.WORKSPACE, false); } - return this.__showIgnoreMessage; + return this._showIgnoreMessage; } private updateSetup(setup?: [IWorkspaceFolder[], IWorkspaceFolder[], ExecutionEngine, JsonSchemaVersion]): void { if (!setup) { setup = this.computeWorkspaceFolderSetup(); } - this.__workspaceFolders = setup[0]; - if (this.__ignoredWorkspaceFolders) { - if (this.__ignoredWorkspaceFolders.length !== setup[1].length) { - this.__showIgnoreMessage = undefined; + this._workspaceFolders = setup[0]; + if (this._ignoredWorkspaceFolders) { + if (this._ignoredWorkspaceFolders.length !== setup[1].length) { + this._showIgnoreMessage = undefined; } else { let set: Set = new Set(); - this.__ignoredWorkspaceFolders.forEach(folder => set.add(folder.uri.toString())); + this._ignoredWorkspaceFolders.forEach(folder => set.add(folder.uri.toString())); for (let folder of setup[1]) { if (!set.has(folder.uri.toString())) { - this.__showIgnoreMessage = undefined; + this._showIgnoreMessage = undefined; break; } } } } - this.__ignoredWorkspaceFolders = setup[1]; - this.__executionEngine = setup[2]; - this.__schemaVersion = setup[3]; + this._ignoredWorkspaceFolders = setup[1]; + this._executionEngine = setup[2]; + this._schemaVersion = setup[3]; } private showOutput(): void { @@ -663,6 +666,10 @@ class TaskService implements ITaskService { return this._providers.delete(handle); } + public registerTaskSystem(key: string, info: TaskSystemInfo): void { + this._taskSystemInfos.set(key, info); + } + public getTask(folder: IWorkspaceFolder | string, alias: string, compareId: boolean = false): TPromise { let name = Types.isString(folder) ? folder : folder.name; if (this.ignoredWorkspaceFolders.some(ignored => ignored.name === name)) { @@ -1244,7 +1251,13 @@ class TaskService implements ITaskService { this._taskSystem = new TerminalTaskSystem( this.terminalService, this.outputService, this.markerService, this.modelService, this.configurationResolverService, this.telemetryService, - this.contextService, TaskService.OutputChannelId + this.contextService, TaskService.OutputChannelId, + (workspaceFolder: IWorkspaceFolder) => { + if (!workspaceFolder) { + return undefined; + } + return this._taskSystemInfos.get(workspaceFolder.uri.scheme); + } ); } else { let system = new ProcessTaskSystem( @@ -1472,8 +1485,9 @@ class TaskService implements ITaskService { return TPromise.as({ workspaceFolder, set: undefined, configurations: undefined, hasErrors: workspaceFolderConfiguration ? workspaceFolderConfiguration.hasErrors : false }); } return ProblemMatcherRegistry.onReady().then((): WorkspaceFolderTaskResult => { + let taskSystemInfo: TaskSystemInfo = this._taskSystemInfos.get(workspaceFolder.uri.scheme); let problemReporter = new ProblemReporter(this._outputChannel); - let parseResult = TaskConfig.parse(workspaceFolder, workspaceFolderConfiguration.config, problemReporter); + let parseResult = TaskConfig.parse(workspaceFolder, taskSystemInfo ? taskSystemInfo.platform : Platform.platform, workspaceFolderConfiguration.config, problemReporter); let hasErrors = false; if (!parseResult.validationStatus.isOK()) { hasErrors = true; @@ -1869,7 +1883,7 @@ class TaskService implements ITaskService { isSecondary: true, run: () => { this.storageService.store(TaskService.IgnoreTask010DonotShowAgain_key, true, StorageScope.WORKSPACE); - this.__showIgnoreMessage = false; + this._showIgnoreMessage = false; } }] ); diff --git a/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts b/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts index b7110508ffd005c2175e55368aaf42c337a1c159..4559dd972522c152c16119b3ff9f0cd6b6c5cd1f 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts @@ -37,7 +37,7 @@ import { } from 'vs/workbench/parts/tasks/common/tasks'; import { ITaskSystem, ITaskSummary, ITaskExecuteResult, TaskExecuteKind, TaskError, TaskErrors, ITaskResolver, - TelemetryEvent, Triggers, TaskTerminateResponse + TelemetryEvent, Triggers, TaskTerminateResponse, TaskSystemInfoResovler, TaskSystemInfo } from 'vs/workbench/parts/tasks/common/taskSystem'; interface TerminalData { @@ -96,6 +96,7 @@ export class TerminalTaskSystem implements ITaskSystem { private terminals: IStringDictionary; private idleTaskTerminals: LinkedMap; private sameTaskTerminals: IStringDictionary; + private taskSystemInfoResolver: TaskSystemInfoResovler; private readonly _onDidStateChange: Emitter; @@ -104,7 +105,8 @@ export class TerminalTaskSystem implements ITaskSystem { private configurationResolverService: IConfigurationResolverService, private telemetryService: ITelemetryService, private contextService: IWorkspaceContextService, - outputChannelId: string) { + outputChannelId: string, + taskSystemInfoResolver: TaskSystemInfoResovler) { this.outputChannel = this.outputService.getChannel(outputChannelId); this.activeTasks = Object.create(null); @@ -113,6 +115,7 @@ export class TerminalTaskSystem implements ITaskSystem { this.sameTaskTerminals = Object.create(null); this._onDidStateChange = new Emitter(); + this.taskSystemInfoResolver = taskSystemInfoResolver; } public get onDidStateChange(): Event { @@ -830,11 +833,23 @@ export class TerminalTaskSystem implements ITaskSystem { this.outputChannel.append(nls.localize('unkownProblemMatcher', 'Problem matcher {0} can\'t be resolved. The matcher will be ignored')); return; } - if (!matcher.filePrefix) { + let workspaceFolder = Task.getWorkspaceFolder(task); + let taskSystemInfo: TaskSystemInfo; + if (workspaceFolder) { + taskSystemInfo = this.taskSystemInfoResolver(workspaceFolder); + } + let hasFilePrefix = matcher.filePrefix !== void 0; + let hasScheme = taskSystemInfo !== void 0 && taskSystemInfo.fileSystemScheme !== void 0 && taskSystemInfo.fileSystemScheme === 'file'; + if (!hasFilePrefix && !hasScheme) { result.push(matcher); } else { let copy = Objects.deepClone(matcher); - copy.filePrefix = this.resolveVariable(task, copy.filePrefix); + if (hasScheme) { + copy.fileSystemScheme = taskSystemInfo.fileSystemScheme; + } + if (hasFilePrefix) { + copy.filePrefix = this.resolveVariable(task, copy.filePrefix); + } result.push(copy); } }); diff --git a/src/vs/workbench/parts/tasks/node/taskConfiguration.ts b/src/vs/workbench/parts/tasks/node/taskConfiguration.ts index 70046911938f3b6034996f292cc7ef5f1b6d5c4e..c4fbf4293a607f45ba6c74ab7cdaa73bfe30e43c 100644 --- a/src/vs/workbench/parts/tasks/node/taskConfiguration.ts +++ b/src/vs/workbench/parts/tasks/node/taskConfiguration.ts @@ -10,7 +10,7 @@ import * as nls from 'vs/nls'; import * as Objects from 'vs/base/common/objects'; import { IStringDictionary } from 'vs/base/common/collections'; -import * as Platform from 'vs/base/common/platform'; +import { Platform } from 'vs/base/common/platform'; import * as Types from 'vs/base/common/types'; import * as UUID from 'vs/base/common/uuid'; @@ -614,6 +614,7 @@ interface ParseContext { uuidMap: UUIDMap; engine: Tasks.ExecutionEngine; schemaVersion: Tasks.JsonSchemaVersion; + platform: Platform; } @@ -829,11 +830,11 @@ namespace CommandConfiguration { let result: Tasks.CommandConfiguration = fromBase(config, context); let osConfig: Tasks.CommandConfiguration = undefined; - if (config.windows && Platform.platform === Platform.Platform.Windows) { + if (config.windows && context.platform === Platform.Windows) { osConfig = fromBase(config.windows, context); - } else if (config.osx && Platform.platform === Platform.Platform.Mac) { + } else if (config.osx && context.platform === Platform.Mac) { osConfig = fromBase(config.osx, context); - } else if (config.linux && Platform.platform === Platform.Platform.Linux) { + } else if (config.linux && context.platform === Platform.Linux) { osConfig = fromBase(config.linux, context); } if (osConfig) { @@ -1553,11 +1554,11 @@ namespace Globals { export function from(config: ExternalTaskRunnerConfiguration, context: ParseContext): Globals { let result = fromBase(config, context); let osGlobals: Globals = undefined; - if (config.windows && Platform.platform === Platform.Platform.Windows) { + if (config.windows && context.platform === Platform.Windows) { osGlobals = fromBase(config.windows, context); - } else if (config.osx && Platform.platform === Platform.Platform.Mac) { + } else if (config.osx && context.platform === Platform.Mac) { osGlobals = fromBase(config.osx, context); - } else if (config.linux && Platform.platform === Platform.Platform.Linux) { + } else if (config.linux && context.platform === Platform.Linux) { osGlobals = fromBase(config.linux, context); } if (osGlobals) { @@ -1742,9 +1743,11 @@ class ConfigurationParser { private workspaceFolder: IWorkspaceFolder; private problemReporter: IProblemReporter; private uuidMap: UUIDMap; + private platform: Platform; - constructor(workspaceFolder: IWorkspaceFolder, problemReporter: IProblemReporter, uuidMap: UUIDMap) { + constructor(workspaceFolder: IWorkspaceFolder, platform: Platform, problemReporter: IProblemReporter, uuidMap: UUIDMap) { this.workspaceFolder = workspaceFolder; + this.platform = platform; this.problemReporter = problemReporter; this.uuidMap = uuidMap; } @@ -1758,7 +1761,8 @@ class ConfigurationParser { uuidMap: this.uuidMap, namedProblemMatchers: undefined, engine, - schemaVersion + schemaVersion, + platform: this.platform }; let taskParseResult = this.createTaskRunnerConfiguration(fileConfig, context); return { @@ -1777,13 +1781,13 @@ class ConfigurationParser { context.namedProblemMatchers = ProblemMatcherConverter.namedFrom(fileConfig.declares, context); let globalTasks: Tasks.CustomTask[]; let externalGlobalTasks: (ConfiguringTask | CustomTask)[]; - if (fileConfig.windows && Platform.platform === Platform.Platform.Windows) { + if (fileConfig.windows && context.platform === Platform.Windows) { globalTasks = TaskParser.from(fileConfig.windows.tasks, globals, context).custom; externalGlobalTasks = fileConfig.windows.tasks; - } else if (fileConfig.osx && Platform.platform === Platform.Platform.Mac) { + } else if (fileConfig.osx && context.platform === Platform.Mac) { globalTasks = TaskParser.from(fileConfig.osx.tasks, globals, context).custom; externalGlobalTasks = fileConfig.osx.tasks; - } else if (fileConfig.linux && Platform.platform === Platform.Platform.Linux) { + } else if (fileConfig.linux && context.platform === Platform.Linux) { globalTasks = TaskParser.from(fileConfig.linux.tasks, globals, context).custom; externalGlobalTasks = fileConfig.linux.tasks; } @@ -1846,7 +1850,7 @@ class ConfigurationParser { } let uuidMaps: Map = new Map(); -export function parse(workspaceFolder: IWorkspaceFolder, configuration: ExternalTaskRunnerConfiguration, logger: IProblemReporter): ParseResult { +export function parse(workspaceFolder: IWorkspaceFolder, platform: Platform, configuration: ExternalTaskRunnerConfiguration, logger: IProblemReporter): ParseResult { let uuidMap = uuidMaps.get(workspaceFolder.uri.toString()); if (!uuidMap) { uuidMap = new UUIDMap(); @@ -1854,7 +1858,7 @@ export function parse(workspaceFolder: IWorkspaceFolder, configuration: External } try { uuidMap.start(); - return (new ConfigurationParser(workspaceFolder, logger, uuidMap)).run(configuration); + return (new ConfigurationParser(workspaceFolder, platform, logger, uuidMap)).run(configuration); } finally { uuidMap.finish(); } diff --git a/src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts b/src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts index 5b8e2ec31a2f531d9922ec4e20a3e4b7e0fd7afa..725807575b475d28815f4a0fd5affcb32c9d529e 100644 --- a/src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts +++ b/src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts @@ -350,7 +350,7 @@ class PatternBuilder { function testDefaultProblemMatcher(external: ExternalTaskRunnerConfiguration, resolved: number) { let reporter = new ProblemReporter(); - let result = parse(workspaceFolder, external, reporter); + let result = parse(workspaceFolder, Platform.platform, external, reporter); assert.ok(!reporter.receivedMessage); assert.strictEqual(result.custom.length, 1); let task = result.custom[0]; @@ -361,7 +361,7 @@ function testDefaultProblemMatcher(external: ExternalTaskRunnerConfiguration, re function testConfiguration(external: ExternalTaskRunnerConfiguration, builder: ConfiguationBuilder): void { builder.done(); let reporter = new ProblemReporter(); - let result = parse(workspaceFolder, external, reporter); + let result = parse(workspaceFolder, Platform.platform, external, reporter); if (reporter.receivedMessage) { assert.ok(false, reporter.lastMessage); }