diff --git a/src/vs/base/common/processes.ts b/src/vs/base/common/processes.ts index f563a8443a95ae430b5397b43064fe45cd1220ee..afd581318cd1f408e7048a9518b833e2c4a46d42 100644 --- a/src/vs/base/common/processes.ts +++ b/src/vs/base/common/processes.ts @@ -11,8 +11,7 @@ import * as Platform from 'vs/base/common/platform'; import { IStringDictionary } from 'vs/base/common/collections'; import * as Types from 'vs/base/common/types'; -import { ValidationStatus, ValidationState, ILogger, Parser, ISystemVariables } from 'vs/base/common/parsers'; - +import { ValidationStatus, ValidationState, ILogger, Parser } from 'vs/base/common/parsers'; /** * Options to be passed to the external program or shell. @@ -252,24 +251,3 @@ export class ExecutableParser extends Parser { return executable; } } - -export function resolveCommandOptions(options: CommandOptions, variables: ISystemVariables): CommandOptions { - let result = Objects.clone(options); - if (result.cwd) { - result.cwd = variables.resolve(result.cwd); - } - if (result.env) { - result.env = variables.resolve(result.env); - } - return result; -} - -export function resolveExecutable(executable: Executable, variables: ISystemVariables): Executable { - let result = Objects.clone(executable); - result.command = variables.resolve(result.command); - result.args = variables.resolve(result.args); - if (result.options) { - result.options = resolveCommandOptions(result.options, variables); - } - return result; -} \ No newline at end of file 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 58038a8fb4e3cf4c4c087995096f2814e454ac53..dc5319eb7cbe70b4d04beeb821e350b2d48e9c6b 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -54,9 +54,9 @@ import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import Constants from 'vs/workbench/parts/markers/common/constants'; import { IPartService } from 'vs/workbench/services/part/common/partService'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { ConfigVariables } from 'vs/workbench/parts/lib/node/configVariables'; import { ITextFileService } from 'vs/workbench/parts/files/common/files'; import { IOutputService, IOutputChannelRegistry, Extensions as OutputExt, IOutputChannel } from 'vs/workbench/parts/output/common/output'; @@ -184,7 +184,8 @@ abstract class OpenTaskConfigurationAction extends Action { @IWorkbenchEditorService editorService: IWorkbenchEditorService, @IFileService fileService: IFileService, @IWorkspaceContextService contextService: IWorkspaceContextService, @IOutputService outputService: IOutputService, @IMessageService messageService: IMessageService, @IQuickOpenService quickOpenService: IQuickOpenService, - @IEnvironmentService private environmentService: IEnvironmentService) { + @IEnvironmentService private environmentService: IEnvironmentService, + @IConfigurationResolverService private configurationResolverService: IConfigurationResolverService) { super(id, label); this.configurationService = configurationService; @@ -216,7 +217,7 @@ abstract class OpenTaskConfigurationAction extends Action { const outputChannel = this.outputService.getChannel(TaskService.OutputChannelId); outputChannel.show(); outputChannel.append(nls.localize('ConfigureTaskRunnerAction.autoDetecting', 'Auto detecting tasks for {0}', selection.id) + '\n'); - let detector = new ProcessRunnerDetector(this.fileService, this.contextService, new ConfigVariables(this.configurationService, this.editorService, this.contextService, this.environmentService)); + let detector = new ProcessRunnerDetector(this.fileService, this.contextService, this.configurationResolverService); contentPromise = detector.detect(false, selection.id).then((value) => { let config = value.config; if (value.stderr && value.stderr.length > 0) { @@ -278,9 +279,10 @@ class ConfigureTaskRunnerAction extends OpenTaskConfigurationAction { @IWorkbenchEditorService editorService: IWorkbenchEditorService, @IFileService fileService: IFileService, @IWorkspaceContextService contextService: IWorkspaceContextService, @IOutputService outputService: IOutputService, @IMessageService messageService: IMessageService, @IQuickOpenService quickOpenService: IQuickOpenService, - @IEnvironmentService environmentService: IEnvironmentService) { + @IEnvironmentService environmentService: IEnvironmentService, + @IConfigurationResolverService configurationResolverService: IConfigurationResolverService) { super(id, label, configurationService, editorService, fileService, contextService, - outputService, messageService, quickOpenService, environmentService); + outputService, messageService, quickOpenService, environmentService, configurationResolverService); } } @@ -293,9 +295,10 @@ class ConfigureBuildTaskAction extends OpenTaskConfigurationAction { @IWorkbenchEditorService editorService: IWorkbenchEditorService, @IFileService fileService: IFileService, @IWorkspaceContextService contextService: IWorkspaceContextService, @IOutputService outputService: IOutputService, @IMessageService messageService: IMessageService, @IQuickOpenService quickOpenService: IQuickOpenService, - @IEnvironmentService environmentService: IEnvironmentService) { + @IEnvironmentService environmentService: IEnvironmentService, + @IConfigurationResolverService configurationResolverService: IConfigurationResolverService) { super(id, label, configurationService, editorService, fileService, contextService, - outputService, messageService, quickOpenService, environmentService); + outputService, messageService, quickOpenService, environmentService, configurationResolverService); } } @@ -628,7 +631,8 @@ class TaskService extends EventEmitter implements ITaskService { @ILifecycleService lifecycleService: ILifecycleService, @IEventService eventService: IEventService, @IModelService modelService: IModelService, @IExtensionService extensionService: IExtensionService, @IQuickOpenService quickOpenService: IQuickOpenService, - @IEnvironmentService private environmentService: IEnvironmentService) { + @IEnvironmentService private environmentService: IEnvironmentService, + @IConfigurationResolverService private configurationResolverService: IConfigurationResolverService) { super(); this.modeService = modeService; @@ -680,7 +684,6 @@ class TaskService extends EventEmitter implements ITaskService { this._taskSystem = new NullTaskSystem(); this._taskSystemPromise = TPromise.as(this._taskSystem); } else { - let variables = new ConfigVariables(this.configurationService, this.editorService, this.contextService, this.environmentService); let clearOutput = true; this._taskSystemPromise = TPromise.as(this.configurationService.getConfiguration('tasks')).then((config: TaskConfiguration) => { let parseErrors: string[] = config ? (config).$parseErrors : null; @@ -702,7 +705,7 @@ class TaskService extends EventEmitter implements ITaskService { if (config) { if (this.isRunnerConfig(config) && this.hasDetectorSupport(config)) { let fileConfig = config; - configPromise = new ProcessRunnerDetector(this.fileService, this.contextService, variables, fileConfig).detect(true).then((value) => { + configPromise = new ProcessRunnerDetector(this.fileService, this.contextService, this.configurationResolverService, fileConfig).detect(true).then((value) => { clearOutput = this.printStderr(value.stderr); let detectedConfig = value.config; if (!detectedConfig) { @@ -728,7 +731,7 @@ class TaskService extends EventEmitter implements ITaskService { configPromise = TPromise.as(config); } } else { - configPromise = new ProcessRunnerDetector(this.fileService, this.contextService, variables).detect(true).then((value) => { + configPromise = new ProcessRunnerDetector(this.fileService, this.contextService, this.configurationResolverService).detect(true).then((value) => { clearOutput = this.printStderr(value.stderr); return value.config; }); @@ -742,7 +745,7 @@ class TaskService extends EventEmitter implements ITaskService { if (config.buildSystem === 'service') { result = new LanguageServiceTaskSystem(config, this.telemetryService, this.modeService); } else if (this.isRunnerConfig(config)) { - result = new ProcessRunnerSystem(config, variables, this.markerService, this.modelService, this.telemetryService, this.outputService, TaskService.OutputChannelId, clearOutput); + result = new ProcessRunnerSystem(config, this.markerService, this.modelService, this.telemetryService, this.outputService, this.configurationResolverService, TaskService.OutputChannelId, clearOutput); } if (result === null) { this._taskSystemPromise = null; @@ -788,13 +791,13 @@ class TaskService extends EventEmitter implements ITaskService { public configureAction(): Action { return new ConfigureTaskRunnerAction(ConfigureTaskRunnerAction.ID, ConfigureTaskRunnerAction.TEXT, this.configurationService, this.editorService, this.fileService, this.contextService, - this.outputService, this.messageService, this.quickOpenService, this.environmentService); + this.outputService, this.messageService, this.quickOpenService, this.environmentService, this.configurationResolverService); } private configureBuildTask(): Action { return new ConfigureBuildTaskAction(ConfigureBuildTaskAction.ID, ConfigureBuildTaskAction.TEXT, this.configurationService, this.editorService, this.fileService, this.contextService, - this.outputService, this.messageService, this.quickOpenService, this.environmentService); + this.outputService, this.messageService, this.quickOpenService, this.environmentService, this.configurationResolverService); } public build(): TPromise { diff --git a/src/vs/workbench/parts/tasks/node/processRunnerDetector.ts b/src/vs/workbench/parts/tasks/node/processRunnerDetector.ts index 39704103f195cefcfcdb3e9b5e76518374f3640a..14a4f1f56befba1e86eb3490520d7d05556910cf 100644 --- a/src/vs/workbench/parts/tasks/node/processRunnerDetector.ts +++ b/src/vs/workbench/parts/tasks/node/processRunnerDetector.ts @@ -5,16 +5,19 @@ 'use strict'; import nls = require('vs/nls'); +import * as Objects from 'vs/base/common/objects'; +import * as Paths from 'vs/base/common/paths'; import { TPromise } from 'vs/base/common/winjs.base'; import Strings = require('vs/base/common/strings'); import Collections = require('vs/base/common/collections'); -import { CommandOptions, resolveCommandOptions, Source, ErrorData } from 'vs/base/common/processes'; +import { CommandOptions, Source, ErrorData } from 'vs/base/common/processes'; import { LineProcess } from 'vs/base/node/processes'; import { IFileService } from 'vs/platform/files/common/files'; -import { SystemVariables } from 'vs/workbench/parts/lib/node/systemVariables'; +import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; + import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import * as FileConfig from './processRunnerConfiguration'; @@ -139,18 +142,21 @@ export class ProcessRunnerDetector { private fileService: IFileService; private contextService: IWorkspaceContextService; - private variables: SystemVariables; + private configurationResolverService: IConfigurationResolverService; private taskConfiguration: FileConfig.ExternalTaskRunnerConfiguration; private _stderr: string[]; private _stdout: string[]; + private _cwd: string; - constructor(fileService: IFileService, contextService: IWorkspaceContextService, variables:SystemVariables, config: FileConfig.ExternalTaskRunnerConfiguration = null) { + constructor(fileService: IFileService, contextService: IWorkspaceContextService, configurationResolverService: IConfigurationResolverService, config: FileConfig.ExternalTaskRunnerConfiguration = null) { this.fileService = fileService; this.contextService = contextService; - this.variables = variables; + this.configurationResolverService = configurationResolverService; this.taskConfiguration = config; this._stderr = []; this._stdout = []; + const workspace = this.contextService.getWorkspace(); + this._cwd = workspace ? Paths.normalize(workspace.resource.fsPath, true) : ''; } public get stderr(): string[] { @@ -165,10 +171,10 @@ export class ProcessRunnerDetector { if (this.taskConfiguration && this.taskConfiguration.command && ProcessRunnerDetector.supports(this.taskConfiguration.command)) { let config = ProcessRunnerDetector.detectorConfig(this.taskConfiguration.command); let args = (this.taskConfiguration.args || []).concat(config.arg); - let options: CommandOptions = this.taskConfiguration.options ? resolveCommandOptions(this.taskConfiguration.options, this.variables) : { cwd: this.variables.workspaceRoot }; + let options: CommandOptions = this.taskConfiguration.options ? this.resolveCommandOptions(this.taskConfiguration.options) : { cwd: this._cwd }; let isShellCommand = !!this.taskConfiguration.isShellCommand; return this.runDetection( - new LineProcess(this.taskConfiguration.command, this.variables.resolve(args), isShellCommand, options), + new LineProcess(this.taskConfiguration.command, this.configurationResolverService.resolve(args), isShellCommand, options), this.taskConfiguration.command, isShellCommand, config.matcher, ProcessRunnerDetector.DefaultProblemMatchers, list); } else { if (detectSpecific) { @@ -208,10 +214,21 @@ export class ProcessRunnerDetector { } } + private resolveCommandOptions(options: CommandOptions): CommandOptions { + let result = Objects.clone(options); + if (result.cwd) { + result.cwd = this.configurationResolverService.resolve(result.cwd); + } + if (result.env) { + result.env = this.configurationResolverService.resolve(result.env); + } + return result; + } + private tryDetectGulp(list:boolean): TPromise<{ config: FileConfig.ExternalTaskRunnerConfiguration; stderr: string[]; }> { return this.fileService.resolveFile(this.contextService.toResource('gulpfile.js')).then((stat) => { let config = ProcessRunnerDetector.detectorConfig('gulp'); - let process = new LineProcess('gulp', [config.arg, '--no-color'], true, {cwd: this.variables.workspaceRoot}); + let process = new LineProcess('gulp', [config.arg, '--no-color'], true, {cwd: this._cwd}); return this.runDetection(process, 'gulp', true, config.matcher, ProcessRunnerDetector.DefaultProblemMatchers, list); }, (err: any): FileConfig.ExternalTaskRunnerConfiguration => { return null; @@ -221,7 +238,7 @@ export class ProcessRunnerDetector { private tryDetectGrunt(list:boolean): TPromise<{ config: FileConfig.ExternalTaskRunnerConfiguration; stderr: string[]; }> { return this.fileService.resolveFile(this.contextService.toResource('Gruntfile.js')).then((stat) => { let config = ProcessRunnerDetector.detectorConfig('grunt'); - let process = new LineProcess('grunt', [config.arg, '--no-color'], true, {cwd: this.variables.workspaceRoot}); + let process = new LineProcess('grunt', [config.arg, '--no-color'], true, {cwd: this._cwd}); return this.runDetection(process, 'grunt', true, config.matcher, ProcessRunnerDetector.DefaultProblemMatchers, list); }, (err: any): FileConfig.ExternalTaskRunnerConfiguration => { return null; @@ -231,7 +248,7 @@ export class ProcessRunnerDetector { private tryDetectJake(list:boolean): TPromise<{ config: FileConfig.ExternalTaskRunnerConfiguration; stderr: string[]; }> { let run = () => { let config = ProcessRunnerDetector.detectorConfig('jake'); - let process = new LineProcess('jake', [config.arg], true, {cwd: this.variables.workspaceRoot}); + let process = new LineProcess('jake', [config.arg], true, {cwd: this._cwd}); return this.runDetection(process, 'jake', true, config.matcher, ProcessRunnerDetector.DefaultProblemMatchers, list); }; return this.fileService.resolveFile(this.contextService.toResource('Jakefile')).then((stat) => { diff --git a/src/vs/workbench/parts/tasks/node/processRunnerSystem.ts b/src/vs/workbench/parts/tasks/node/processRunnerSystem.ts index 87d11fa122c601673dc6ed15dfc890ff8dc09a76..fc25031b9365216ee3fd5e3001749207c9de12f3 100644 --- a/src/vs/workbench/parts/tasks/node/processRunnerSystem.ts +++ b/src/vs/workbench/parts/tasks/node/processRunnerSystem.ts @@ -18,7 +18,7 @@ import { TerminateResponse, SuccessData, ErrorData } from 'vs/base/common/proces import { LineProcess, LineData } from 'vs/base/node/processes'; import { IOutputService, IOutputChannel } from 'vs/workbench/parts/output/common/output'; -import { ISystemVariables } from 'vs/base/common/parsers'; +import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { IMarkerService } from 'vs/platform/markers/common/markers'; import { ValidationStatus } from 'vs/base/common/parsers'; @@ -37,11 +37,11 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem { public static TelemetryEventName: string = 'taskService'; private fileConfig: FileConfig.ExternalTaskRunnerConfiguration; - private variables: ISystemVariables; private markerService: IMarkerService; private modelService: IModelService; private outputService: IOutputService; private telemetryService: ITelemetryService; + private configurationResolverService: IConfigurationResolverService; private validationStatus: ValidationStatus; private defaultBuildTaskIdentifier: string; @@ -54,14 +54,15 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem { private activeTaskIdentifier: string; private activeTaskPromise: TPromise; - constructor(fileConfig:FileConfig.ExternalTaskRunnerConfiguration, variables:ISystemVariables, markerService:IMarkerService, modelService: IModelService, telemetryService: ITelemetryService, outputService:IOutputService, outputChannelId:string, clearOutput: boolean = true) { + constructor(fileConfig: FileConfig.ExternalTaskRunnerConfiguration, markerService: IMarkerService, modelService: IModelService, telemetryService: ITelemetryService, + outputService: IOutputService, configurationResolverService: IConfigurationResolverService, outputChannelId: string, clearOutput: boolean = true) { super(); this.fileConfig = fileConfig; - this.variables = variables; this.markerService = markerService; this.modelService = modelService; this.outputService = outputService; this.telemetryService = telemetryService; + this.configurationResolverService = configurationResolverService; this.defaultBuildTaskIdentifier = null; this.defaultTestTaskIdentifier = null; @@ -405,7 +406,7 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem { } private resolveVariable(value: string): string { - return this.variables.resolve(value); + return this.configurationResolverService.resolve(value); } public log(value: string): void {