in src/vs/workbench/contrib/tasks/node/processTaskSystem.ts [205:358]
private doExecuteTask(task: CustomTask, telemetryEvent: TelemetryEvent): ITaskExecuteResult {
let taskSummary: ITaskSummary = {};
let commandConfig: CommandConfiguration = task.command;
if (!this.errorsShown) {
this.showOutput();
this.errorsShown = true;
} else {
this.clearOutput();
}
let args: string[] = [];
if (commandConfig.args) {
for (let arg of commandConfig.args) {
if (Types.isString(arg)) {
args.push(arg);
} else {
this.log(`Quoting individual arguments is not supported in the process runner. Using plain value: ${arg.value}`);
args.push(arg.value);
}
}
}
args = this.resolveVariables(task, args);
let command: string = this.resolveVariable(task, Types.isString(commandConfig.name) ? commandConfig.name : commandConfig.name!.value);
this.childProcess = new LineProcess(command, args, commandConfig.runtime === RuntimeType.Shell, this.resolveOptions(task, commandConfig.options!));
telemetryEvent.command = this.childProcess.getSanitizedCommand();
// we have no problem matchers defined. So show the output log
let reveal = task.command.presentation!.reveal;
if (reveal === RevealKind.Always || (reveal === RevealKind.Silent && task.configurationProperties.problemMatchers!.length === 0)) {
this.showOutput();
}
if (commandConfig.presentation!.echo) {
let prompt: string = Platform.isWindows ? '>' : '$';
this.log(`running command${prompt} ${command} ${args.join(' ')}`);
}
if (task.configurationProperties.isBackground) {
let watchingProblemMatcher = new WatchingProblemCollector(this.resolveMatchers(task, task.configurationProperties.problemMatchers!), this.markerService, this.modelService);
let toDispose: IDisposable[] | null = [];
let eventCounter: number = 0;
toDispose.push(watchingProblemMatcher.onDidStateChange((event) => {
if (event.kind === ProblemCollectorEventKind.BackgroundProcessingBegins) {
eventCounter++;
this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.Active, task));
} else if (event.kind === ProblemCollectorEventKind.BackgroundProcessingEnds) {
eventCounter--;
this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.Inactive, task));
}
}));
watchingProblemMatcher.aboutToStart();
let delayer: Async.Delayer<any> | null = null;
this.activeTask = task;
const inactiveEvent = TaskEvent.create(TaskEventKind.Inactive, task);
let processStartedSignaled: boolean = false;
const onProgress = (progress: LineData) => {
let line = Strings.removeAnsiEscapeCodes(progress.line);
this.appendOutput(line + '\n');
watchingProblemMatcher.processLine(line);
if (delayer === null) {
delayer = new Async.Delayer(3000);
}
delayer.trigger(() => {
watchingProblemMatcher.forceDelivery();
return null;
}).then(() => {
delayer = null;
});
};
const startPromise = this.childProcess.start(onProgress);
this.childProcess.pid.then(pid => {
if (pid !== -1) {
processStartedSignaled = true;
this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessStarted, task, pid));
}
});
this.activeTaskPromise = startPromise.then((success): ITaskSummary => {
this.childProcessEnded();
watchingProblemMatcher.done();
watchingProblemMatcher.dispose();
if (processStartedSignaled && task.command.runtime !== RuntimeType.CustomExecution) {
this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessEnded, task, success.cmdCode!));
}
toDispose = dispose(toDispose!);
toDispose = null;
for (let i = 0; i < eventCounter; i++) {
this._onDidStateChange.fire(inactiveEvent);
}
eventCounter = 0;
if (!this.checkTerminated(task, success)) {
this.log(nls.localize('TaskRunnerSystem.watchingBuildTaskFinished', '\nWatching build tasks has finished.'));
}
if (success.cmdCode && success.cmdCode === 1 && watchingProblemMatcher.numberOfMatches === 0 && reveal !== RevealKind.Never) {
this.showOutput();
}
taskSummary.exitCode = success.cmdCode;
return taskSummary;
}, (error: ErrorData) => {
this.childProcessEnded();
watchingProblemMatcher.dispose();
toDispose = dispose(toDispose!);
toDispose = null;
for (let i = 0; i < eventCounter; i++) {
this._onDidStateChange.fire(inactiveEvent);
}
eventCounter = 0;
return this.handleError(task, error);
});
let result: ITaskExecuteResult = (<any>task).tscWatch
? { kind: TaskExecuteKind.Started, task, started: { restartOnFileChanges: '**/*.ts' }, promise: this.activeTaskPromise }
: { kind: TaskExecuteKind.Started, task, started: {}, promise: this.activeTaskPromise };
return result;
} else {
this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.Start, task));
this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.Active, task));
let startStopProblemMatcher = new StartStopProblemCollector(this.resolveMatchers(task, task.configurationProperties.problemMatchers!), this.markerService, this.modelService);
this.activeTask = task;
const inactiveEvent = TaskEvent.create(TaskEventKind.Inactive, task);
let processStartedSignaled: boolean = false;
const onProgress = (progress: LineData) => {
let line = Strings.removeAnsiEscapeCodes(progress.line);
this.appendOutput(line + '\n');
startStopProblemMatcher.processLine(line);
};
const startPromise = this.childProcess.start(onProgress);
this.childProcess.pid.then(pid => {
if (pid !== -1) {
processStartedSignaled = true;
this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessStarted, task, pid));
}
});
this.activeTaskPromise = startPromise.then((success): ITaskSummary => {
this.childProcessEnded();
startStopProblemMatcher.done();
startStopProblemMatcher.dispose();
this.checkTerminated(task, success);
if (processStartedSignaled && task.command.runtime !== RuntimeType.CustomExecution) {
this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessEnded, task, success.cmdCode!));
}
this._onDidStateChange.fire(inactiveEvent);
this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.End, task));
if (success.cmdCode && success.cmdCode === 1 && startStopProblemMatcher.numberOfMatches === 0 && reveal !== RevealKind.Never) {
this.showOutput();
}
taskSummary.exitCode = success.cmdCode;
return taskSummary;
}, (error: ErrorData) => {
this.childProcessEnded();
startStopProblemMatcher.dispose();
this._onDidStateChange.fire(inactiveEvent);
this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.End, task));
return this.handleError(task, error);
});
return { kind: TaskExecuteKind.Started, task, started: {}, promise: this.activeTaskPromise };
}
}